Tuesday, December 28, 2010

Versioning with ccnet

Every mature project has its own versioning system. There are a lot of different approaches. Microsoft recommends following:
Version numbers consist of two to four components: major, minor, build, and revision. The major and minor components are required; the build and revision components are optional, but the build component is required if the revision component is defined. All defined components must be integers greater than or equal to 0.
It's more or less clear about major and minor versions. But what about build and revision? In reality Microsoft uses different approaches e.g.:
The build number is frequently set to increment on a daily basis, either starting at 1 and continuing from there, or as some representation of the date of the build. For Visual Studio 2005, the build numbers are of the form YYMMDD. The revision is typically used to differentiate between multiple builds on the same day, usually starting at 1 and incrementing for each build.
Be aware that build numbers based on date have one pitfall. If you set build number e.g. 101228 in visual studio you will get this error message:

You will get similar error if you build project by msbuild. Problem is discussed here.

This was short introduction. Now let me describe how to implement versioning in ccnet.
In my project we use following structure:
  • major - major version
  • minor - number of sprint in scrum
  • build - MMdd
  • revision - subversion revision number
Also we have assembly description YYYMMdd rev.{revision}  which provides full date.
We found this format the most handy because it provides all necessary information about a library.

What we have in ccnet? First of all we added svnRevisionLabeller plug-in.This plug-in allows you to get revision number from svn.

ccnet.config
Now in CCNetLabel you will have revision number. We just need to launch msbuild script to update version in AssemblyInfo.cs files e.g. from nant:

updateLibrariesVersion.xml looks as following:

Here we used additional msbuild task called AssemblyInfoTask.

Tuesday, June 15, 2010

Cruise Control .NET (ccnet) + NAnt + NUnit + White

We develop WPF application. This application has very simple UI but really complex logic. So we decided to write UI tests for it. We use White as UI test framework. White is just wrapper over UI Automation. It is pretty simple and powerful. Moreover it has source code so you can change whatever you want.

But White has one restriction. UI tests should be run in windows interactive mode. So this is the problem to run your tests on continuous build. Please look at this short article for details. There are two ways to avoid this restriction:
- use virtual machine like DMWare
- use TightVNC instead of standard Remote Desktop.

We decided to use TightVNC. It is freeware and we don't need to install additional operation system on virtual machine.

First of all you need to download TightVNC from their web site. Please be careful to install the same version of the server and viewer. Otherwise you'll get connection error.
Install TightVNC-server on your build server and TightVNC-viewer on your local box.

Connect to build server through TightVNC-viewer. If you have running ccnet as a service stop it. You need to launch ccnet just as console application. I didn't manage to run White tests when ccnet was running as a service. I tried to check "interact with the desktop" option in the service properties, tried to use different login accounts - nothing helped. Actually it's ok just to launch "C:\Program Files\CruiseControl.NET\server\ccnet.exe".
Finally don't forget to uncheck this option.



If you have correctly configured ccnet then that's all. If not I'll tell how to configure all this stuff.

We implemented following approach:
1. ccnet executes nant build through nant task.
2. nant builds project and executes nunit tests through exec task.
3. ccnet merges log of nunit with main log.

It seems that some issue in ccnet. It duplicates nunit log if you're using nunit task. I tried to use recommendations on their web site to avoid this. But without success.


ccnet.config

It launches nant build as executable and has 2 tasks as targets. One to compile project and second to run ui tests.
Then it merges nunit results into main log.

nant.build


This nant script just executes msbuild to build solution and then executes nunit to run tests. NUnit produces results into MyProject.Tests-results.xml. You can run this build both from ccnet process and standalone.