I’ve created a similar setup as David Donald Belcham (a.k.a. igloocoder) mentions in this post for our current project at NOIS.
When I mean similar, we’re using the exact same tools for the job, with NAnt (asminfo task) & CC.NET. But there’s a couple of differences.
New labeller for CC.NET
The first, and minor difference is the labeller. I wanted the versions to work almost as the NAntContrib version task with the automatic build & revision based on day of year and time of day respectively. As most people were running the traditional ymmdd-format for the build, this effectively had to stop at the beginning of 07; 16 bit for the build number breaks that setup. So I settled for an algorithm which won’t break until the year 2066. The major & minor numbers is set manually.
I couldn’t seem to find such a labeller out there, and as I wanted the same number in the CC.NET build-number, and in the assemblies (and in the source control system as well, I’ll get back to that), CC.NET needed to be master. Not finding what I wanted, I created my own labeller for CC.NET, which gives me the build-numbering scheme I wanted.
With the extensibility-points in CC.NET it was great fun, and real easy to deploy my own. Here’s the whole thing:
using System;
using Exortech.NetReflector;
using ThoughtWorks.CruiseControl.Core;
namespace Haugern.Util.CCNet
{
[ReflectorType("versionLabeller")]
public class VersionLabeller : ILabeller
{
[ReflectorProperty("major", Required = true)]
public int Major;
[ReflectorProperty("minor", Required = true)]
public int Minor;
public string Generate(IIntegrationResult integrationResult)
{
if(integrationResult == null)
throw new ArgumentNullException(“integrationResult”);
DateTime now = DateTime.Now;
return Major + “.” + Minor + “.” + ComputeBuild(now) + “.” + ComputeRelease(now);
}
private static string ComputeRelease(DateTime now)
{
return Math.Round((now.TimeOfDay.TotalSeconds/10)).ToString();
}
private static string ComputeBuild(DateTime now)
{
return now.ToString(“yy”) + now.DayOfYear.ToString(“000″);
}
public void Run(IIntegrationResult result)
{
result.Label = Generate(result);
}
}
}
Consistent Build Number
The second difference (well, in his defence, it’s not even mentioned), is that the exact same label should be set back into the source control system. In our case, we’re using TFS Source Control, and with the standard plugin it was easy to apply it there as well.
Now we got this great setup where we can track everything that happens back to the build-number as it is the same across the whole environment:
Application <-> Build server <-> Source Control
Consistent build number across the production line also means every build is a candidate for release.
Should some bug find it way through our thorough unit-testing & qa-scheme into the hands of our customers, finding the right version to search for it will not be a problem!
#1 by Donald Belcham on January 12th, 2008
Hey man. My dad (the only David Belcham I know of) doesn’t have any idea what Continuous Integration is. I think it has something to do with him being a cattle farmer.
Thanks for the props dude.
#2 by Morten Haug on January 13th, 2008
Hi, sorry about that
Give him my greetings!
#3 by Kory on August 19th, 2011
Wow, this is in every respect what I ndeeed to know.