METTRE À JOUR:
Les choses ont évolué depuis que j'ai initialement répondu à cette question. Le Microsoft.NET.Sdk
(ce qui signifie que vous devez utiliser un projet de style sdk) inclut désormais la prise en charge de l'ajout du hachage de validation à la fois à la version informative de l'assembly ainsi qu'aux métadonnées du package nuget, si certaines conditions sont remplies:
- La
<SourceRevisionId>
propriété doit être définie. Cela peut être fait en ajoutant une cible comme celle-ci:
<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>
Cette cible exécute une commande qui sera définie SourceRevisionId
comme le hachage abrégé (8 caractères). BeforeTargets provoque cette exécution avant la création de la version informative de l'assembly.
Pour inclure le hachage dans les métadonnées du package nuget, le <RepositoryUrl>
doit également être défini.
<SourceControlInformationFeatureSupported>
la propriété doit être true
, cela oblige la tâche de pack de nugets à récupérer également le SourceRevisionId.
J'éviterais les gens d'utiliser le package MSBuildGitHash, car cette nouvelle technique est plus propre et plus cohérente.
ORIGINAL:
J'ai créé un package nuget simple que vous pouvez inclure dans votre projet et qui s'en chargera pour vous: https://www.nuget.org/packages/MSBuildGitHash/
Ce package nuget implémente une solution MSBuild «pure». Si vous préférez ne pas dépendre d'un package nuget, vous pouvez simplement copier ces cibles dans votre fichier csproj et il devrait inclure le hachage git comme attribut d'assemblage personnalisé:
<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>
Il y a deux cibles ici. Le premier, "GetGitHash", charge le hachage git dans une propriété MSBuild nommée BuildHash, il ne le fait que si BuildHash n'est pas déjà défini. Cela vous permet de le transmettre à MSBuild sur la ligne de commande, si vous préférez. Vous pouvez le transmettre à MSBuild comme ceci:
MSBuild.exe myproj.csproj /p:BuildHash=MYHASHVAL
La deuxième cible, "WriteGitHash", écrira la valeur de hachage dans un fichier du dossier temporaire "obj" nommé "CustomAssemblyInfo.cs". Ce fichier contiendra une ligne qui ressemble à:
[assembly: AssemblyMetadata("GitHash", "MYHASHVAL")]
Ce fichier CustomAssemblyInfo.cs sera compilé dans votre assembly, vous pouvez donc utiliser la réflexion pour rechercher le AssemblyMetadata
à l'exécution. Le code suivant montre comment cela peut être effectué lorsque la AssemblyInfo
classe est incluse dans le même 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;
}
}
Certains avantages de cette conception est qu'elle ne touche aucun fichier dans votre dossier de projet, tous les fichiers mutés se trouvent dans le dossier «obj». Votre projet sera également généré de manière identique à partir de Visual Studio ou de la ligne de commande. Il peut également être facilement personnalisé pour votre projet et sera contrôlé à la source avec votre fichier csproj.