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: , ,

2 Responses

Subscribe to comments with RSS.

  1. Justin Koreska said, on April 3, 2013 at 3:31 PM

    Thanks so much for mentioning the bug in 1.4.0.56, where GitVersion does not set the property. It does work in 1.4.0.45.

    I just killed a half hour and it coulda been a lot more! I owe you a beer. Thanks again.

  2. Gourav said, on July 13, 2016 at 1:00 PM

    Thanks a lot for this code snippet. i am wondering what other Taskparamter we can use. I am looking forward to use latest Tag number instead of commit number. Could you please help me here.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: