MEMPERBARUI:
Banyak hal telah berkembang sejak saya pertama kali menjawab pertanyaan ini. The Microsoft.NET.Sdk(artinya Anda harus menggunakan project gaya sdk) sekarang menyertakan dukungan untuk menambahkan hash commit ke versi informasi assembly serta ke metadata paket nuget, jika beberapa kondisi terpenuhi:
- The
<SourceRevisionId>properti harus didefinisikan. Ini dapat dilakukan dengan menambahkan target seperti ini:
<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>
Target ini mengeksekusi perintah yang akan SourceRevisionIddisingkat menjadi hash yang disingkat (8 karakter). SebelumTarget menyebabkan ini dijalankan sebelum versi informasi rakitan dibuat.
Untuk menyertakan hash dalam metadata paket nuget, <RepositoryUrl>harus juga ditentukan.
<SourceControlInformationFeatureSupported>properti harus true, ini menyebabkan tugas paket nuget untuk mengambil SourceRevisionId juga.
Saya akan menjauhkan orang dari penggunaan paket MSBuildGitHash, karena teknik baru ini lebih bersih dan paling konsisten.
ASLI:
Saya telah membuat paket nuget sederhana yang dapat Anda sertakan dalam proyek Anda yang akan menangani ini untuk Anda: https://www.nuget.org/packages/MSBuildGitHash/
Paket nuget ini mengimplementasikan solusi MSBuild "murni". Jika Anda lebih suka tidak bergantung pada paket nuget Anda cukup menyalin Target ini ke dalam file csproj Anda dan itu harus menyertakan git hash sebagai atribut perakitan khusus:
<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>
Ada dua target di sini. Yang pertama, "GetGitHash", memuat git hash ke dalam properti MSBuild bernama BuildHash, ini hanya melakukan ini jika BuildHash belum ditentukan. Ini memungkinkan Anda untuk meneruskannya ke MSBuild pada baris perintah, jika Anda mau. Anda bisa meneruskannya ke MSBuild seperti ini:
MSBuild.exe myproj.csproj /p:BuildHash=MYHASHVAL
Target kedua, "WriteGitHash", akan menulis nilai hash ke sebuah file di folder "obj" sementara bernama "CustomAssemblyInfo.cs". File ini akan berisi baris yang terlihat seperti:
[assembly: AssemblyMetadata("GitHash", "MYHASHVAL")]
File CustomAssemblyInfo.cs ini akan dikompilasi ke dalam assembly Anda, sehingga Anda dapat menggunakan refleksi untuk mencari AssemblyMetadatasaat runtime. Kode berikut menunjukkan bagaimana hal ini dapat dilakukan ketika AssemblyInfokelas disertakan dalam rakitan yang sama.
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;
}
}
Beberapa manfaat desain ini adalah tidak menyentuh file apa pun di folder proyek Anda, semua file yang dimutasi berada di bawah folder "obj". Proyek Anda juga akan dibangun secara identik dari dalam Visual Studio atau dari baris perintah. Ini juga dapat dengan mudah disesuaikan untuk proyek Anda, dan akan dikontrol sumbernya bersama dengan file csproj Anda.