Wednesday, December 2, 2009

Continuous Integration Server Setup – Part 2

This is the second part of my process for setting up a prototype Continuous Integration server using CruiseControl.NET.  I describe the server setup in Part 1.  This post describes how I configured my projects and unit tests using the ccnet.config file.

I decided to use a Visual Studio 2008 console application solution as the test for my prototype CI server.  There were some steps required to set up that solution to build and test properly in a CI environment.  I detailed the solution configuration steps in a separate blog post.

I then edited the ccnet.config file to build and run my projects and unit tests.  I extensively followed the advice of Geoff Lane from his DRY your CruiseControl.NET Configuration post.

  • I defined reusable variables and blocks
  • I split my ccnet.config file into multiple parts.
    • The ccnet.config file itself contains the variable and block definitions that are shared by all projects.  It imports the user information and all project information from external files.  The ccnet.config file is managed in source control.
    • Individual project files config contain variable and block definitions specific to the projects.  All project files are managed in source control.
    • The user information is stored in a separate config file and contains the plain text UID and PWD for connecting to the SubVersion server.  The user config file is not managed in source control as a security precaution.

Download sample CruiseControl.NET ccnet.config and other config files

Here are some other Key Points:

  • The <artifactDirectory> and <workingDirectory> values should exactly mimic the folder structure in the Visual Studio solution so that all references are valid when the projects are checked out to the CI server.
  • Set the <webURL> value to use the actual host name (rather than localhost) so that CI email notifications contain a valid clickable link.
  • I configured my NUnit tests to run using the <nunit> task block, but I could have configured the unit tests to run as part of the MSBuild process in the .csproj file.
  • I configured the email publisher so that details are not included (<email includeDetails=”false” … />).  Including the details is a handy feature, but I discovered that anytime there was an exception when trying to connect to the SubVersion server, the cruisecontrol UID and password were included in the email details.
  • I manage the ccnet.config file itself in source control and added a CCNET project to the top of the ccnet.config file to check out the ccnet.config file.  In other words, set up CCNET so that when any developer makes a change to the ccnet.config file, the updated file is immediately checked out to the CI server by the previous version of the ccnet.config file.

Next steps to take the prototype to prime time on a production CI server:

  1. Resolve errors I am still seeing in the build logs – there are four occasional error messages:  “Source control operation failed: svn: OPTIONS of 'project name': Could not read status line: An existing connection was forcibly closed by the remote host” or “Source control operation failed: svn: Server sent unexpected return value (401 Authorization Required) in response to PROPFIND request for 'project name'” or “Source control operation failed: svn: OPTIONS of 'project name': SSL negotiation failed: An existing connection was forcibly closed by the remote host” or “Source control operation failed: svn: Server sent unexpected return value (401 Authorization Required) in response to REPORT request for 'project name'.”  I can think of several possible causes for these errors:
    1. These errors might go away when the CI server is set up as a true production server instead of as a VM virtual server.
    2. The CI server has a newer version of svn.exe than the version of SVN on the source control server.
    3. The self-signed certificate used by the source control server might have to be replaced with a commercial certificate.
  2. Consider changing my strategy so that NUnit tests are run after the build by MSBuild (rather than as a task in the ccnet.config file).  Using MSBuild is the recommended strategy suggested by the CCNET documentation and by Craig Berntson’s Continuous Integration for .NET Development white paper.
  3. Most of my projects are developed against the ESRI ArcGIS Server framework, which loads all of its assemblies to the GAC.  Despite best efforts to use local Lib copies (with Browse references) of the ESRI assemblies, it looks like the CI server will need to install ArcGIS Server to avoid build or test errors.

No comments:

Post a Comment