I consider myself a neophyte when it comes to continuous integration (CI), but having read up on the topic, “played around” a bit, reviewed a couple of products, and having now incorporated it into our standard development practices, I am starting to hold my own.  If nothing else, the benefits of continuous integration are now obvious and, well, I can’t imagine ever turning back. 

For me, the power of continuous integration extends far beyond build validation.  CI it has become a welcome management tool which allows me to keep my finger on the pulse of numerous developed products as well as individual developer contributions.  Though I am very interested in the overall success/fail state of the current build, equally valuable is the the notifications which email specified team members the code change log which accompanies each build. (i.e. A list modified files and associated comments since the last automated build.)  If you are responsible for overall project success (which typically includes management of deliverable, code quality, task distribution, etc) then continuous integration is for you.

As I mentioned earlier, I reviewed a few products.  Last year, I reviewed FinalBuilder which provided me a nice and easy introduction into this space.  Based almost completely on its popularly and price tag (free), I have since turned to CruiseControl.NET.  I will not claim that was able to quickly get up and running with CruiseControl.NET.  At times, I was down-right questioning if I was smart enough to figure out the product and its configuration.  But, alas, it is now running on a dedicated build machine and my team and I are all the better for it. 

Please let it be known that I am not a wizard when it comes to CruiseControl.NET.  I am, however, good at is documentation of repeatable actions and I tried to capture the steps on getting started with CruiseControl.NET below.  As always, any feedback is greatly appreciated.

By the way, if you are looking for general information on continuous integration or CruiseControl.NET, you are not going to find here.  For more information, you may wish to consult the following:  What is Continuous Integration and What is CruiseControl.NET.

That’s basically it.  Best of luck!

 

1. Find a Build Machine

Though CruiseControl.NET could be installed on a development machine, I recommended that it be installed on a dedicated build server. Your build server should have access your source control repository and an optimal STMP server.  The server should have IIS and the NET Framework installed as well.  More information on the build server to follow…

 

2. Install CruiseControl.NET

Download CruiseControl.NET Server and Dashboard and install using provided default selections. 

http://downloads.sourceforge.net/ccnet/CruiseControl.NET-1.3-setup.exe?modtime=1182463056&big_mirror=0

 

3. Install MSBuild

If you are working with .NET 2.0+ applications, you can build using MSBuild. Otherwise, you may need to learn a bit about NANT.  All of the provided sample configurations below assume you will be using MSBuild. 

The MSBuild DLL is not included in initial CCNET Server installation, but it can be downloaded from the ThoughtWorks site: http://ccnetlive.thoughtworks.com/MSBuildXmlLogger%2DBuilds/. To install, simply copy the ThoughtWorks.CruiseControl.MSBuild.dll into C:\Program Files\CruiseControl.NET\server\ location.

 

4. Install Source Control Client

You will potentially need to install your source control client on the build machine. For the samples provides, we are using Borland StarTeam 2005.  CruiseControl.NET integrates with just about every source control system I could think of, so if you are using something other than StarTeam, you will want to consult the Source Control Block documentation.

 

5. CruiseControl.NET Server Configuration

CruiseControl.NET Server is driven by CCNET configuration file settings. After the fresh install, the configuration is essentially empty and requires manual updates to the ccnet.config file itself. As far as my knowledge, there is no associated configuration editor.  First things first, crack open “C:\Program Files\CruiseControl.NET\server\ccnet.config” in Visual Studios or your favorite XML editor. (There is shortcut under All Programs > CruiseControl.NET > CruiseControl.NET Config.)

If you have a pre-configured ccnet.config file available, simply overwrite the file content. If you are starting from scratch, you may wish reference the online CruiseControl.NET configuration overview and review samples: http://confluence.public.thoughtworks.org/display/CCNET/Configuring+the+Server.  Additional example configuration files were installed on your build box as well: C:\Program Files\CruiseControl.NET\Examples.  They are worth a look.

The bad news: Though you will find examples sprinkled throughout the ThoughtWorks site and the locations noted above, you will most likely need to muck around with your own config file for a while until you get it right.  Additional samples are provide below, but just as I wasn’t able to find the magic configuration combination to get my server running right off the bat, I bet you won’t either. 

The good news: Getting the right configuration was trail-and-error process for me.  I kept the configuration very simple at first and then built upon it.  Hopefully the next steps can help you with your troubleshooting.

 

6. Start CruiseControl.NET Server

The CCNET Server is not started at the time of installation. Thus, you will need to start the service manually: Administrative Tools > Services > CruiseControl.NET Server > Select > Start the service.

If the service fails at startup, it will immediately stop and present the following generic dialogue:

The CruiseControl.NET Server service on Local Computer started and then stopped. Some services stop automatically if they have no work to do, for example, the Performance Logs and Alert service.

If you encounter this error your first stop is to consult the logs: C:\Program Files\CruiseControl.NET\server\ccnet.log. By default, the file contains verbose logging which is helpful (although somewhat difficult to navigate.)  Believe me, the logs are your fried.

Based on the log file feedback, I suggest tweaking the ccnet.config file and then restarting the service – repeating until the service is fully configured.  And, if it is easier for you, you may run the CCNET Server via the command window: CD C:\Program Files\CruiseControl.NET\server > ccnet.exe.  This approach will render errors in the cmd window rather than having to monitor the ccnet.log file.  It was a time saver for me at least.

Once the project is successfully setup, you will see something similar to the following listed in the logs:

· [CCNet Server:DEBUG] The trace level is currently set to debug. This will cause CCNet to log at the most verbose level, which is useful for setting up or debugging the server. Once your server is running smoothly, we recommend changing this setting in C:\Program Files\CruiseControl.NET\server\ccnet.exe.config to a lower level.

· [CCNet Server:INFO] Reading configuration file “C:\Program Files\CruiseControl.NET\server\ccnet.config”

· [CCNet Server:INFO] Registered channel: tcp

· [CCNet Server:INFO] CruiseManager: Listening on url:tcp://localhost:21234/CruiseManager.rem

· [CCNet Server:INFO] Starting CruiseControl.NET Server

· [PROJECTNAME:INFO] Starting integrator for project: PROJECTNAME

At this point, the Server is waiting to initiate the next build. Based on the config file <triggers> setting it could take a while to get the checkout and build to fire. Adjust the following setting to around 10 seconds while still in the testing phase:

<triggers>
  <intervalTrigger name="continuous" seconds="10"
                   buildCondition="IfModificationExists"/>
</triggers>

On a similar note, the Server restarts itself automatically each time the ccnet.config file is modified.

 

7. Potential Gotchas

I ran into a couple specific cases while debugging which I suspect could be common issues. 

1. Ensure the MSBuild timeout value allows enough time to the build to complete. This will otherwise return in a failure which wasn’t easy to troubleshoot.

<msbuild>
  <timeout>600</timeout>
</msbuild>

2. For web solutions, update the TargetPath for the Debug and/or Release build of the application to be outside of the source application directory. Otherwise, you will receive the following error:

ASPNETCOMPILER : error ASPRUNTIME: The precompilation target directory cannot be in the same tree as the source application directory.

This can be done by modifying the following in the solution file:

Debug.AspNetCompiler.TargetPath = “c:\ccnet\PrecompiledWeb\SampleWeb\”
Release.AspNetCompiler.TargetPath = “c:\ccnet\PrecompiledWeb\SampleWeb\”

Alternative, one may update the Output location found in the application MSBuild properties.

You may be wondering why an updated solution won’t be updated with the next scheduled build.  As it works out (and makes sense) only changes which are applied to source control are pulled onto the build box. 

 

8. Automating Your Builds

Once the build process is running successfully, modify the <intervalTrigger> setting to a reasonable value and then update the “CruiseControl.NET Server” Service Startup Type to Automatic and then Start the service.  I might suggest also crossing your fingers for the next day or so.

 

9. Monitoring Your Builds

The CCNet Web Dashboard Application is used for reporting a wide range of information. At one end of the scale it reports summary details of all projects being managed by CruiseControl.NET and at the other it can give specific metric output for any specific build.  The Dashboard is setup with your initial installation.  You may access the Dashboard application by navigating a location similar to the following: http://buildbox.com/ccnet/ViewFarmReport.aspx.  For more information on the Web Dashboard: http://confluence.public.thoughtworks.org/display/CCNET/Web+Dashboard

The CCTray an optional utility for use with the CruiseControl.NET Continuous Integration server. It provides feedback upon build progress, and allows control over some of the server’s operations.  As “optional utility” implies, the CCTray isn’t included with the base installation.  You may download the Windows Tray Application from the following location and install using provided default selection: http://downloads.sourceforge.net/ccnet/CruiseControl.NET-CCTray-1.3-Setup.exe?modtime=1182463076&big_mirror=0. There isn’t much to using the CCTray but I do consider it a handy add-on.  Basically, you will find a shortcut to the CCTray on your desktop. Launch the application to begin monitoring the automated build(s) status and schedule.  The information provides via the CCTray is very similar to that which is provided in the Dashboard application.  For more information on CCTray: http://confluence.public.thoughtworks.org/display/CCNET/CCTray.

 

Sample Configuration Files

If you have made it this far, I really, really hope your required configuration is similar to mine.  If so, this is your golden ticket.  I have provided two flavors of configuration files below. You will undoubted need to tweak the files a bit (replace the project locations and names along with credentials will obviously be required), but hopefully these will help get you started.  By the way, the formatting of the XML leaves something to be desires as I have formatted to fit within the given real estate.

 

Windows Service, StarTeam, MSBuild, Emailing and Unit Tests

<cruisecontrol>
  <project name="SampleService" queue="Q1" queuePriority="0">
    <workingDirectory>c:\Projects\Services\SampleService
      </workingDirectory>
    <artifactDirectory>c:\ccnet\artifacts\Services\SampleService
      </artifactDirectory>
    <category>Continuous Builds</category>
    <webURL>http://buildbox.com/ccnet/server/local/project/
      SampleService/ViewProjectReport.aspx</webURL>
    <triggers>
      <intervalTrigger name="continuous" seconds="600"
                       buildCondition="IfModificationExists"/>
    </triggers>
    <state type="state" directory="c:\ccnet\state"/>
    <labeller type="defaultlabeller">
      <prefix>Build-1.0.</prefix>
      <incrementOnFailure>false</incrementOnFailure>
    </labeller>
    <sourcecontrol type="starteam">
      <executable>c:\Program Files\Borland\StarTeam 2005\
        stcmd.exe</executable>
      <project>Project</project>
      <username>user</username>
      <password>password</password>
      <host>10.1.10.100</host>
      <port>11111</port>
      <path>Projects/Services/SampleService</path>
      <autoGetSource>true</autoGetSource>
    </sourcecontrol>
    <tasks>
      <msbuild>
        <executable>C:\WINDOWS\Microsoft.NET\Framework\
          v2.0.50727\MSBuild.exe
        </executable>
        <workingDirectory>C:\Projects\Services\SampleService
          </workingDirectory>
        <projectFile>SampleService.sln</projectFile>
        <buildArgs>/noconsolelogger /p:Configuration=Debug /v:m
          </buildArgs>
        <targets>Clean;Build</targets>
        <timeout>600</timeout>
        <logger>ThoughtWorks.CruiseControl.MsBuild.XMLLogger,
          C:\Program Files\CruiseControl.NET\server\
          ThoughtWorks.CruiseControl.MsBuild.dll</logger>
      </msbuild>
      <msbuild>
        <executable>C:\WINDOWS\Microsoft.NET\Framework\
          v2.0.50727\MSBuild.exe</executable>
        <workingDirectory>C:\Projects\Services\SampleService
          </workingDirectory>
        <projectFile>UnitTestBuild.proj</projectFile>
        <buildArgs>/noconsolelogger /p:Configuration=Debug /v:diag
          </buildArgs>
        <targets>Tests</targets>
        <timeout>1500</timeout>
        <logger>ThoughtWorks.CruiseControl.MsBuild.XMLLogger,
          C:\Program Files\CruiseControl.NET\server\
          ThoughtWorks.CruiseControl.MsBuild.dll</logger>
      </msbuild>
    </tasks>
    <publishers>
      <merge>
        <files>
          <file>c:\ccnet\artifacts\Services\SampleService\
            mbUnit-testResults.xml</file>
          <file>c:\ccnet\artifacts\Services\SampleService\
            msbuild-results.xml</file>
        </files>
      </merge>
      <xmllogger/>
      <email from="no-reply@buildbox.com"
              mailhost="localhost" includeDetails="TRUE">
        <users>
          <user name="User 1" group="BuildMaster"
                  address="user.one@buildbox.com"/>
          <user name="user 2" group="TechLead"
                  address="user.two@buildbox.com"/>
        </users>
        <groups>
          <group name="BuildMaster" notification="always"/>
          <group name="TechLead" notification="change"/>
        </groups>
      </email>
    </publishers>
  </project>
</cruisecontrol>

Web Application, StarTeam, MSBuild, Emailing, and Build Dependencies

<cruisecontrol>
  <project name="SampleWeb" queue="Q2"
           queuePriority="1">
    <workingDirectory>c:\Projects\Web\SampleWeb
      </workingDirectory>
    <artifactDirectory>c:\ccnet\artifacts\Web\SampleWeb
      </artifactDirectory>
    <category>Continuous Builds</category>
    <webURL>http://buildbox.com/ccnet/server/local/project/
      SampleWeb/ViewProjectReport.aspx</webURL>
    <modificationDelaySeconds>15</modificationDelaySeconds>
    <triggers>
      <intervalTrigger name="continuous" seconds="3600"
                       buildCondition="IfModificationExists"/>
      <projectTrigger project="SampleData">
        <!-- Force build when data component is successfully built. -->
        <triggerStatus>Success</triggerStatus>
        <innerTrigger type="intervalTrigger" seconds="30"
                      buildCondition="ForceBuild"/>
      </projectTrigger>
    </triggers>
    <state type="state" directory="c:\ccnet\state" />
    <labeller type="defaultlabeller">
      <prefix>SampleWeb-Build-</prefix>
      <incrementOnFailure>true</incrementOnFailure>
    </labeller>
    <sourcecontrol type="starteam">
      <executable>C:\Program Files\Borland\
        StarTeam Cross-Platform Client 2006 R2\stcmd.exe</executable>
      <project>Project</project>
      <username>user</username>
      <password>password</password>
      <host>10.1.10.100</host>
      <port>11111</port>
      <path>Projects/Web/SampleWeb</path>
      <autoGetSource>true</autoGetSource>
    </sourcecontrol>
    <tasks>
      <msbuild>
        <executable>C:\WINDOWS\Microsoft.NET\Framework\
          v2.0.50727\MSBuild.exe</executable>
        <workingDirectory>C:\Projects\Web\SampleWeb
          </workingDirectory>
        <projectFile>SampleWeb.sln</projectFile>
        <timeout>900</timeout>
        <buildArgs>/clp:PerformanceSummary /verbosity:d
          </buildArgs>
        <logger>C:\Program Files\CruiseControl.NET\server\
          ThoughtWorks.CruiseControl.MsBuild.dll</logger>
      </msbuild>
    </tasks>
    <publishers>
      <xmllogger />
      <buildpublisher>
        <publishDir>c:\ccnet\artifacts\Web\SampleWeb</publishDir>
        <useLabelSubDirectory>true</useLabelSubDirectory>
      </buildpublisher>
      <email from="no.reply@buildbox.com"
              mailhost="localhost" includeDetails="TRUE">
        <users>
          <user name="User 1" group="BuildMaster"
                  address="user.one@buildbox.com"/>
          <user name="user 2" group="TechLead"
                address="user.two@buildbox.com"/>
        </users>
        <groups>
          <group name="BuildMaster" notification="always"/>
          <group name="TechLead" notification="change"/>
        </groups>
      </email>
    </publishers>
    <externalLinks>
      <externalLink name="Sample Web"
             url="http://buildbox.com/SampleWeb/default.aspx" />
    </externalLinks>
  </project>
</cruisecontrol>

