This post is going to focus on getting our version number automatically updated during the build process. We are going to use the AssemblyInfo task from the “MSBuild.Community.Tasks” library and the HgVersion task from the “MSBuild.Mercurial” library.
The HgVersion task will get the revision number from our Mercurial source control repository so we can include it in our assemblyInfo file.
The AssemblyInfo task will create our AssemblyInfo file before the compile task is executed.
If you are using TFS or Subversion you will need to substitute the Mercurial task for the equivalent task for these version control systems. The MsBuild.Community.Tasks contains a TFS and Subversion Version tasks for this purpose.
1) Getting the revision number from Mercurial.Firstly download and copy the MSBuild.Mercurial from http://msbuildhg.codeplex.com/releases/view/47779 and copy the following two files below to “[Project Root]\Tools\MSBuild.Mercurial” diretory:
Firstly we set “MsBuildMercurialPath” to the current directory. Then we import the Mercurial Tasks from our Tools directory.<PropertyGroup> <MSBuildMercurialPath>.</MSBuildMercurialPath> </PropertyGroup> <Import Project="Tools\MSBuild.Mercurial\MSBuild.Mercurial.Tasks" /> <Target Name="Hg-Revision"> <HgVersion LocalPath="$(MSBuildProjectDirectory)" Timeout="5000"> <Output TaskParameter="Revision" PropertyName="Revision" /> </HgVersion> <Message Text="Last revision from HG: $(Revision)"/> </Target>
Next we define a new target called “Hg-Revision” which calls the HgVersion task. The HgVersion task will set the revision number from the repository in the "LocalPath" to a property called “Revision”.
Lets test it out by running: build /t:hg-revision
2) Creating our Assembly Info FileNow we are going to create a task to automatically generate an assembly info file.
We need the MSBuild.Community.Tasks library from here: http://msbuildtasks.tigris.org/
Again I will copy the necessary files under the tools folder.
Once this is in place we can now generate our AssemblyInfo.cs file. I have called the output filename SolutionInfo.cs as I like to use the same file for each project in the solution (I’ll show you how to do this soon).<!-- Create an Assembly Info File --> <PropertyGroup> <Major>1</Major> <Minor>0</Minor> <Build>0</Build> <Revision>0</Revision> <MSBuildCommunityTasksPath>.</MSBuildCommunityTasksPath> </PropertyGroup> <Import Project=".\Tools\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" /> <Target Name="SolutionInfo"> <Message Text="Creating Version File: $(Major).$(Minor).$(Build).$(Revision)"/> <AssemblyInfo CodeLanguage="CS" OutputFile=".\Source\SolutionInfo.cs" AssemblyTitle="Jobping.StickyBseak" AssemblyDescription="StickyBeak logs requests to your website" AssemblyCompany="http://www.jobping.com/" AssemblyProduct="Jobping.StickyBeak" AssemblyCopyright="Copyright © whohive" ComVisible="false" CLSCompliant="true" Guid="1d4d1a0d-52f3-49d4-b2f8-3ca642f05cfe" AssemblyVersion="$(Major).$(Minor).$(Build).$(Revision)" AssemblyFileVersion="$(Major).$(Minor).$(Build).$(Revision)" /> </Target>
Let's test this by running: build /t:solutionInfo
As you can see we are using the hard-coded version number of 184.108.40.206 for the moment.
Now lets hook our SolutionInfo.cs file into our visual studio project and have it included in the build.
- Firstly go through your project and delete any existing AssemblyInfo files you may have under the “Properties” folder.
- For each project in your solution right click and select “Add Existing Item” from the context menu.
- Navigate to the SolutionInfo.cs file generated and add as a link. (See below on how to add as a link)
3) Combining the Hg-Revision and SolutionInfo TasksSo far our SolutionInfo task only uses a hard-coded revision number of "0". What we really want is to have this revision number linked to the source control revision number. This is really easy to achieve as follows.
So we have just combined the two items into a new task called VersionSolutionInfo. This task depends on the Hg-Revision and SolutionInfo tasks, so it will first call Hg-Revision to get the lastest revision number into our Revision property then when SolutionInfo is called it will use this revision number.<Target Name="VersionSolutionInfo" DependsOnTargets="Hg-Revision;SolutionInfo"> <Message Text="Get Revision, Generate SolutionInfo"/> </Target>
Lets execute it as follows: build /t:VersionSolutionInfo
As you can see, the revision number 10 is retrieved from mercurial and then the solutionInfo is generated. If you inspect the SolutionInfo.cs file you will find that the version number is now 220.127.116.11
The final step is to change our default build task to depend on VersionSolutionInfo so we can have everything done in 1 step.
NB: you can have any number of files containing the assembly meta data such as company, version etc. For example we could split it as follows:<Target Name="Build" DependsOnTargets="Clean;VersionSolutionInfo,Compile"> <Message Text="Clean, VersionSolutionInfo, Compile"/> </Target>
- SolutionInfo.cs – contains static information and is checked into source control
- SolutionInfo.geneated.cs – just contains version information (not checked in)
Update: You need to TAG your repository with the full version number so you can relate the release's version no to a changeset across all repositories. I'll post a build target to do the tag automatically at some point. Thanks to @jdhard for bringing this up.
Below I have provided two sample MsBuild files. Firstly we have our main build file that handles : clean & compile from the first post it this series. The second file contains the targets used in this post. I have split out the items so it's easy to isolate the Tasks for this post.
- Main MsBulid File - Main build with targets : clean, compile & build. Imports all other build files.
- Version MsBuild File - Contains targets from this post (to auto version AssemblyInfo from mercurial)
- MSBuild Project File Schema Reference - Microsoft documents on MsBuild
- Create a Build File for a Visual Studio Solution - MsBuild Series
- Mercurial Revision No to Version your AssemblyInfo - MsBuild Series
- Zipping Build Outputs - MsBuild Series
- NuPack packaging - MsBuild Series
- NUnit Testing - MsBuild Series (coming later)
- Web Projects and AspNetComplier - MsBuild Series (coming later)
- Cruise Control - MsBuild Series (coming later)