CruiseControl.Net Tutorial – Part 1

1 06 2008

Suggested Books

Expert .Net Delivery .Net Architecting Applications For The Enterprise Patterns of  Enterprise Application Architecture Design Patterns

My AutoComplete Project on CodePlex

1. Introduction
2. Resources
3. Installation
3.1. Install CruiseControl.NET
3.2. Create a CCNet Website in IIS
3.3. Install Nunit
4. CruiseControl.NET Server Configuration – General
5. Structure of a ‘Project’ Configuration File
6. Source Control Block
7. Trigger Block
8. Labeller Block
9. Tasks Block (part 2)
10. MsBuild Task (part 2)
10.1. MSBuild and ReferencePath – CruiseControl.NET not resolving reference to Nunit (part 2)
10.2. An Alternative MSBuild Logger – Christian Rodemeyer’s MsBuildToCCNet (part 2)
10.3. CruiseControl.NET Webdashboard fails in finding images if not installed in virtual directory (part 2)
10.4. MSBuildToCCNET reports wrong number of compiled projects (part 2)
10.5. CruiseControl.NET, MsBuild Task and Resources – Assembly Linker (part 2)
10.6. CruiseControl.NET, MsBuild Task and Web Application projects (part 2)
11. Nunit Task (part 2)
11.1. Nunit Task (part 2)
11.2. Executable Task (part 2)
12. Publishers Block (part 2)
13. PreBuild Block (part 2)
13.1. Install Nant (part 2)
13.2. Nant Fundamentals (part 2)

1. Introduction

In this article series I will review the various steps needed to setup and configure a working CruiseControl.Net server.
The goal is to set up a Continuous Integration process for a sample project as close as possible to a real-life project.
I will point out several issues that might arise and I will provide solutions as well.
I will try to underline all the details that you need to be aware of.

Thanks to Frank Geerlings for making me aware of a casing problem with the xml samples.
By talking with the guys at WordPress support it came out that there was a little bug and they suggested me how to fix the problem.

→ top of post

2. Resources

During the article I will guide you through the installation process of the following software:



The following are optional:


You can find information about how to install: Subversion, TortoiseSVN and AnkhSVN in the article: Guide to Versioning a Visual Studio Solution with Subversion, TortoiseSVN and AnkhSVN.
There you can also find a quick guide about how to create a Subversion repository and how to add a Visual Studio solution to source control.

This tutorial assumes that you have Subversion 1.4.6 installed and that you have configured a Subversion repository at the url: svn://localhost/trunk as shown in the article: Guide to Versioning a Visual Studio Solution with Subversion, TortoiseSVN and AnkhSVN.

If you already have a working environment with a repository and versioned files, you can go on reading and replace the paths and names in the examples with the paths and names in your environment.

→ top of post
→ top of paragraph

3. Installation

This tutorial will assume that you install CruiseControl.NET on the same machine on which you had installed the Subversion repository. So, first of all, let’s go through the steps needed to install CruiseControl.NET on your server machine.

3.1. Install CruiseControl.NET

Download the latest CruiseControl.NET release from: SourceForge or the latest build from CCNetLive.
You can find release notes here. For this article I used the installer for version 1.4 (CruiseControl.NET-1.4-Setup.exe), downloaded from the CCNetLive website.

Run the setup executable file and, when prompted, you must specify your choices for a couple of actions:
‘Install CC.Net server as windows service’ must be checked so that the setup will install CruiseControl as a Windows service.
In the Services management console the CruiseControl service will be displayed with the name: CruiseControl.NET.
‘Create virtual directory in IIS for Web dashboard’ will create a virtual directory named ccnet in the machine’s IIS web server. If you have an IIS server installation supporting multiple web sites (this is not the case for Windows XP Professional) and prefer to have a separate web site for the CCNet web dashboard you should uncheck this option. This is my choice. In the next paragraph I will show you how to create an IIS web site for the CruiseControl.NET web dashboard.

When the install process is finished all the content will be installed in the folder:
C:\%ProgramFiles%\CruiseControl.NET (e.g. C:\Program Files\CruiseControl.NET).
Under this path you will find a directory called server, containing all the CCNet binary files and executables, and a directory called webdashboard, containing the CruiseControl.NET web interface.

→ top of post
→ top of paragraph

3.2. Create a CCNet Website in IIS

Here I will add and configure a Website in IIS for the CruiseControl.NET Webdashboard: the administrative interface of CruiseControl.NET.
Open IIS Manager in Administrative Tools, right-click on the Web Sites node and select New Web Site.
The Web site creation wizard will start.
Click Next and you will be prompted for a Web Site Description.
Type CCNet and click Next, leave Unassigned the IPAddress, choose a port number (say: 222) and leave empty the ‘Host Header for this site’ field, then click Next.
Choose C:\%ProgramFiles%\CruiseControl.NET\webdashboard as the path for the Website and click Next.
Allow ‘Read’ and ‘Run scripts’, the default, and click Next. The wizard is finished and the new Website created.

→ top of post
→ top of paragraph

3.3. Install Nunit

For the sake of our example we will need Nunit so, if you haven’t already done, install it on the same machine on which you have installed CruiseControl.NET.

You can find the latest Nunit release here at SourceForge.
This article is based on the release 2.4.6, currently the latest. You can install it by downloading: NUnit-2.4.6-net-2.0.msi.

After the installation you will have a new directory under %ProgramFiles% : C:\%ProgramFiles%\NUnit 2.4.6.

→ top of post
→ top of paragraph

4. CruiseControl.NET Server Configuration – General

All the configuration files we’re going to talk about are placed or are to be placed in:

CruiseControl.NET comes with two server executables: ccservice.exe which is the windows service installed by the installation setup and ccnet.exe which is a console application included for testing purposes.
It is much easier to debug a console application that a service so I strongly suggest to make your initial tests with ccnet.exe and carefully read the console output to get familiar with CCNet behavior.

Each of the two executables comes with a default configuration file (i.e.: ccservice.exe.config and ccnet.exe.config) that you don’t need to change at the moment.
Moreover both the server processes (windows service or console application) look for a file named ccnet.config in which you will place all the actual information needed by CCNet to learn what it is supposed to do and how it is supposed to do it.

ccnet.config is an xml file with a root element named <cruisecontrol> and a child element, named <project>, for each set of activities that we want CruiseControl.NET to execute, as shown in the following example:

<project name="project1">
<project name="project2">

In this tutorial we will setup our CruiseControl.NET configuration with two logical sets of activities.
For the sake of clarity we will benefit of the usage of xml entities.
We’ll define each ‘project’ configuration in a separate file and import all the files in ‘ccnet.config’ by means of entity definitions and entity declarations:

< !DOCTYPE cruisecontrol [
	< !ENTITY project1 SYSTEM "file:project1.xml.config">
	< !ENTITY project2 SYSTEM "file:project2.xml.config">

Let’s focus, at first, only on the first project, so delete the second entity reference (i.e.: &project2; ) thus obtaining:

< !DOCTYPE cruisecontrol [
	< !ENTITY project1 SYSTEM "file:project1.xml.config">
	< !ENTITY project2 SYSTEM "file:project2.xml.config">

→ top of post
→ top of paragraph

5. Structure of a ‘Project’ Configuration File

What we need to do now is creating a file named: project1.xml.config in C:\%ProgramFiles%\CruiseControl.NET\server
and use it to setup CruiseControl.NET main activities.
This file will contain what is called the ‘Project Configuration Block’ for the first CCNet activity that we want to configure.
First of all we need to assign a unique name to the root of the Project Configuration Block: the <project> tag. We then write:

<project name="1 - testProject">

Let’s talk about the first three children nodes:

represents the URL at which the current project is available through the web interface. We will see later why it is useful.
For now just make sure to set it to the IP of the server machine (in which you installed CCNet) and to the port that you chose for the WebDashboard website when you configured the web site in IIS (see: 3.2. Create a CCNet Website in IIS).

is the path to the main directory of this project and is meant to contain the checked out version of the project under integration.
This path will be accessible as an environment variable: %CCNetWorkingDirectory%, available to external scripts (we will see it later).
I use to place all the projects managed with CCNET in folders under a common directory named: C:\develop\CCnet.
For this test project I chose: C:\develop\CCnet\project1WorkingDir.

It is convenient to choose a directory in which to place all the stuff that will be used by CCNet (script files or executable files that you may want CruiseControl.NET to execute) as well as the workingDirectory in which CCNET will checkout the versioned files and the artifactDirectory in which it will output log files.
In the example above I chose the directory: C:\develop\CCnet as the container of all CCNet related stuff.

is the path to the directory where all the build logs for this project will be placed.

Apart from the three tags described above, the main blocks that we’re going to add to the project configuration file are:

→ top of post
→ top of paragraph

6. Source Control Block

Source Control configuration block tells CruiseControl.NET that the project named ‘1 – testProject’ is bound to a Subversion repository.
This means that the task performed when executing this project depends on the status of that particular Subversion repository.
As soon as CruiseControl.NET detects a new revision in the repository it updates its working copy and executes the tasks related to the current project.
Here is the xml excerpt:

<sourcecontrol type="svn">
  <username>ccnet </username>
<password> ccnet </password>

contains the url of the repository that we want to check for modifications (e.g., svn://svnserver/pathToRepo).
As we saw in the post Guide to Versioning a Visual Studio Solution with Subversion, TortoiseSVN and AnkhSVN, Subversion could host several repositories under a common folder, say: C:\develop\TestRepo.
But in that article, as well as in the current example, we set up only one repository and run svnserve with the command line: svnserve -d -r “C:\develop\test\repo”.
So, specifying the server name (localhost) and the path to the particular repository we’re interested in, turns out to be simply: svn://localhost/trunk (instead of: svn://localhost/SpecificRepositoryFolder/trunk);
is the directory that will contain the working copy checked out by CCNET;
sets the timeout for the source control operation. It defaults to 10 minutes and you can set it to a different amount of time in milliseconds (default) or specifying units (“millis”, “seconds”, “minutes”, “hours”); I left it out thus accepting the default.
If you want to set it to a different value remember to not choose a too short timeout value because if the timeout is exceeded the build will fail without providing information about the reason.
In that case the only way you can retrieve the actual reason of the build failing is by analyzing CCNET log file in the CruiseControl.NET\server folder (if you set log4net to the debug log level)
and must be set to a valid svn account that CCNET can use to access Subversion repository.

→ top of post
→ top of paragraph

7. Trigger Block

A trigger block is needed to specify when CruiseControl.NET will start a new integration cycle.
We want to check for the repository status continuously so we need an ‘Interval Trigger’ to tell CruiseControl.NET to perform integration periodically after a specified amount of time:

  <intervalTrigger name="Subversion" seconds="10" />

CruiseControl.NET, as far as project ‘1 – TestProject’ is concerned, polls the repository every 10 seconds to see if any changes has been committed.
The name attribute is used by CruiseControl.NET GUI to identify the trigger that requested the build;
The seconds attribute is the amount of time before triggering the next integration cycle.

Each time the time interval elapses, CCNET checks for modifications and, by default, runs integration only if changes are detected.

→ top of post
→ top of paragraph

8. Labeller Block

A label is created, at each integration cycle, to identify the specific build occurred.
Different labellers can be used to generate the label that CCNet will use to track the builds.

Other than the Labeller Blocks that come with the CruiseControl.NET distribution, many people provided plugin Labeller Blocks to target the generation of labels with specific formats.

A very good one, IMHO, is SvnRevisionLabeller by David Keaveny (much important to me because I recently contributed to the project).
This plugin allows labelling CruiseControl.NET builds with Subversion’s repository revision numbers and I think this is a really useful feature.
So this example will use SvnRevisionLabeller as the Labeller Block.
For detailed information about this plugin see my post: CruiseControl.NET and Subversion – SvnRevisionLabeller.

To use the SvnRevisionLabeller plugin in your installation of CruiseControl.NET you need to unzip the downloaded package and copy the assembly: ccnet.SvnRevisionLabeller.plugin.dll in the server folder directory under the CruiseControl.NET install path (e.g.: ‘C:\Program Files\CruiseControl.NET\server’).

Next you need to configure the Labeller Block in your project:

<labeller type="svnRevisionLabeller">

SvnRevisionLabeller will produce build labels in the format:

where major and minor are the two values you set in the configuration block while svnRevision is the current version in the Subversion’s repository related to this project.
The build number is automatically incremented each time a new build is forced if no further modification has been committed to the repository.

<url> is the path to the repository used to retrieve the revision number (e.g. svn://svnserver/pathToRepo/trunk). Actually it should be filled with the same path used in the <trunkUrl> field of the Subversion Source Control Block.
In our example it is:


Following is a configuration for SvnRevisionLabeller with the complete set of fields:

<labeller type="svnRevisionLabeller">

Such a configuration will produce a label with the following format:
<username> and <password> are the username and password of a valid Subversion account for the repository specified in the <url> field.

You can use in an external script the build label produced, which is stored in an environment variable.
It can be useful to flag release version of output dlls.
You can access the build number from a script with the syntax: %CCNetLabel% or from a C# application with the following row:


If you used the SolutionInfo approach in your Visual Studio solution (see my post: SolutionInfo and Partitioned Single Solution) you can use the build label produced by SvnRevisionLabeller to update the AssemblyFileVersion attribute in the SolutionInfo.cs file.
In this way you can provide consistent versioning of the released assemblies together with easy trackability of the corresponding source code’s revision.

Be careful not to use the <prefix> tag in this case because you need to set AssemblyFileVersion to a string in the format:
with all of the 4 fields being numerical values.

→ top of post
→ top of paragraph

CruiseControl.Net Tutorial – Part 2 >>

kick it on

About these ads



41 responses

3 06 2008
Reflective Perspective - Chris Alcock » The Morning Brew #106

[...] CruiseControl.Net Tutorial – Part 1 – Matteo gives a nice step by step guide to setting up CC.NET – looks like this will be a good series to keep hold of as a reference. [...]

3 06 2008
roScripts - Webmaster resources and websites

CruiseControl.Net Tutorial - Part 1 « My view on C#…

CruiseControl.Net Tutorial - Part 1 « My view on C#…

4 06 2008


4 06 2008

Thank you,
I’m very happy that you appreciate this post!
I’m currently writing the draft of the second part.


5 06 2008
CruiseControl.Net Tutorial « Rams On It - .NET

[...] in Tools. trackback Everyday this tool becoming famous among the developers, I just read one nice tutorial about [...]

9 06 2008
Wöchentliche Rundablage: Silverlight 2, WPF, ASP.NET MVC, jQuery… | Code-Inside Blog

[...] CruiseControl.Net Tutorial – Part 1 [...]

9 06 2008
Weekly Links: Silverlight 2, WPF, ASP.NET MVC, jQuery… | Code-Inside Blog International

[...] CruiseControl.Net Tutorial – Part 1 [...]

12 06 2008

I find this tutorial very useful. Can’t to see part2

13 06 2008

Hello Marcia,
Here it is, I eventually posted part 2 at the following address:

1 07 2008
Frank Geerlings

Thanks for this article. Even though I am already familiar with CCNET, it saved me at least an hour getting things set up in a new environment.

You might want to check whether everything in the XML file is cased correctly. I had some issues with my artifactDirectory node being called artifactdirectory, as in your examples above.

2 07 2008

Thank you very much Frank,
I didn’t realized that the formatting tag I used for xml samples automatically turned lowercase every tag name.
I changed the samples, where needed, using a less appealing but more controllable display method.

6 07 2008

Thanks for this awesome Tut. Can’t wait for the final part.

17 12 2008
Recent Links Tagged With "cruisecontrol" - JabberTags

[...] tests on multiple servers in 200^H^H^H 13 lines of… Saved by xSilentxLegendx on Tue 02-12-2008 CruiseControl.Net Tutorial – Part 1 Saved by ottyke on Mon 01-12-2008 Cruise Control Saved by KarateConTino on Mon 01-12-2008 [...]

9 03 2009
Harikrishna Routhu

you done a excellent job mr,I am new to this ccnet.Please send me next tuotorials.i am eagerly waiting ……these articles helps a lot for new learners.once again thanks

30 03 2009 Installation Tutorial… « Its my Place at my Pace….

[...] Installation Tutorial… Matte has a nice and simple tutorial on how to install CruiseControl.Net, which is an automated  continuous integration server for the [...]

12 04 2009

Thank you for this post. Where are 3-rd and 4-th pats of the tutorial

20 08 2009

I do have a question. What if one wants to install CruiseControl on a remote machine i.e a web hosting server account, and then link it up to another remote subversion engine, on another host account. How would one go about doing that please?

10 09 2009

Hi! I was surfing and found your blog post… nice! I love your blog. :) Cheers! Sandra. R.

28 10 2009

Really nice blog post. I’m working with SVN 1.5.0 and I just wondering when svnRevisionLabeller will realesed to support this latest version?


8 05 2010
2 06 2010
26 11 2010

I have to publish a webservice (in c#) to a remote server, the remote server URL will be changing .So, I need to specify the remote server URL in the configuration. Taking the URL address, the webservice which is in the local system has to be deployed to the remote server.

Can I use Cruise Control to achieve this and if yes can you help me in suggesting how we can do this?

29 11 2010

I’m very sorry but I’ve been working on other things in the last two years. So I’m not as skilled as I used to be.
I’m going to delve again into CCNET shortly in order to publish the 3rd part of this tutorial (at the moment it’s only a draft).
As soon as I realize a way to help you I will let you know with a new reply.

6 12 2010
Slava Agafonov

Very nice post, thanks for sharing. I have just configured my project to new version of CCNET with help of this article.

24 06 2011

Very nice. I had to include a reference to the svn.exe to make that part work (see

26 08 2011

Thank you so much!!!

26 08 2011

Error in in section: 4. CruiseControl.NET Server Configuration – General

There should not be a space between the < and ! symbols in ccnet.config

18 10 2011
Ravirkishna Avula

Hello,I am Getting bellow exception even the latest subversion client version 1.7 installed.

Bellow is the exception.

Error Message: ThoughtWorks.CruiseControl.Core.CruiseControlException: Source control operation failed: svn: The path ‘.’ appears to be part of a Subversion 1.7 or greater working copy. Please upgrade your Subversion client to use this working copy. . Process command: C:\Program Files\VisualSVN\bin\svn.exe update –username ravikrishnaa –password techvedika –non-interactive –no-auth-cache at ThoughtWorks.CruiseControl.Core.Sourcecontrol.ProcessSourceControl.Execute(ProcessInfo processInfo) at ThoughtWorks.CruiseControl.Core.Sourcecontrol.Svn.GetSource(IIntegrationResult result) at ThoughtWorks.CruiseControl.Core.IntegrationRunner.Build(IIntegrationResult result)
Project: MyProject
Date of build: 2011-10-18 15:26:39
Running time: 00:00:00
Integration Request: intervalTrigger triggered a build (ForceBuild)

8 11 2011

To Ravirkishna Avula:

I had the same problem. The reason was that the old SVN version hadn’t been uninstalled automatically before new version installation. You can check it by ‘svn.exe –version’ command, for me it showed 1.6.12 instead of 1.7.

This was just because PATH environment variable contained two paths – one to old svn folder and another to new svn folder. So removing old svn folder from PATH and manual uninstallation of old SVN fixed the problem (WIN+PAUSE, “Advanced system settings”, “Environment variables” button).

27 12 2011
web design dubai company

I just could not go away your web site before suggesting that I really enjoyed the standard information a person provide in your visitors? Is gonna be again ceaselessly to investigate cross-check new posts

16 11 2012

Seems slightly odd there’s no mention of CCTray on here… Or did I miss it?

21 04 2013

I am curious to find out what blog platform you
have been working with? I’m experiencing some small security issues with my latest website and I would like to find something more risk-free. Do you have any suggestions?

29 04 2013

I needed to thank you for this great read!! I definitely enjoyed every bit of it.
I have you book marked to check out new stuff you post…

9 07 2013
Technology Radar | Gomes Blog

[…] CruiseControl.Net Tutorial – Part 1 « My view on C# […]

22 07 2013

Good work. I am new to this ccnet and want to establish connection can you send me some sample tutorials?

22 09 2014
Garmin nuvi 2555 gps lifetime

I’ve been surfing on-line more than three hours nowadays,
yet I by no means discovered any attention-grabbing
article like yours. It is beautiful price sufficient for me.
In my view, if all site owners and bloggers made just right content material as you did, the net shall be much more helpful than ever before.

23 09 2014
high school online

certainly like your web-site however you need to take a look at the spelling
on quite a few of your posts. Many of them are rife with spelling problems and I find it very
bothersome to tell the reality then again I’ll certainly come again again.

23 09 2014
Moger Tilakraj

Tutor was very good, excellent for learners. i have one question with you,
in the tutorial you said all the configurations file to be placed in C:\%ProgramFiles%\CruiseControl.NET\server, can we make the ccnet.config file to be read from svn archive?

5 10 2014

This paragraph provides clear idea designed for
the new viewers of blogging, that truly how to do running a blog.

6 10 2014
Going On this site

I like the valuable information you provide tto your articles.
I’ll bookmark your bloog aand test agakn here frequently.
I’m slightly sure I’ll be informed plenty of new stuff proper
right here! Good luck for thee next!

16 10 2014

Very good article. I will be dealing with some of these issues as well..

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: