There’s been a lack of programming content here of late…

I’m trying to implement a continuous integration strategy with my dev team as we move forward with a new project, so I decided to look into CruiseControl .NET.  V. 0.8 just came out, so I started clean with that.  It was a hell of a day getting it set up, so I’m hoping I can help a few people out with this.

First of all, huge thanks to Joe Field for his excellent guide (pertinent to 0.7).  It got me about 90% of the way there.  Second, I don’t know everything about CCNET…I just started using it today.  But it’s so far so cool.

Prerequisites

Okay, my setup is physically 3 machines.  Build Machine, Source Machine, and Client Machine.  You can do it all on one machine as well, which is what I did at first on my laptop to see how it went.

The following needs to be installed:

Build Machine:

Visual Studio .NET 2003
Visual Source Safe 6.0d
CruiseControl .NET v 0.8
NAnt
NAntContrib
NUnit (if you’re running unit tests…not included in this guide.  Check Joes’ guide for that)No

Source Machine

Visual Source Safe 6.0d

Client Machine:

.Net Framework 1.1

on the build machine, extract the CCNET into a directory.  I used the following structure:

c:\CruiseControl
    /server
    /webservice
    /web
    /webdashboard
    /cctray
    /doc
    /NAnt

which is basically the default folder structure of CCNET with the NAnt directory added in.  Unzip NAnt into the nant directory.  Unzip NAntContrib and put the binaries from it into the bin folder of NAnt.

Setup

Now you need to set it up.  First, launch sourcesafe admin.  You want to create a separate ccnet user for your source repository.  For example’s sake, we’ll say it’s login:ccnet pwd:ccnet.

Go to the server directory of your ccnet installation.  create a new text file called ccnet.config.  In it, put the following:

<

cruisecontrol>
     <project>
         
<name>ProjectName</name>
         
<webURL>http://localhost/ccnet</webURL>
         
<triggers>
              
<intervalTrigger seconds="60" />
         
</triggers>
         
<sourcecontrol type="vss">
               
<project>SourceProjectName</project>
              
<username>ccnet</username>
              
<password>ccnet</password>
              
<ssdir>\\sourcemachine\vss</ssdir>
         
</sourcecontrol>
         
<build type="nant">
              
<executable>C:\CruiseControl\NAnt\bin\nant.exe</executable>
              
<baseDirectory>C:\CruiseControl</baseDirectory>
              
<buildFile>cruise.build</buildFile>
              
<targetList>
                   
<target>run</target>
              
</targetList>
         
</build>
         
<publishers>
              
<xmllogger>
                   
<logDir>c:\CruiseControl\web\log</logDir>
              
</xmllogger>
         
</publishers>
     
</project>
</
cruisecontrol>

 

Basically it breaks down like this: 

name = whatever you want to call this project in ccnet
weburl = the url to the web portal (get to this shortly)
intervalTrigger = how long between checks for build server (v 0.8 only.  earlier versions are a different attribute)
sourcecontrol = this is where you set your source control options.  I use VSS here, but you can use SVN, CVS, Vault, and a bunch of others.
project = project name in VSS.  if there is a space in the project name you will need quotations:  “project name”
ssdir =  the path that holds the srcsafe.ini for the repository
build = I don’t really know all the options for this yet.  What I have comes from Joe’s article.
logDir = directory for the build logs to be consumed by the web site.  create this folder

In the base ccnet directory you are now going to want to create a text file called cruise.build.  This is what we told nant to look at.  To get this example to run it simply needs to consist of the following:

<?xml version="1.0"?>
<project default="run">
 <target name="run">
 </target>
</project>

so now, open a command prompt, go to the server directory, and run ccnet.exe.  You should see it say a bunch of stuff about accessing the source repository, trying to build, and then a success or failure.  It will repeat every 60 seconds (if you keep that parameter the same) and will report “No Modifications” if nothing has happened recently.  If you check in a change, you will get a new log.  If not, it will just idle for another 60 seconds.

Setting up the web portal

This part is easy.  In IIS admin, create a new virtual directory and point it at the /web folder of your cc install.  Give it read and script permissions.  Set the default document to default.aspx.  Done and done.

Notes on this:  If you are getting messages about log file exceptions, make sure that A) you have set up the log folder in the web directory that you specified in ccnet.config. 2) that ccnet.exe is writing xml files there.  iii) that the ServerLogFilePath in web.config points to the ccnet.log file path (found in the “server” directory).  That should cover those bases…I had log errors for a while until I got all that running.

Running CCTRAY

CCTRAY.exe is found in the cctray folder.  Bring that folder to the client machine and run cctray.exe.  Right-click on it and go to settings.  Change the TCP listener machine name to match the build machine.  Make sure to select a project.  This is nice because it polls and keeps you updated on status, and you can force a build from the context menu.

Running CCNET as a Service

The thing that gave me the most headache, that I just got working, is running the system as a service on the build machine so that nobody has to be logged on.  First, you will need to install the service with installutil from the vs.net command prompt.  the service is ccservice.exe.

it will ask you for a login to use.  This is the key issue.  I don’t know what the requirements are on this login, but whatever they are, they’re annoying.  I had everything running fine with the console app, and the last step was setting up the service.  When I started using the service, I got nonstop build errors of:

 

ThoughtWorks.CruiseControl.Core.CruiseControlException: Source control operation failed: No VSS database (srcsafe.ini) found. Use the SSDIR environment variable or run netsetup.

 

So, I proceeded to spend the next several hours googling (no good) and troubleshooting my VSS installation.  I was using a generic domain user that we have set up for application authentication as the login.  Finally, out of frustration, I changed it to my credentials.  The service started working.  I switched back to the app user, and gave it all manner of rights on both the build machine and the source machine, no dice.  So it’s still on my user.  But the console app worked fine.  Strange stuff.  Now that I’m typing, I have a thought…one sec while I check it out…

Okay no.  I was thinking that maybe the ccservice is ignoring or not properly using the login settings from ccnet.config, but I made some tests and that doesn’t seem to be the case.  Or I didn’t test it right.  Either way, it’s strange behavior.  I’m not entirely comfortable this thing running under my domain credentials…plus it’s a pain in the ass come password change time…so if anyone knows or has any input on this part of it, please let me know.

Wrap-up

So that’s the basic setup.  For a really more thorough description see Joe's article which is much better than this one.  I wanted to just get out some of the frustrations I had with this so that maybe if others come across the same they can turn here for help.

When I get unit tests integrated and FxCop then I’ll write that process up.

**Note:  Found out today that BizTalk and his buddies SharePoint and InfoPath FUBAR a web server something fierce.  I was going to make our test BizTalk server my build machine, but I couldn’t get the web stuff running to save my life.  So I’m running it on a utility server.

Hope this helps someone.  If I have anything wrong, or you have a clarification on a point, please comment or email me so I can fix/add.


Tags: