ОБНОВИТЬ:
С тех пор, как я изначально ответил на этот вопрос, все изменилось. Microsoft.NET.Sdk(То есть вы должны использовать проект СОК-стиль) теперь включает поддержку для добавления фиксации хэша как на сборочный информационную версию, а также метаданные NuGet пакета, если соблюдены некоторые условия:
<SourceRevisionId>Должно быть определено свойство. Это можно сделать, добавив такую цель:
<Target Name="InitializeSourceControlInformation" BeforeTargets="AddSourceRevisionToInformationalVersion">
<Exec
Command="git describe --long --always --dirty --exclude=* --abbrev=8"
ConsoleToMSBuild="True"
IgnoreExitCode="False"
>
<Output PropertyName="SourceRevisionId" TaskParameter="ConsoleOutput"/>
</Exec>
</Target>
Эта цель выполняет команду, которая будет установлена SourceRevisionIdкак сокращенный (8 символов) хэш. BeforeTargets заставляет это запускаться до создания информационной версии сборки.
Чтобы включить хэш в метаданные пакета nuget, <RepositoryUrl>также необходимо определить.
<SourceControlInformationFeatureSupported>свойство должно быть true, это заставляет задачу пакета nuget также получать SourceRevisionId.
Я бы посоветовал людям отказаться от использования пакета MSBuildGitHash, поскольку этот новый метод более понятен и согласован.
ОРИГИНАЛ:
Я создал простой пакет nuget, который вы можете включить в свой проект, который позаботится об этом за вас: https://www.nuget.org/packages/MSBuildGitHash/
Этот пакет nuget реализует «чистое» решение MSBuild. Если вы не хотите зависеть от пакета nuget, вы можете просто скопировать эти Targets в свой файл csproj, и он должен включать хэш git в качестве настраиваемого атрибута сборки:
<Target Name="GetGitHash" BeforeTargets="WriteGitHash" Condition="'$(BuildHash)' == ''">
<PropertyGroup>
<!-- temp file for the git version (lives in "obj" folder)-->
<VerFile>$(IntermediateOutputPath)gitver</VerFile>
</PropertyGroup>
<!-- write the hash to the temp file.-->
<Exec Command="git -C $(ProjectDir) describe --long --always --dirty > $(VerFile)" />
<!-- read the version into the GitVersion itemGroup-->
<ReadLinesFromFile File="$(VerFile)">
<Output TaskParameter="Lines" ItemName="GitVersion" />
</ReadLinesFromFile>
<!-- Set the BuildHash property to contain the GitVersion, if it wasn't already set.-->
<PropertyGroup>
<BuildHash>@(GitVersion)</BuildHash>
</PropertyGroup>
</Target>
<Target Name="WriteGitHash" BeforeTargets="CoreCompile">
<!-- names the obj/.../CustomAssemblyInfo.cs file -->
<PropertyGroup>
<CustomAssemblyInfoFile>$(IntermediateOutputPath)CustomAssemblyInfo.cs</CustomAssemblyInfoFile>
</PropertyGroup>
<!-- includes the CustomAssemblyInfo for compilation into your project -->
<ItemGroup>
<Compile Include="$(CustomAssemblyInfoFile)" />
</ItemGroup>
<!-- defines the AssemblyMetadata attribute that will be written -->
<ItemGroup>
<AssemblyAttributes Include="AssemblyMetadata">
<_Parameter1>GitHash</_Parameter1>
<_Parameter2>$(BuildHash)</_Parameter2>
</AssemblyAttributes>
</ItemGroup>
<!-- writes the attribute to the customAssemblyInfo file -->
<WriteCodeFragment Language="C#" OutputFile="$(CustomAssemblyInfoFile)" AssemblyAttributes="@(AssemblyAttributes)" />
</Target>
Здесь две цели. Первый, «GetGitHash», загружает хеш git в свойство MSBuild с именем BuildHash, только если BuildHash еще не определен. Это позволяет вам передать его в MSBuild из командной строки, если хотите. Вы можете передать его в MSBuild так:
MSBuild.exe myproj.csproj /p:BuildHash=MYHASHVAL
Вторая цель, «WriteGitHash», запишет хеш-значение в файл во временной папке «obj» с именем «CustomAssemblyInfo.cs». Этот файл будет содержать строку следующего вида:
[assembly: AssemblyMetadata("GitHash", "MYHASHVAL")]
Этот файл CustomAssemblyInfo.cs будет скомпилирован в вашу сборку, поэтому вы можете использовать отражение для поиска AssemblyMetadataсреды выполнения. В следующем коде показано, как это можно сделать, если AssemblyInfoкласс включен в ту же сборку.
using System.Linq;
using System.Reflection;
public static class AssemblyInfo
{
/// <summary> Gets the git hash value from the assembly
/// or null if it cannot be found. </summary>
public static string GetGitHash()
{
var asm = typeof(AssemblyInfo).Assembly;
var attrs = asm.GetCustomAttributes<AssemblyMetadataAttribute>();
return attrs.FirstOrDefault(a => a.Key == "GitHash")?.Value;
}
}
Некоторые преимущества этого дизайна заключаются в том, что он не затрагивает никакие файлы в папке вашего проекта, все измененные файлы находятся в папке "obj". Ваш проект также будет идентично собран из Visual Studio или из командной строки. Его также можно легко настроить для вашего проекта, и он будет управляться исходным кодом вместе с вашим файлом csproj.