Tag Archive for MSBuild

Bamboo Version Labelling

We’ve recently switched from CruiseControl.NET to Atlassian Bamboo for our CI. This was partly borne out of frustration with CC.NET’s XML-based configuration, but we also use Jira, Confluence and BitBucket, so the integration between these products and Bamboo had some appeal.

Naturally the conversion hasn’t been completely smooth. One thing that initially wasn’t particularly obvious was how to auto-increment a .NET project’s version number when building a deployment package, and how to then label the build in Bamboo with that version number.

Version Increment

The easiest way of adding build tasks to a Bamboo stage is to, well, add an MSBuild task. The clue’s in the name. There are plenty of pre-made build tasks out there. For incrementing the version number we’re going to use the MSBuild.ExtensionPack. This contains a wealth of build targets, including one called VersionNumber.

If all we want is to increment the version number, we just import the VersionNumber targets and set some attributes:

[html]
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="SetAssemblyInfo" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\MSBuild.Extension.Pack.1.5.0\tools\net40\MSBuild.ExtensionPack.VersionNumber.targets"/>
<Target Name="SetAssemblyInfo">
<MSBuild.ExtensionPack.Framework.AssemblyInfo
AssemblyInfoFiles="..\..\MyProject.Interface.Web\Properties\AssemblyInfo.cs"
AssemblyBuildNumberType="DateString"
AssemblyBuildNumberFormat="MMdd"
AssemblyRevisionType="AutoIncrement"
AssemblyRevisionFormat="00"
AssemblyFileBuildNumberType="DateString"
AssemblyFileBuildNumberFormat="MMdd"
AssemblyFileRevisionType="AutoIncrement"
AssemblyFileRevisionFormat="00" />
</Target>
</Project>
[/html]

The paths above assume I have placed the saved the above as [ROOT]\SolutionFiles\BuildTasks\IncrementAssemblyVersion.csproj, where [ROOT] is the root of the solution. The structure is unimportant. What matters is that the paths to MSBuild.ExtensionPack.VersionNumber.targets and your project’s AssemblyInfo.cs are correct.

The attributes I’ve set will produce version numbers in the following format:

Major.Minor.Date.Number

Where Date is the combination of zero-padded day of the month and month, eg 0208 if built on the 2nd of March. There is provision in VersionNumber.targets to format the version number using the year as well. I wouldn’t advise this as it will (dependent on the actual date) overflow the int which backs the version number.

The Number is a simple integer increment for each daily build. eg the first build for that day wil be 0, the next 1, and so on.

I like this as it gives some useful information about the build. It should be noted that for this to work you will need to set the masking in AssemblyInfo.cs appropriately. In this case, use “1.0.0.0”

To use this file in Bamboo, add a new MSBuild task to the build stage, and supply it with the path the project file. eg

SolutionFiles\buildtasks\IncrementAssemblyVersion.csproj

Labelling in Bamboo

It would also be nice to be able to see the version number for a build from Bamboo build list. This can be achieved using labels.

Now, before I proceed I have to hold up my hand and say that this feels like a bit of a kludge. However it was the only way I could see of achieving what I wanted, so I present it here in the hope that someone knows a better way and can tell me what it is.

In Bamboo, labels can be created by parsing the build log with regex. Yes, I know. I KNOW.

What I’ve done is add a build target which will write the current version number into the log file, so that it can be parsed as a label. I’ve reused the project file we created for the version increment for this, as it makes sense to write to the log immediately after setting it. The project file now contains:

[html]
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="SetAssemblyInfo;RetrieveIdentities" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\MSBuild.Extension.Pack.1.5.0\tools\net40\MSBuild.ExtensionPack.VersionNumber.targets"/>
<Target Name="SetAssemblyInfo">
<MSBuild.ExtensionPack.Framework.AssemblyInfo
AssemblyInfoFiles="..\..\MyProject.Interface.Web\Properties\AssemblyInfo.cs"
AssemblyBuildNumberType="DateString"
AssemblyBuildNumberFormat="MMdd"
AssemblyRevisionType="AutoIncrement"
AssemblyRevisionFormat="00"
AssemblyFileBuildNumberType="DateString"
AssemblyFileBuildNumberFormat="MMdd"
AssemblyFileRevisionType="AutoIncrement"
AssemblyFileRevisionFormat="00" />
</Target>

<Target Name="RetrieveIdentities">
<GetAssemblyIdentity AssemblyFiles="..\..\MyProject.Interface.Web\bin\MyProject.Interface.Web.dll">
<Output TaskParameter="Assemblies" ItemName="AssemblyInfo"/>
</GetAssemblyIdentity>
<Message Text="MyProject.Interface.Web.dll has been set to Version_%(AssemblyInfo.Version)" />
</Target>
</Project>
[/html]

It’s pretty straightforward. The RetrieveIdentities target is called after SetAssemblyInfo. It uses the GetAssemblyIdentity target to get the current version number from the specified .dll. It then writes a message to the log containing the version number.

To make use of this message, go to the Miscellaneous tab for your job in Bamboo. At the bottom is a section title Pattern Match Labelling. This is where we enter a regex pattern to retrieve out version number from the logs. The following pattern will do this:

(Version_[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)

Finally we just need to tell Bamboo to use the first match as the build label. Do so by entering \1 in the Labels box.