CruiseControl Basics

In short CruiseControl is a system that will build software periodically and make the results available via a web server. Continuous integration is a corner stone of agile development (build early, build often). What is built is what is checked into source control, not what is local to individual developers machines. CruiseControl also enables tracking of changes since the last build, showing ‘who broke the build’ leading to greater accountability.

Always having a build of the software (and associated tools) can be very useful both to developers and to members of the team that are not software developers. For example artists often like to look at how the game engine is rendering their models in game (to world scale, with lighting & shaders running). Builds can also be forced without tying up your local PC. Having the latest build available to all members of the development team frees up your time, this is a good thingTM.

Anything that can be scripted (launched from a command prompt and runs ‘headless’) can be launched from CruiseControl. Any output from scripts can potentially be included as artefacts of the build. This extends not only to items like installers, but also to unit tests et al.

 

Screen shot of CruiseControl in action.

Setting up CruiseControl

Setup described:

  • Install CruiseControl
  • Configure a single project
  • Write an MSBuild script for
    • Checkout from source control (SVN repository in this case)
    • Build a C++ solution (VS2010 in this case)
    • Publish results (build log included in artefacts)

Not covered:

  • Writing scripts for installers
  • Running unit test and merging results to the output
  • Security considerations
  • Running CruiseControl as a service

Scenerio Described:

Notes about MSBuild

MSBuild can be used to build C++ (and .NET) projects under Visual Studio 2008 and Visual Studio 2010. VS2008 uses MSBuild 3.x while VS2010 uses MSBuild 4.0. Further to this the logging system has also changed for VS2010. Under VS2008 logging used to automatically go to a UTF16 html file in $(ProjectDir)/$(Configuration)/BuildLog.htm, for VS2010 various loggers can be defined and used. This tutorial focuses on VS2010.

Getting CruiseControl

CruiseControl comes in two main flavours. CC.NET is a more recent development which runs via .NET with MSBuild using Microsoft Internet Information Server as a web server. The original version of CruiseControl runs via a Java runtime with Ant and uses Jetty as a web server. While CC.NET has better integration with MSBuild, I prefer the classic version as IMHO it is more self contained and less complex to configure than IIS.

At the time of writing the most recent version of CruiseControl is 2.8.4. This version of CruiseControl will not start correctly under a Java Runtime less than JRE6 and crashes under JRE7.

Choose a computer for the build machine. This computer will be acting as the web server (and doing the builds). You really want a computer that is on a fixed IP address or can be resolved to an IP address on the local network by DNS. Ensure a Java runtime is installed, then extract cruisecontrol-bin-2.8.4.zip to a directory on eg. C:/cruisecontrol-bin-2.8.4.

The JAVA_HOME  Environment Variable

Java SDK’s and run times (JRE's) usually set the JAVA_HOME environment variable. By default this path is C:\Program Files (x86)\Java\jre6. You can verify which directory JAVA_HOME points too from the command prompt using the set command or alternatively: WinKey+BreakKey, Advanced System Settings, Environment Variables.

Modern Java Runtimes tend to update automatically from online sources (configured from the Windows control panel) which can occasionally break CruiseControl. It is recommended that you copy the contents of the JREX directory to another location and edit the CruiseControl batch file to point to this (static unchanging) location. I use Notepad++ for text editing (sourceforge.net/projects/notepad-plus/). My CruiseControl.bat looks something like the following:

set MY_JAVA_PATH="E:\cruisecontrol-bin-2.8.4\jre6"
set CC_OPTS=-Xms512m -Xmx1024m
set CCDIR=%~dp0

:checkJava
if not defined MY_JAVA_PATH goto noJavaHome
set JAVA_PATH="%MY_JAVA_PATH%\bin\java"
set CRUISE_PATH=%MY_JAVA_PATH%\lib\tools.jar
goto setCruise

:noJavaHome
echo WARNING: You have not set the MY_JAVA_PATH environment variable. Any tasks relying on the tools.jar file will not work properly.
set JAVA_PATH=java

:setCruise
set LIBDIR=%CCDIR%lib
set LAUNCHER=%LIBDIR%\cruisecontrol-launcher.jar
set JETTY_LOGS=%CCIDR%logs
set EXEC=%JAVA_PATH% %CC_OPTS% -Djavax.management.builder.initial=mx4j.server.MX4JMBeanServerBuilder "-Djetty.logs=%JETTY_LOGS%" -jar "%LAUNCHER%" %* -jmxport 8000 -webport 8080 -rmiport 1099
echo %EXEC%
%EXEC%

Note that the -webport flag is the port number that CruiseControl will run on. If you happen to know that there is something else on your machine listening on port 8080, then change it now. Also note that I have increased the memory allocated to the Java runtime (minimum 512Mb, maximum 1024Mb) with the line set CC_OPTS=-Xms512m -Xmx1024m

Starting CruiseControl

Run CruiseControl.bat now. Unless you have a Java SDK installed (as opposed to a vanilla JRE), you will get an error from the ‘connectfour’ project about not being able to find a Java compiler. This doesn’t matter as we will be using MSBuild. Leaving the CruiseControl window open, start a web browser and type in the following address to ensure that CruiseControl is running http://localhost:8080/cruisecontrol/. If you get no response in the web browser, then there is something wrong with your setup. The most likely scenerio is that something else is using/blockingport 8080, try changing this to port 8090 in cruisecontrol.bat and restart CruiseControl.

The URL most often referenced is actually a plugin for CruiseControl - the dashboard http://localhost:8080/dashboard. The dashboard has fewer options and but IMHO provides a better more user friendly overview. Having verfied that CruiseControl responds, close down CruiseControl for now (CTRL+Break on the command shell window).

How CruiseControl Works

Config.xml defines a set of projects

  • Each project has a modification set to check
    • This is the path to a local checkout from a repository
    • A quiet period can be defined for versioning systems like CVS where commits are not atomic (to avoid attempting to build partial commits)
  • Each project has a schedule
    • The schedule defines an interval to check for changes between the local check and the files in the repository
    • The schedule also defines an xml file (ant – build.xml) to launch when changes are detected
  • Each project has a publisher
    • Each publisher has a list of files to publish to the web server on success
    • Each publisher has a list of files to publish to the web server on failure
  • It is the responsibility of the build file to ensure that all files are present either on build success or build failure

CruiseControl Directory Structure

  • projects/
    • One directory for each project to build
      • XML files to do the build (defaults to build.xml)
      • Code for project usually checked out with child of this folder
  • logs/
    • Time stamped IP requests & response logs for web server
    • One directory for each project built here
      • Time stamped build logs here
      • status.txt - locks during build for each project
  • artefacts/
    • One directory for each project built here
      • Time stamped directories containing artefacts for each build
  • ProjectName.ser - One for each project
    • Created/updated by CruiseControl - tracks build number & last build
  • config.xml - Defines which projects to build when

Test Project Setup



	
	
		
			
		
	

	
	


	
		
		
		


		
			
		


		
		
			
		
		
		
			
			
		
		

		
		
			
				
				
				
				
				
				
			
			
				
				
			
		
		
	

The sample ‘connectfour’ project (Java) that comes bundled with CruiseControl can now be removed. Even though it is no longer referenced in the config.xml, logs are present so it will still show up in the dashbaord view. Delete connectfour.ser from the root CruiseControl directory and delete the connectfour directory from projects/ and logs/.

Create a basic hello world application (a sample Hello World application is included in the zip below).  Add it to SVN (I recommend a local file system repository for testing).  Create a directory for the project (TestProject in this case) under the CruiseControl projects/ directory.  Create a directory named Checkout within this directory and check the code out to this directory ie.

Cruisecontrol-bin-2.8.4 <-- Where you extracted the CruiseControl zip
+- config.xml
+- projects
  +- TestProject
     build.xml          <-- next step (build script)
     CheckOutBuild.xml  <-- step after next
     CheckOut
     +- .svn		<-- SVN folder (hidden by default)
     +- TestProject     <-- Directory checked out from SVN
        TestProject.sln
        … Other files for the project …

MSBuild Community Tasks

Being a Microsoft tool, MSBuild does not support open source version control tools like subversion out of the box. The MSBuild community tools add a few tasks (XML tag definitions) including support for SVN.

Install the community tools for MSBuild, use the ‘latest release’ rather than the ‘nightly build’ - at the time of writing the latest release for the MSBuild community tasks is 1.2.0.306. Note that you will not be prompted for an install location, the install location is the same as where MSBuild is installed. By default the community tasks including a chm help file is installed to C:\Program Files (x86)\MSBuild\MSBuildCommunityTasks\

build.xml

As per config.xml, CruiseControl calls projects/TestProject/build.xml when changes are detected. This is an Ant script, useful for building Java applications but not so good for C++ and .NET applications. In this case, we just want to call MSBuild and determine success or failure. This is done by launching MSBuild from the command prompt. Ant also supports embedded JavaScript, JavaScript can be used to determine the return value from MSBuild. I originally found this JavaScript solution on a blog, but the source has been lost in the mists of time.



	

	
		
		
			
			
			
			
		

		
		
		
		
		
			
				
			
		
        

CheckOutBuild.proj

Build.xml launches this file. This is an MSBuild script file (not an Ant file) that does the actual work of the build. How to use MSBuild is beyond the scope of this tutorial. This file will get CruiseControl up and running and should get you started understanding how MSBuild works.




	
	


	
	
		
		
		TestProject
		Test Project
		1
		0
		0
		1

		
		file:///E:/Test/TestRepo/trunk/TestProject

		
		$(MSBuildProjectDirectory)\CheckOut

		
		$(MSBuildProjectDirectory)\Current

		
		Release

		
		
		
	


	
	
		
		

		
		

		
		
		

		
	

	
	
		
		
		 
		

		
		
	
	
	
	
	
		
		
		
		

		
			
			
		
		
		
		

		
		

		
		
	

	
	
		
		  		
		
			&lt;?xml version="1.0" encoding="utf-8"?&gt;
			&lt;VersionDetail&gt;
			&lt;Version&gt;
			Version: $(Version_Major).$(Version_Minor).$(Version_Revision)
			&lt;/Version&gt;
			&lt;BuildTime&gt;
			$(Build_Date_Stamp) $(Build_Time_Stamp)
			&lt;/BuildTime&gt;
			&lt;/VersionDetail&gt;
			
		

		
		

		
	




When you launch CruiseControl the new TestProject will be detected and should build automatically. Navigating to the dashboard (http://localhost:8080/dashboard) should show a single project square lit up green.  Clicking on the project drills down to the detail (should be similar to the screen shot near the top of this tutorial). 

Any changes committed to SVN for files relating to TestProject should now result in CruiseControl automatically rebuilding the project. Note that CruiseControl only checks for changes periodically.  You will probably want to edit config.xml, dropping the interval in the schedule tag from 1800 seconds down to around 30 seconds while testing.