Nathan Evans' Nemesis of the Moment

Adding the Git changeset hash on every build

Posted in .NET Framework, Automation, Uncategorized by Nathan B. Evans on March 27, 2013

Version numbers in the traditional sense were obsoleted ever since DVCS arrived on the scene. They’re still useful for literal human consumption but I prefer having the full Git (or Hg) changeset hash available on the assembly as well so I can literally do CTRL+SHIFT+G on GitExtensions (or the equiv. on TortoiseHg etc) and paste in the changeset hash to go directly to it.

To set this up is fairly simple. Firstly, ensure your Git.exe is in your PATH. It generally will be if you installed Git with default/recommended settings. Second, import the NuGet package for MSBuild Community Tasks. Make sure you import the older version available here as there is a bug in the newer versions where the GitVersion task is broken.

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(SolutionDir)\.build\MSBuild.Community.Tasks.targets" />

  <Target Name="UpdateVersionAssemblyInfo" BeforeTargets="BeforeBuild">
    <PropertyGroup>
      <Major>1</Major>
      <Minor>0</Minor>
      <Build>0</Build>
      <Revision>0</Revision>
      <GitHash>unknown</GitHash>
    </PropertyGroup>

    <GitVersion LocalPath="$(SolutionDir)" Short="false">
      <Output TaskParameter="CommitHash" PropertyName="GitHash" />
    </GitVersion>

    <AssemblyInfo
      CodeLanguage="CS"
      OutputFile="$(SolutionDir)\VersionAssemblyInfo.cs"
      AssemblyInformationalVersion="$(Major).$(Minor).$(Build).$(Revision) (git $(GitHash))"
      AssemblyVersion="$(Major).$(Minor).$(Build).$(Revision)"
      AssemblyFileVersion="$(Major).$(Minor).$(Build).$(Revision)" />
  </Target>
</Project>

Create a VersionAssemblyInfo.cs in your solution root, and create a “Link” to this file in all your projects.

Then in each project file you just need to add a new import, typically underneath the “Microsoft.CSharp.targets” import.

<Import Project="$(SolutionDir)\VersionAssemblyInfo.targets" />

Now rebuild your project(s). If you check the disassembly with a tool like JustDecompile or Reflector and look at the assembly attributes you should see that (little known and rarely used) AssemblyInformationalVersionAttribute is there and contains both the human-readable major.minor.build.revision as well as the Git changeset hash.

You may now choose to replace the various areas of your application that display version information with this attribute instead.

Tagged with: , ,