Auto-versioning our assemblies in TeamCity using MSBuild was more fiddly than I expected but ultimately a very clean implementation.
I’m using TeamCity for continuous integration and MSBuild to run our project’s solution file (.sln) as the build script. I wanted each of our builds to have a version number on the assembly (.exe) so that testers would know what they were dealing with. The format for the version number is the familiar dotted quad of Major.Minor.Build.Revision where the Build would be the build number from TeamCity and the Revision would be our version control system (VCS) revision number (our VCS is Perforce).
I use Scrum for Agile software construction, in an OpenUP project management process, so I’ve decided our Major number is the number of the release to the customer and the Minor is the iteration (Sprint) that produced the build. For example, my first build with this system was 0.8.282.11066 which means: we’ve yet to make a release to the customer (0); the build was from the eighth two-week Sprint (8); TeamCity has completed 282 builds; and Perforce is up to revision 11066.
MSBuildCommunityTasks includes an AssemblyInfo task. These are the steps I used to get this working:
(1) added MSBuildCommunityTasks to our “ExternalTools” folder in Perforce and submitted the MSBuild.Community.Tasks.dll and MSBuild.Community.Tasks.Targets files.
(2) integrated the MSBuildCommunityTasks items from step 1 into the solution’s “tools” folder.
(3) updated the MSBuild.Community.Tasks.Targets file to the correct path to the MSBuildCommunityTasksLib (in our “tools” folder from step 2).
(4) imported the Targets file from step 3 into the project file (.csproj).
<MSBuildCommunityTasksTargets>..\tools\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets</MSBuildCommunityTasksTargets>
<Import Project="$(MSBuildCommunityTasksTargets)" />
(5) created the properties for the parts of the version number so it is easy to update for releases and works both on the developer’s machine, where the Build number and Revision number are set to 0, and on TeamCity which provides environment variables for the TeamCity build number and the VCS revision number.
<PropertyGroup>
<!-- Release -->
<Major>0</Major>
<!-- Iteration -->
<Minor>9</Minor>
<Build>0</Build>
<Build Condition="'$(BUILD_NUMBER)' != ''">$(BUILD_NUMBER)</Build>
<Revision>0</Revision>
<Revision Condition="'$(BUILD_VCS_NUMBER)' != ''">$(BUILD_VCS_NUMBER)</Revision>
<Version>$(Major).$(Minor).$(Build).$(Revision)</Version>
</PropertyGroup>
(6) deleted the current AssemblyInfo.cs from the source and the VCS.
(6) add the AssemblyInfo task that will autogenerate the AssemblyInfo.cs for each build
<Target Name="BeforeBuild">
<AssemblyInfo CodeLanguage="CS"
OutputFile="$(MSBuildProjectDirectory)\Properties\AssemblyInfo.cs"
AssemblyTitle="MyProduct"
AssemblyDescription="My Product"
AssemblyConfiguration=""
AssemblyCompany="MyCompany Ltd"
AssemblyProduct="MyProduct"
AssemblyCopyright="Copyright © MyCompany Ltd 2009"
AssemblyTrademark=""
ComVisible="false"
CLSCompliant="true"
Guid="884276aa-6859-4318-8bb9-073f68a66057"
AssemblyVersion="$(Version)" />
</Target>
Now I need to create a WiX project to build a release version and expose it as an artifact in TeamCity so our testers can easily pick up a build themselves.
Technorati Tags: MSBuildCommunityTasks AssemblyInfo TeamCity MSBuild