29 Comments to “Getting Started with CruiseControl.NET”

  1. Jonny,

    You might want to take a look at our Parabuild. It is much easier to install and configure than CruiseControl. Installation takes 2 minutes. Typical time to the first build run with Parabuild is about 15 minutes.

    Serge

  2. bgriswold says:

    I took a quick look and now I am intrigued. What you put together sounds really promising.

  3. Jon Galloway says:

    I’ve also heard good things about CIFactory, which helps set up CruiseControl and a lot of other services – unit testing, backup, installers, etc. http://www.cifactory.org/

  4. aaa says:

    Check out this blog if you are looking for a beginners article … amazing article
    http://gauravrohatgi.blogspot.com

  5. Craig says:

    Is there a way to set up cruise control to have emails go out to those uers who have committed files for a build that fails? I’ve read how you can set up users and not assign them to a group, which intern emails them whether the build fails or passes. I want the same kind of functionality, but only when the build fails. I dont want to have them get emailed if the build passes.

  6. bgriswold says:

    I can nearly meet your need. Check out the following: http://ccnet.sourceforge.net/C.....isher.html. Here you will see you can set up the notification values for groups to “always” or “change.” If set to “change” notifications will only be sent to group members when the status of the build changes from passed to failed or vice versa. In theory, this is what you want. Assuming the build is in a passing state, email the group upon failure and then email again once you’re passing again so everyone knows their back in business. I hope this helps.

  7. Eduardo says:

    I have a problem, I am getting this error:

    Task output: MSBUILD : error MSB1021: Cannot create an instance of the logger. Could not load file or assembly ‘ThoughtWorks.CruiseControl.MsBuild.XMLLogger\, ThoughtWorks.CruiseControl.MsBuild.dll’ or one of its dependencies. The given assembly name or codebase was invalid. (Exception from HRESULT: 0×80131047)Switch: ThoughtWorks.CruiseControl.MsBuild.XMLLogger, ThoughtWorks.CruiseControl.MsBuild.dll;C:\Projects\BuildingSolution\Artifacts\msbuild-results.xml

    Any Ideas??

  8. Martin Rakhmanov says:

    This post contains sample config which references mbUnit-testResults.xml file. How this file is generated – I cannot find an instruction to name it for the logger.

  9. Ben Griswold says:

    The reference is specific to the mbUnit testing suite. If you wish to hook up automated tests through CC.NET, mbUnit is an option and mbUnit actually generates the testResults.xml file. This file is not specific to CC.NET. The second online example config does not reference unit tests. You may wish to look into that option.

  10. Martin Rakhmanov says:

    Ben

    Then I guess there is a problem with the example. task will
    pick mbUnit-testResults.xml and msbuild-results.xml from the last
    task while the msbuild-results.xml from first MSBuild task
    (SampleService.sln) will never be E-mailed.

    I looked into the CCNET source: it seems to be impossible to specify
    anything else than default “msbuild-results.xml” for the MSBuild task
    logger output file.

    Martin

  11. Renette says:

    Hi Eduardo
    I also get the following problem:

    MSBUILD : error MSB1021: Cannot create an instance of the logger. Could not load file or assembly ‘ThoughtWorks.CruiseControl.MsBuild.XmlLogger\,c:\\Program Files\\CruiseControl.NET\\server\\ThoughtWorks.CruiseControl.MsBuild.dll’ or one of its dependencies. The given assembly name or codebase was invalid. (Exception from HRESULT: 0×80131047) Switch: ThoughtWorks.CruiseControl.MsBuild.XmlLogger

    I assume that you have solved your problem by now? Can you give me any ideas, please??

  12. Jean Dorme says:

    All, Just downloaded v1.4 of cruisecontrol.net I have added an example project but when I attempt to open a web browser http://localhost/ccnet the page is not available. I have installed IIS6 etc am I missing something?

  13. Lee says:

    You may need to check your virtual directory, ccnet, at IIS to allow it to execute both scripts and executables. Then you may also need to add the default page to the site, default.aspx.

    Hope this helps.

  14. Prasad says:

    Thanks for this, it saved my time.

  15. Ben Griswold says:

    @Prasad You’re welcome. I’m glad to help out.

  16. saurabh singh says:

  17. Chris says:

    What is the c:\ccnet folder structure, which is used for example in the block? Who creates it; who populates it?

  18. Chris says:

    What is the c:\ccnet folder structure, which is used for example in the artifactsDirectory block? Who creates it; who populates it?

    (Original message removed the artifactsDirectory word that I enclosed in angle brackets)

  19. Might I just say nice to read a comfort to find anyone who definitely understands what they may be discussing on the web. You actually understand how to take a problem to light and enable it to be significant. Even more people should study this and understand this particular side of the story. I can’t believe you’re not more popular because you actually have the gift.

  20. mgtexjbvbt says:

    ljxGjr cqtirosnznmp, [url=http://ltinkuqyqoho.com/]ltinkuqyqoho[/url], [link=http://rqqewiblycim.com/]rqqewiblycim[/link], http://rryljrejpiep.com/

  21. keratoconus says:

    Download link is broken to ThoughtWorks.CruiseControl.MsBuild.dll. Where can I find it?

    thank you in advance

  22. I mostly agree but there are a few points which are not conform my ideas.

  23. Wonderful beat ! I would like to apprentice while you amend your web site, how could i subscribe for a blog web site? The account aided me a acceptable deal. I had been a little bit acquainted of this your broadcast offered bright clear concept

  24. proxy list says:

    This is a set of words, not an essay. you are incompetent

  25. My business is attempting to receive the overall notion nonetheless My spouse and i dont seem and therefore.

  26. HostingHelp says:

    I want to know who is hosting this website please?

  27. Excellent giveaway….Thanks TJ….

Leave a Reply

You can wrap your code with [ruby][/ruby] or [python][/python] blocks for syntax highlighting and you can use these traditional tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>