Tuesday, November 15, 2011

nANT C# Assembly Labeller (CruiseControl.NET)

If your using CruiseControl.NET for your build automation then your going to implement it's biggest advantage: Controlled and consistent version labeling.

The example below shows hows to add version labeling to CruiseControl.NET and then access the label in nANT for processing AssemblyInfo.cs files.


Step 1:  Add the CruiseControl.NET assemblyVersionLabeller to your ccnet.config file. This will provide access to the CCNETLabel environment variable for the rest of your project.

   NOTE: In the example below, major, minor and build are hard coded into ccnet.config file to provide a single point of control, revision will be generated from the source control system.

CCNET.CONFIG
   <labeller type="assemblyVersionLabeller">
       <major>5</major>
       <minor>6</minor>
       <build>2</build>
       <incrementOnFailure>false</incrementOnFailure>
   </labeller>



Step 2:  Create your nANT script to search and update all AssemblyInfo.cs files in your source code. You will have to update the <items basedir="..\..\"> based on the location of your nANT script and your source code.

 nANT_AssemblyLabeler.build
<?xml version="1.0"?>
<project name="setversion" default="setversion">
<target name="setversion" description="Sets the version number to CruiseControl.Net label.">

    <script language="C#">
        <references>
            <include name="System.dll" />
        </references>
        <imports>
            <import namespace="System.Text.RegularExpressions" />
        </imports>
        <code><![CDATA[

             [TaskName("setversion-task")]
             public class SetVersionTask : Task
             {
              protected override void ExecuteTask()
              {
               StreamReader reader = new StreamReader(Project.Properties["filename"]);
               string contents = reader.ReadToEnd();
               reader.Close();

               string replacement = "[assembly: AssemblyVersion(\"" + Project.Properties["CCNetLabel"] + "\")]";

               string newText = Regex.Replace(contents, @"\[assembly: AssemblyVersion\("".*""\)\]", replacement);

               string replacement2 = "[assembly: AssemblyFileVersion(\"" + Project.Properties["CCNetLabel"] + "\")]";

               string newText2 = Regex.Replace(newText , @"\[assembly: AssemblyFileVersion\("".*""\)\]", replacement2);

               System.Console.WriteLine("Updating Version: " + Project.Properties["CCNetLabel"] + ", AssemblyFile : " + Project.Properties["filename"]);

               StreamWriter writer = new StreamWriter(Project.Properties["filename"], false);
               writer.Write(newText2);
               writer.Close();

              }
             }
             ]]>
        </code>
    </script>

    <foreach item="File" property="filename">
        <in>
            <items basedir="..\..\">
                <include name="**\AssemblyInfo.cs"></include>
            </items>
        </in>
        <do>
            <setversion-task />
        </do>
    </foreach>
</target>
</project>




Step 3: Add the following nANT task inside your <tasks> node before compiling the source code to update all AssemblyInfo.cs files.


CCNET.CONFIG
  <nant>
    <executable>C:\AutomateBuild\nant-0.91\bin\nant.exe</executable>       <baseDirectory>C:\Source_Trunk\ReleaseManagement\Scripts</baseDirectory>
    <nologo>false</nologo>
    <buildFile>nANT_AssemblyLabeler.build</buildFile>
    <buildTimeoutSeconds>6000</buildTimeoutSeconds>
  </nant>


No comments: