AKTUALISIEREN:
Die Dinge haben sich weiterentwickelt, seit ich diese Frage ursprünglich beantwortet habe. Das Microsoft.NET.Sdk(dh Sie müssen ein Projekt im SDK-Stil verwenden) unterstützt jetzt das Hinzufügen des Commit-Hashs sowohl zur Assembly-Informationsversion als auch zu den Metadaten des Nuget-Pakets, wenn einige Bedingungen erfüllt sind:
- Die
<SourceRevisionId>Eigenschaft muss definiert werden. Dies kann durch Hinzufügen eines Ziels wie folgt erfolgen:
<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>
Dieses Ziel führt einen Befehl aus, SourceRevisionIdder als abgekürzter (8 Zeichen) Hash festgelegt wird. Die BeforeTargets bewirken, dass dies ausgeführt wird, bevor die Assembly-Informationsversion erstellt wird.
Um den Hash in die Metadaten des Nuget-Pakets aufzunehmen, <RepositoryUrl>muss auch der Hash definiert werden.
<SourceControlInformationFeatureSupported>Eigenschaft muss sein true, dies bewirkt, dass die Nuget-Pack-Task auch die SourceRevisionId aufnimmt.
Ich würde Leute davon abhalten, das MSBuildGitHash-Paket zu verwenden, da diese neue Technik sauberer und beständiger ist.
ORIGINAL:
Ich habe ein einfaches Nuget-Paket erstellt, das Sie in Ihr Projekt aufnehmen können und das dies für Sie erledigt: https://www.nuget.org/packages/MSBuildGitHash/
Dieses Nuget-Paket implementiert eine "reine" MSBuild-Lösung. Wenn Sie sich nicht auf ein Nuget-Paket verlassen möchten, können Sie diese Ziele einfach in Ihre csproj-Datei kopieren. Der Git-Hash sollte als benutzerdefiniertes Assembly-Attribut enthalten sein:
<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>
Hier gibt es zwei Ziele. Der erste, "GetGitHash", lädt den Git-Hash in eine MSBuild-Eigenschaft namens BuildHash. Dies geschieht nur, wenn BuildHash noch nicht definiert ist. Auf diese Weise können Sie es in der Befehlszeile an MSBuild übergeben, wenn Sie dies bevorzugen. Sie können es wie folgt an MSBuild weitergeben:
MSBuild.exe myproj.csproj /p:BuildHash=MYHASHVAL
Das zweite Ziel, "WriteGitHash", schreibt den Hashwert in eine Datei im temporären Ordner "obj" mit dem Namen "CustomAssemblyInfo.cs". Diese Datei enthält eine Zeile, die wie folgt aussieht:
[assembly: AssemblyMetadata("GitHash", "MYHASHVAL")]
Diese CustomAssemblyInfo.cs-Datei wird in Ihre Assembly kompiliert, sodass Sie mithilfe der Reflektion nach der AssemblyMetadataLaufzeit suchen können . Der folgende Code zeigt, wie dies durchgeführt werden kann, wenn die AssemblyInfoKlasse in derselben Assembly enthalten ist.
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;
}
}
Einige Vorteile dieses Designs sind, dass es keine Dateien in Ihrem Projektordner berührt. Alle mutierten Dateien befinden sich im Ordner "obj". Ihr Projekt wird auch in Visual Studio oder über die Befehlszeile identisch erstellt. Es kann auch einfach an Ihr Projekt angepasst werden und wird zusammen mit Ihrer csproj-Datei quellgesteuert.
git rev-parse HEADDas würde dir den Hash bringen, aber ich bin kein C # -Entwickler, also weiß ich nicht, wie du es erreichen kannst.