Tuesday, April 18, 2006

Troubleshooting automated builds with CruiseControl.Net, PVCS and MSBuild

Following on from our efforts to automate our build process, I have been experimenting with Continuous Integration using CruiseControl.Net. This integrates the various parts of the build process such as source control, build tools, testing tools etc. and can remove a lot of the grunt work from performing builds. The cool thing about it is that it can be set up to poll the source control system for modifications and trigger a build whenever one of the source files changes so you get early notice of when the build is broken.

The tool is fairly well documented using a wiki. As with many wikis though, some parts of the documentation receive more attention than others. This caused me a few problems as we are using an old version of PVCS for source control and the PVCS docs are a bit thin. I got it working after a bit of trial and error and subsequent browsing of other areas of the site for different source control providers gave some tips that appear to be common to all source providers, so a common section would have been useful.

Installation was fairly simple and I proceeded to set up a simple test project:

<sourcecontrol type="pvcs">
<!--client executable-->
<executable>X:\VM\Win32\Bin\pcli.exe</executable>
<!--PVCS Database-->
<project>S:\PVCS Databases</project>
<subproject>/LIBRARY/.Net/NullableDateTimePicker</subproject>
<workingDirectory >C:\development\LIBRARY\.Net\NullableDateTimePicker</workingDirectory>
<!--<recursive >true</recursive>-->
<autoGetSource >True</autoGetSource>
<labelOrPromotionName >shared_DEV</labelOrPromotionName>
</sourcecontrol>
This configuration did not work and I had to investigate a bit more how it works. What seems to happen is that CruiseControl issues a succession of pcli commands and use the output from each to build further batch files for use by the next command. On my system, these batch files were saved to my temp directory:
C:\Documents and Settings\myname\Local Settings\Temp

When the next command attempted to use the file as input, the directory name was not escaped so the embedded spaces caused it to fail. I worked around this by setting my TEMP and TMP environment variables to point to C:\agtemp\temp this allowed me to proceed to the next step.

Now that the pcli commands were succesfully running, I had to change a source file in order to trigger the build. When I did this, I noticed that the pcli command produced by CruiseControl only got changed files when I had assumed that it would get all files in the project. This does make sense as the structure in PVCS does not neccesarily map directly to the .Net project structure. You are supposed to already have all the source code available in your working directory before starting CruiseControl which then just gets subsequent modifications before performing the build. If you need to get all of it then you can do a get for a specific label or promotion group by adding a </labelorpromotionname> element whose value corresponds to your label or promotion group.

Finally, I wasn't getting any executables even though the build was reported as succesful. This was another mistaken assumption on my part as I thought that it would automatically call MSBuild for the project. I added an MSBuild task to the project and configured it to call my solution file which then resulted in a shiny new dll in the release folder.

Thursday, April 13, 2006

Automating builds with PVCS and MSBuild

We are currently using PVCS version 6.8 as the Source Code Control system on a large .Net project. The project consists of 30 Assemblies so the builds take quite a while. I have been trying to get automated builds working so that we can run them as an overnight job. The script turned out to be quite simple in the end but working out the right combination of options was a trial and error process. Here is the script we used in the end:

REM -aworkpath Path to place workfiles in. Overrides default workspace for project
REM -bpprojpath path to base project to use when resolving references, required when -a or -o specified
REM -prDBpath to PVCS database
REM -z recursive flag, operate on specified project and all sub-projects
REM -gPromotionGroup get files with specified promotion group or higher
REM entity project to operate on

x:\vm\win32\bin\pcli get -bp"/Billing/Source" -gGBDEV -pr"X:\VM\vmdevint" -aH:\gettest -z "/Billing/Source"
REM cd to workpath
cd H:\gettest
REM
REM C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\msbuild /logger:EmailLogger,"C:\EmailLogger\bin\Release\EmailLogger.dll";To=buildmanager@tempuri.org;From=buildmanager@tempuri.org;Subject=BuildLog:%DATE%;Host=mail.tempuri.org Billing.sln
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\msbuild Billing.sln

The commented out call to msbuild includes a call to a custom logger that will email the results of the build. The source code for the logger was obtained from this blog