ОНОВЛЕННЯ:
Речі склалися з моменту, коли я спочатку відповів на це питання. 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 спричиняють це до запуску до створення інформаційної версії збірки.
Щоб включити хеш до метаданих пакунків на нуті, <RepositoryUrl>необхідно також визначити.
<SourceControlInformationFeatureSupported>властивості повинно бути true, це призводить до того, що завдання пакету «nuget» також підбирає SourceRevisionId.
Я б ухиляв людей від використання пакету MSBuildGitHash, оскільки ця нова методика є більш чистою та найбільш послідовною.
ОРИГІНАЛ:
Я створив простий пакунок, який ви зможете включити у свій проект, який буде за вас подбати про це: https://www.nuget.org/packages/MSBuildGitHash/
Цей пакунок від «nuget» реалізує «чисте» рішення MSBuild. Якщо ви бажаєте не залежати від пакета нута, ви можете просто скопіювати ці цілі у свій файл 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.