Letzten git commit für AssemblyVersion in MSBuild verwenden

Written on November 20, 2010

Um eine Verbindung zwischen einem Changeset am Code und der kompilierten Version einer Assembly herzustellen, gibt es die Möglichkeit, z.B. die Id des Commits der Quellecode-Verwaltung zu verwenden.

Am Beispiel von Git soll dies hier demonstriert werden.

Zunächst das Resultat, das wir erzielen möchten:

AssemblyProperties

Der Inhalt von "Product version" kommt aus der Einstellung AssemblyFileVersion in der AssemblyInfo.cs im Properties-Ordner des Projekts:

[assembly: AssemblyFileVersion("1.1. / c1c2d54")]

Dieses Setting könnten wir von Hand pflegen. Allerdings müßten wir dann, um die aktuelle Version der AssemblyInfo.cs im Git-Repository zu haben (welche dann vom Build-Server ausgecheckt wird), diese nochmal committen, sodass der letzte Commit nicht mehr unsere eigentliche Änderung am Code wäre, sondern eben der Commit der Änderung an der AssemblyInfo.cs

Um dieses Problem zu lösen, verwenden wir einen MSBuild-Task, der den SHA-Wert des letzten Commits aus dem Git-Repository ausliest und dann die AssemblyFileVersion vor dem Build aktualisiert und somit für das gewünschte Ergebnis sorgt.

Der verwendete MSBuild-Task heißt "GitVersion" und stammt von Stefan Holmberg.

Im MSBuild-File unseres Projektes ersetzen wir den auskommentierten Bereich (am Ende des Build-Files) der Targets "BeforeBuild" und "AfterBuild" durch folgende Xml-Fragment:

<Import Project="$(SolutionDir)Tools\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" />
<UsingTask AssemblyFile="$(SolutionDir)GitVersion.dll" TaskName="GitVersion" />
<PropertyGroup Label="versioning">
    <versioningMajor>1</versioningMajor>
    <versioningMinor>1</versioningMinor>
    <versioningBuild>0</versioningBuild>
    <versioningRevision>0</versioningRevision>
    <LastCommit>not avail</LastCommit>
</PropertyGroup>
<Target Name="BeforeBuild">
<GitVersion LocalPath="$(MSBuildProjectDirectory)">
    <Output TaskParameter="LastCommit" PropertyName="LastCommit" />
</GitVersion>
<AssemblyInfo 
        CodeLanguage="CS" 
        OutputFile="Properties\AssemblyInfo.cs" 
        AssemblyTitle="LastCommitMSBuild" 
        AssemblyDescription="LastCommitMSBuild" 
        AssemblyCompany="PDMLab" 
        AssemblyProduct="LastCommitMSBuild" 
        AssemblyCopyright="Copyright PDMLab 2010" 
        ComVisible="false" 
        CLSCompliant="false" 
        AssemblyVersion="$(versioningMajor).$(versioningMinor).$(versioningBuild).$(versioningRevision)" 
        AssemblyFileVersion="$(versioningMajor).$(versioningMinor). / $(LastCommit)" />
</Target>
<Target Name="AfterBuild">
</Target>

Die Funktionsweise des GitVersion-Tasks ist praktisch selbsterklärend:

  • Zunächst werden in einer PropertyGroup die Variablen für das Erstellen der Versionsnummer definiert und befüllt

  • Als Pfad wird das Projekt-Verzeichnis verwendet, welches das MSBuild-File definiert.

  • Der Output TaskParameter "LastCommit" enthält die aus dem Git-Repository gelesene SHA-Info des letzten Commits

  • Der nachgeschaltete AssemblyInfo-Task erzeugt eine AssemblyInfo.cs mit den gewünschten Werten und verwendet auch "LastCommit" an gewünschter Stelle

Die Beispiel-Solution kann hier heruntergeladen werden:

LastGitCommitMSBuild.zip (1.34 mb)

Vor der Verwendung muss diese in ein Git-Repository kopiert werden, damit der GitVersion-Task funktionieren kann.

Außerdem muss Git so konfiguriert sein, dass es in der Windows-Kommandozeile funktioniert.

DotNetKicks-DE Image