Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I pass build number from Nant back to Cruise Control

I have a Nant build script which CruiseControl uses to build a solution on-demand.

However, we only recently got CruiseControl so our official build number is different from what is listed in CruiseControl.

I know CruiseControl injects some properties into build scripts so that I can access the CC build number in the script (CCNetLabel) but how do I pass a value back to CC to use as the build number on the UI screen?

Example, CC says build number 2

nAnt script increments a buildnumber.xml value every build, and the official build number is on 123.

I want the CC UI to show last successful build number: 123, not 2, so how do I pass that value back up?

like image 266
Matthew Rathbone Avatar asked Nov 06 '08 11:11

Matthew Rathbone


2 Answers

A custom build labeler is required for this. Perforce is our source control provider and we derive our version number from it. The code is as follows:

/// <summary>
/// Gets the latest change list number from perforce, for ccnet to consume as a build label.
/// </summary>
[ReflectorType( "p4labeller" )]
public class PerforceLabeller : ILabeller
{
    //  perforce executable (optional)
    [ReflectorProperty("executable", Required = false)]
    public string P4Executable = "p4.exe";

    // perforce port (i.e. myserver:1234)
    [ReflectorProperty("port", Required = false)]
    public string P4Port = String.Empty;

    // perforce user
    [ReflectorProperty("user", Required = false)]
    public string P4User = String.Empty;

    //  perforce client
    [ReflectorProperty("client", Required = false)]
    public string P4Client = String.Empty;

    // perforce view (i.e. //Dev/Code1/...)
    [ReflectorProperty("view", Required = false)]
    public string P4View = String.Empty;

    // Returns latest change list
    public string Generate( IIntegrationResult previousLabel )
    {
        return GetLatestChangelist(); 
    }

    // Stores latest change list into a label
    public void Run( IIntegrationResult result )
    {
        result.Label = GetLatestChangelist();
    }

    // Gets the latest change list
    public string GetLatestChangelist()
    {
        // Build the arguments to pass to p4 to get the latest changelist
        string theArgs = "-p " + P4Port + " -u " + P4User + " -c " + P4Client + " changes -m 1 -s submitted " + P4View;
        Log.Info( string.Format( "Getting latest change from Perforce using --> " + theArgs ) );

        // Execute p4
        ProcessResult theProcessResult = new ProcessExecutor().Execute( new ProcessInfo( P4Executable, theArgs ) );

        // Extract the changelist # from the result
        Regex theRegex = new Regex( @"\s[0-9]+\s", RegexOptions.IgnoreCase );
        Match theMatch = theRegex.Match( theProcessResult.StandardOutput );
        return theMatch.Value.Trim();
    }
}

The method, GetLatestChangelist, is where you would probably insert your own logic to talk to your version control system. In Perforce there is the idea of the last changelist which is unique. Our build numbers, and ultimately version numbers are based off of that.

Once you build this (into an assembly dll), you'll have to hook it into ccnet. You can just drop the assembly into the server directory (next to ccnet.exe).

Next you modify your ccnet project file to utilize this labeller. We did this with the default labeller block. Something like the following:

<project>
<labeller type="p4labeller">
    <client>myclient</client>
    <executable>p4.exe</executable>
    <port>myserver:1234</port>
    <user>myuser</user>
    <view>//Code1/...</view>
</labeller>
<!-- Other project configuration to go here -->
</project>

If you're just wanting the build number to show up in ccnet then you're done and don't really need to do anything else. However, you can access the label in your NAnt script if you wish by using the already provided CCNetLabel property.

Hope this helps some. Let me know if you have any questions by posting to the comments.

like image 82
Scott Saad Avatar answered Sep 23 '22 09:09

Scott Saad


Did you try to use some environment variables? I believe CCNet can handle these.

I'll dig a bit on this.

Well I see a solution, quite dirty, but anyhow:

1- Add a defaultlabeller section in your CCNET project definition. It will contains the pattern of the build number you want to display.

2- Within NAnt, have a script to update your configuration file, inserting the build number you want to see.

3- Touch (in the Unix sense) the ccnet.exe.config file so as to make it re-load the projects configuration files.

et voilà.

like image 29
Vinzz Avatar answered Sep 20 '22 09:09

Vinzz