更新:
私が最初にこの質問に答えて以来、物事は進化してきました。Microsoft.NET.Sdk
いくつかの条件が満たされた場合には(あなたは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 packタスクはSourceRevisionIdも取得します。
MSBuildGitHashパッケージの使用を避けるようにします。この新しい手法はよりクリーンで一貫性が高いためです。
元の:
私はあなたがあなたのためにこれを処理するあなたのプロジェクトに含めることができる単純なnugetパッケージを作成しました:https ://www.nuget.org/packages/MSBuildGitHash/
このnugetパッケージは、「純粋な」MSBuildソリューションを実装します。nugetパッケージに依存したくない場合は、これらのターゲットを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>
ここには2つのターゲットがあります。最初の「GetGitHash」は、BuildHashという名前のMSBuildプロパティにgitハッシュをロードします。これは、BuildHashがまだ定義されていない場合にのみ行われます。これにより、必要に応じて、コマンドラインでMSBuildに渡すことができます。次のようにMSBuildに渡すことができます。
MSBuild.exe myproj.csproj /p:BuildHash=MYHASHVAL
2番目のターゲット「WriteGitHash」は、「CustomAssemblyInfo.cs」という名前の一時的な「obj」フォルダー内のファイルにハッシュ値を書き込みます。このファイルには、次のような行が含まれます。
[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ファイルとともにソース管理されます。