Category Archives: statefilelabeller

How to share CCNET label across multiple projects and get incremented for each build

There is stateFileLabeler which you can use in ccnet.config to share same build label across multiple projects in CCNET like below-

<labeller type="stateFileLabeller">
     Project Name to pull Build Label From

But, build label will remain same, which is disadvantage,if you need incremental build label across multiple projects. You can create your own custom plugin for CCNET to do that. I have implemented like below-

1) Create C# Class Library Project and name it as sharedLabeller. Put below code in .cs file

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ThoughtWorks.CruiseControl.Core;
using ThoughtWorks.CruiseControl.Remote;
using System.IO;
using Exortech.NetReflector;

namespace ThoughtWorks.CruiseControl.Core.labeller

// this is the labeller name that will be used in  ccnet.config
public class SharedLabeller : ILabeller
[ReflectorProperty(“syncronisationFilePath”, Required = true)]
public string SyncronisationFilePath { get; set; }

#region ILabeller Members

public string Generate(IIntegrationResult previousResult)
if (ShouldIncrementLabel(previousResult))
return IncrementLabel();

if (previousResult.Status == IntegrationStatus.Unknown)
return “0”;

return previousResult.Label;

public void Run(IIntegrationResult result)
result.Label = Generate(result);


private string IncrementLabel()
if (!File.Exists(SyncronisationFilePath))
return “0”;

using (FileStream fileStream = File.Open(SyncronisationFilePath,
// read last build number from file
var bytes = new byte[fileStream.Length];
fileStream.Read(bytes, 0, bytes.Length);

string rawBuildNumber = Encoding.ASCII.GetString(bytes);

// parse last build number
int previousBuildNumber = int.Parse(rawBuildNumber);
int newBuildNumber = previousBuildNumber + 1;

// increment build number and write back to file
bytes = Encoding.ASCII.GetBytes(newBuildNumber.ToString());

fileStream.Seek(0, SeekOrigin.Begin);
fileStream.Write(bytes, 0, bytes.Length);

return newBuildNumber.ToString();

private static bool ShouldIncrementLabel(IIntegrationResult previousResult)
return (previousResult.Status == IntegrationStatus.Success || previousResult.Status == IntegrationStatus.Unknown);

2) Change properties of the project to output dll and name it like- ccnet.sharedLabeller.plugin
3) Build solution and copy in \server folder
4) Edit ccnet.config and ccnet.exe.config for Plugin location value and give path to the folder where you placed Plugin.
5) Create some file like buildnumber.txt in \server folder and edit ccnet.config for your project where to want to share your label incrementally-
        E:\Program Files\CruiseControl.NET\server\buildnumber.txt
Whenever build is triggered, it will increment label in buildnumber.txt and use in the project where it is being called.
Well, one drawback in above plugin is that it will increment label even for failure builds also.