CẬP NHẬT:
Mọi thứ đã phát triển kể từ khi tôi trả lời câu hỏi này ban đầu. Các Microsoft.NET.Sdk
(có nghĩa là bạn phải sử dụng một dự án sdk-style) hiện nay bao gồm hỗ trợ cho việc thêm các cam kết băm để cả hai phiên bản lắp ráp cung cấp thông tin cũng như các siêu dữ liệu gói NuGet, nếu một số điều kiện được đáp ứng:
- Các
<SourceRevisionId>
bất động sản phải được xác định. Điều này có thể được thực hiện bằng cách thêm một mục tiêu như sau:
<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>
Mục tiêu này thực thi một lệnh sẽ được đặt thành SourceRevisionId
băm (8 ký tự) viết tắt. Các BeforeTargets làm cho điều này được chạy trước khi phiên bản thông tin lắp ráp được tạo.
Để bao gồm băm trong siêu dữ liệu gói nuget, <RepositoryUrl>
cũng phải được xác định.
<SourceControlInformationFeatureSupported>
phải là thuộc tính true
, điều này khiến nhiệm vụ gói nuget cũng nhận SourceRevisionId.
Tôi sẽ hướng mọi người tránh sử dụng gói MSBuildGitHash, vì kỹ thuật mới này rõ ràng hơn và nhất quán nhất.
NGUYÊN:
Tôi đã tạo một gói nuget đơn giản mà bạn có thể đưa vào dự án của mình, gói này sẽ giải quyết việc này cho bạn: https://www.nuget.org/packages/MSBuildGitHash/
Gói nuget này thực hiện một giải pháp MSBuild "thuần túy". Nếu bạn không muốn phụ thuộc vào gói nuget, bạn có thể chỉ cần sao chép các Mục tiêu này vào tệp csproj của mình và nó phải bao gồm băm git dưới dạng thuộc tính lắp ráp tùy chỉnh:
<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>
Có hai mục tiêu ở đây. Cái đầu tiên, "GetGitHash", tải git băm vào một thuộc tính MSBuild có tên BuildHash, nó chỉ thực hiện điều này nếu BuildHash chưa được định nghĩa. Điều này cho phép bạn chuyển nó đến MSBuild trên dòng lệnh, nếu bạn thích. Bạn có thể chuyển nó cho MSBuild như vậy:
MSBuild.exe myproj.csproj /p:BuildHash=MYHASHVAL
Đích thứ hai, "WriteGitHash", sẽ ghi giá trị băm vào một tệp trong thư mục "obj" tạm thời có tên "CustomAssemblyInfo.cs". Tệp này sẽ chứa một dòng giống như sau:
[assembly: AssemblyMetadata("GitHash", "MYHASHVAL")]
Tệp CustomAssemblyInfo.cs này sẽ được biên dịch vào tập hợp của bạn, vì vậy bạn có thể sử dụng phản chiếu để tìm kiếm AssemblyMetadata
thời gian chạy. Đoạn mã sau đây cho thấy cách này có thể được thực hiện khi AssemblyInfo
lớp được bao gồm trong cùng một assembly.
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;
}
}
Một số lợi ích của thiết kế này là nó không chạm vào bất kỳ tệp nào trong thư mục dự án của bạn, tất cả các tệp bị đột biến đều nằm trong thư mục "obj". Dự án của bạn cũng sẽ xây dựng giống hệt nhau từ trong Visual Studio hoặc từ dòng lệnh. Nó cũng có thể được tùy chỉnh dễ dàng cho dự án của bạn và sẽ được kiểm soát nguồn cùng với tệp csproj của bạn.