New MSBuild Extension Pack

Brian Harry posted today about a new MSBuild Extension Pack project on CodePlex. I figured this would be a good opportunity to demonstrate how you can use it to version the assemblies in your builds. Here are the steps for setting up assembly versioning for your builds using the MSBuild Extension Pack.

1. Download and install the MSBuild Extension Pack on your build machine(s).
2. Create a base target file with the following XML:

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" >
<Import Project="$(MSBuildExtensionsPath)\ExtensionPack\MSBuild.ExtensionPack.tasks" />

<!-- ASSEMBLY VERSIONING -->
<PropertyGroup>
<AssemblyMajor>1</AssemblyMajor>
<AssemblyMinor>0</AssemblyMinor>
</PropertyGroup>

<Target Name="GenerateAssemblyVersion">
<!-- Get a version number based on the elapsed days since a given date -->
<!--TfsVersion TaskAction="GetVersion" BuildName="$(BuildDefinition)" TfsBuildNumber="$(BuildNumber)" VersionFormat="Elapsed" StartDate="17 Nov 1976" PaddingCount="4" PaddingDigit="1" Major="$(AssemblyMajor)" Minor="$(AssemblyMinor)">
<Output TaskParameter="Version" PropertyName="AssemblyVersion" />
</TfsVersion-->
<!-- Get a version number based on the format of a given datetime -->
<TfsVersion TaskAction="GetVersion" BuildName="$(BuildDefinition)" TfsBuildNumber="$(BuildNumber)" VersionFormat="DateTime" DateFormat="MMdd" PaddingCount="5" PaddingDigit="1" Major="$(AssemblyMajor)" Minor="$(AssemblyMinor)">
<Output TaskParameter="Version" PropertyName="AssemblyVersion" />
</TfsVersion>
<Message Text="New Version is $(AssemblyVersion)" />
</Target>

<Target Name="VersionAssemblies">
<!-- Run the CreateItem task to populate the group after the source code has been downloaded. -->
<CreateItem Include="$(SolutionRoot)\**\AssemblyInfo.cs">
<Output TaskParameter="Include" ItemName="FilesToVersion" />
</CreateItem>
<!-- Set the version in a collection of files -->
<TfsVersion TaskAction="SetVersion" SetAssemblyVersion="true" Files="%(FilesToVersion.Identity)" Version="$(AssemblyVersion)" />
</Target>
</Project>

3. Save the file and copy it out to the MSBuild directory under Program Files on your build machine(s).

The GenerateAssemblyVersion target shows a couple of ways to use the GetVersion action of the TfsVersion task to generate different assembly version formats. The task has several attributes that allow you to customize the format to fit your needs. Check out the help file included with the MSBuild Extension Pack installation for more details.

To actually use this functionality in your builds, just add the following XML to your TFSBuild.proj files.

<Import Project="$(MSBuildExtensionsPath)\My.TeamFoundation.Build.targets" />

<PropertyGroup>
<AssemblyMajor>3</AssemblyMajor>
<AssemblyMinor>5</AssemblyMinor>
</PropertyGroup>

<Target Name="AfterGet">
<CallTarget Targets="GenerateAssemblyVersion;VersionAssemblies" />
</Target>

Here, you override the base values of the AssemblyMajor and AssemblyMinor properties from your base target file. In addition, you're overriding the built-in AfterGet target that is part of Team Build to call the custom targets in your base target file. This keeps the amount of duplicated MSBuild script very low.

UPDATE: Mike Fourie has a great post on some additional things you should consider when setting up assembly versioning in your builds. Of note is the separation of the AssemblyVersion and AssemblyFileVersion attributes when working with strong-named assemblies.

jb

No comments: