Setting up Continuous Integration with Cruise Control.Net

I recently set up Cruise Control on Vista PC for development purposes and I thought it might be useful to document the process I followed.

If you don’t know what Continuous integration is then I recommend a that you read a brief overview of it by Cruise Control .Net developers

In my implementation there are 3 components to continuous integration system.

Source control (I am using VisualSVN)
Complier (MSBuild.exe, which is part of the .Net Framework)
Nunit, a unit test runner

The process involved is fairly straightforward. First the trunk of the source code is pulled from the repository to the working directory. MSbuild.exe compiles the source code, then the nUnit tests. Finally the tests are run against the complied code. The success or failure of of the tests is output as an xml file and is reported in web dashboard.

I have also installed CCtray, a program that runs in the systray showing the state of the last build. It allows builds to be run manually, as opposed to a on a timed interval . The CC web dashboard shows a wealth of information on the build state and if any Nunit tests have failed.

I achieved this by following instructions on The CCNET homepage which I’ve summarised below.

In my case the editing, building and testing of the code is done on my local machine along with hosting the source control. In a bigger environment your would host these services seperately for performance reasons, but in my scenario this is not an issue.

Having installed from the download page I installed setup.exe. The CCTray.exe will be installed once the server has been setup

Once CC net is installed the server must be started by running the CruiseControl.net icon on the desktop.

To test if the install was successfully, I pointed my browser to http://localhost/ccnet/ViewFarmReport.aspx

The first hiccup I encountered was a an IIS 7 error:
HTTP Error 500.23 – Internal Server Error
An ASP.NET setting has been detected that does not apply in Integrated managed pipeline mode.

Which was easily solved after a quick google, I found that the solution was to switch the application to a Classic mode application
pool

The server is controlled via it’s config file, which is found in C:\Program Files\CruiseControl.NET\server\ccnet.config. This file is at the heart if to the entire integration process, and contains the list of actions the server will complete on each build.

Any edits to ccnet.confg will restart the CCnet server.

To complete the first stage of a build, which is to checkout the latest version of the code, I added the source control block to ccnet.config. It which defines where code is within the repository and where it is checked out to. My example is for a SVN but Cruise Control.net supports many other source control systems.

<sourcecontrol type="svn">
  <trunkUrl>http://localhost:8080/svn/myproject/trunk</trunkUrl>
  <workingDirectory>c:\dev\ccnet</workingDirectory>
  <executable>c:\Program Files\VisualSVN Server\bin\svn.exe</executable>
  <username>username</username>
  <password>password</password>
</sourcecontrol>

The next step is to add to the config file instructions to build the code that has been checked out.

To do this I used the MSbuild.exe file found in C:\Windows\Microsoft.NET\Framework\v3.5. To save my aching fingers from typing too much, I added the above path to it to the system path.

Within the tags I inserted the block as below

 <msbuild>
          <executable>
            C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe
          </executable>
          <workingDirectory>c:\dev\ccnet\trunk</workingDirectory>
          <projectFile>project.sln</projectFile>
          <buildArgs>
              /noconsolelogger /p:Configuration=Debug /v:diag
           </buildArgs>
          <targets>Build</targets>
          <timeout>0</timeout>
          <logger>
           c:\Program Files\
       CruiseControl.NET\server ThoughtWorks.CruiseControl.MsBuild.dll
           </logger>
</msbuild>

This builds the code that has been checked out. Note that the workingDirectory values are the same.

I also added another block which complies the nUnit tests. In my case, the trunk directory that was checked out contains both the data classes and Nunit test classes so only one checkout was required.

Now that the code has been complied, the unit tests are to be run. I have added the path to the nunit exes to the system path. The Nunit-console.exe runs the tests and creates an xml file containing the status report of the tests run against the classes.

I added the exec block inside the tags

       <exec>
          <executable>nunit-console.exe</executable>
          <baseDirectory>
              C:\Program Files\NUnit 2.5.2\bin\net-2.0
          </baseDirectory>
          <buildArgs>
             c:\dev\ccnet\trunk\NunitTests\bin\Debug\NunitTests.dll
           /xml:c:\testresults\testoutput.xml
           </buildArgs>
          <buildTimeoutSeconds>10</buildTimeoutSeconds>
          <successExitCodes>0,1,3,5</successExitCodes>
       </exec>

At this point in the build process the tests have been run, so I now wanted to display the results in the CC web dashboard. To do this, I merged the testoutput.xml file into the build status output. This block needs to be put inside the block

<merge>
        <files>
            <file> c:\testresults\testoutput.xml</file>
          </files>
</merge>

Finally I activated the xmllogger, by adding to the block the

Under this configuration it was possible for me to check code into the trunk of my project, and force a build that checked out the code and unit tests, and automatically ran the tests against it, outputing the results to a the CCNet web dashboard, via a single click.

This entire process can be run from the CCNet web dashboard, or more conveniently, the CCTray sys tray program. There is a moderate overhead in setting up continuous integration but the return on investment grows the longer the system is developed.

Where to go on from here?

My setup could be improved in a number of ways.

  1. Auto build on each commit by using a post commit hook on subversion
  2. Selenium testing for the web functional tests
  3. using FxCop to analyse the complied code to find improvements and include this in build reports

Some of these topics I will explore in future posts

One thought on “Setting up Continuous Integration with Cruise Control.Net

  1. Pingback: Tweets that mention New Blog: post Continuous Integration & Cruise Control -- Topsy.com

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">

Code*: