Continuous Integration with Cruise Control, .NET (C#, WPF, ASP.NET) Projects, and NAnt

UPDATE: NAnt 0.91 Alpha 2 has been released with support for .NET 4. Download it here.
UPDATE: CruiseControl.NET 1.5 (Final) has been released and is available here.
UPDATE CruiseControl.NET 1.5 RC1 has been released and is available here.

My Cruise Control .NET implementation consists of numerous development projects each with multiple different Cruise Control .NET projects associated with it (one per environment per branch). In order to make the projects more maintainable, I have created a separate configuration file for each development project. Defining variables and separating ccnet.config configuration file into smaller files allows for easier maintenance of each project over their lifetimes.

Defining and using variables

Variables can be defined using the following format

<cb:define KEY=”VALUE” />

To reference that variable later in the configuration file, simply use $(KEY)

Check out the Cruise Control .NET website for complete explanation of variables using the pre-processor.

Separating the configuration files

<!DOCTYPE cruisecontrol [
<!ENTITY PROJECT_NAME SYSTEM “file:project.xml“>
<cruisecontrol xmlns:cb=”urn:ccnet.config.builder”>

project.xml would, then, contain the regular xml configuration for a Cruise Control .NET project:

<?xml version=”1.0″ encoding=”utf-8″?>
<project name=”My Project” category=”A Category”>
<intervalTrigger seconds=”900″ buildCondition=”IfModificationExists” />
<scheduleTrigger time=”04:00″ buildCondition=”ForceBuild” />
<labeller type=”svnRevisionLabeller”>
<pattern>Version {major}.{minor}.{build}.{revision}</pattern>
<sourcecontrol type=”svn”>
<cb:SvnOptions />
<xmllogger />
<cb:include href=”EmailConfig.xml”/>

On caveat with this idea is that changes to the separate configuration files are not recognized until the cruise control is restarted by either restarting the service or modifying the ccnet.config file.

Building and Deploying ASP.NET Web Applications

The NAnt target below is a full parameterized call to MsBuild.exe to compile any solution. ThoughtWorks.CruiseControl.MsBuild.dll provides an MSBuild logger that allows Cruise Control .NET to report the bulid output.

<target name=”build”>
<exec program=”${MSBuildPath}”>
<arg line='”${SolutionFile}”‘ />
<arg line=”/property:Configuration=${SolutionConfiguration}” />
<arg value=”/target:Rebuild” />
<arg value=”/verbosity:normal” />
<arg value=”/nologo” />
<arg line=’/logger:”C:Program FilesCruiseControl.NETserverThoughtWorks.CruiseControl.MsBuild.dll”‘/>


MSBuildPath – The path to the MsBuild executable.

For .NET Framework versions 2.0 and 3.5  on a 32-bit Windows OS, use C:WINDOWSMicrosoft.NETFrameworkv2.0.50727MsBuild.exe
For .NET Framework version 4.0, use C:WINDOWSMicrosoft.NETFrameworkv4.0.30319MsBuild.exe

SolutionFile – The relative path from the build file to the solution file. Fully qualified paths are also allowed.

SolutionConfiguration – “Release” or “Debug”.