Incorporer le hachage git commit dans une dll .Net

102

Je construis une application C #, en utilisant Git comme contrôle de version.

Existe-t-il un moyen d'intégrer automatiquement le dernier hachage de validation dans l'exécutable lorsque je construis mon application?

Par exemple, l'impression du hachage de validation sur la console ressemblerait à ceci:

class PrintCommitHash
{
    private String lastCommitHash = ?? // What do I put here?
    static void Main(string[] args)
    {
        // Display the version number:
        System.Console.WriteLine(lastCommitHash );
    }
}

Notez que cela doit être fait au moment de la construction , pas au moment de l'exécution , car mon exécutable déployé n'aura pas le dépôt git accessible.

Une question connexe pour C ++ peut être trouvée ici .

EDIT

À la demande de @ mattanja, je poste le script git hook que j'utilise dans mes projets. La mise en place:

  • Les hooks sont des scripts shell Linux, qui sont placés sous: path_to_project \ .git \ hooks
  • Si vous utilisez msysgit , les hooks dossier contient déjà des exemples de scripts. Pour que git les appelle, supprimez l'extension '.sample' du nom du script.
  • Les noms des scripts hook correspondent à l'événement qui les appelle. Dans mon cas, j'ai modifié post-commit et post-merge .
  • Mon fichier AssemblyInfo.cs se trouve directement sous le chemin du projet (même niveau que le dossier .git ). Il contient 23 lignes et j'utilise git pour générer la 24e.

Comme mon shelling Linux est un peu rouillé, le script lit simplement les 23 premières lignes de AssemblyInfo.cs dans un fichier temporaire, renvoie le hachage git à la dernière ligne et renomme le fichier en AssemblyInfo.cs . Je suis sûr qu'il existe de meilleures façons de faire cela:

#!/bin/sh
cmt=$(git rev-list --max-count=1 HEAD)
head -23 AssemblyInfo.cs > AssemblyInfo.cs.tmp
echo [assembly: AssemblyFileVersion\(\"$cmt\"\)] >> AssemblyInfo.cs.tmp
mv AssemblyInfo.cs.tmp AssemblyInfo.cs

J'espère que cela t'aides.

Bavaza
la source

Réponses:

64

Nous utilisons des balises dans git pour suivre les versions.

git tag -a v13.3.1 -m "version 13.3.1"

Vous pouvez obtenir la version avec hachage de git via:

git describe --long

Notre processus de construction place le hachage git dans l'attribut AssemblyInformationalVersion du fichier AssemblyInfo.cs:

[assembly: AssemblyInformationalVersion("13.3.1.74-g5224f3b")]

Une fois que vous compilez, vous pouvez afficher la version à partir de l'explorateur Windows:

entrez la description de l'image ici

Vous pouvez également l'obtenir par programme via:

var build = ((AssemblyInformationalVersionAttribute)Assembly
  .GetAssembly(typeof(YOURTYPE))
  .GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false)[0])
  .InformationalVersion;

où YOURTYPE est n'importe quel type de l'assembly qui a l'attribut AssemblyInformationalVersion.

Artisan
la source
14
Salut, je voulais demander il y a un mois, mais je n'avais pas assez de représentant pour commenter. Lorsque vous dites: «Notre processus de construction met le hachage git dans l'attribut AssemblyInformationalVersion de AssemblyInfo.cs», que se passe-t-il exactement? Êtes-vous simplement en train de créer un studio visuel ou utilisez-vous quelque chose comme NAnt ou un autre outil?
John Jesus
3
Nous utilisons ruby ​​(rake) pour automatiser notre build. L'une de nos tâches de génération de rake met à jour le fichier CommonAssemblyInfo.cs qui est utilisé dans tous les projets de la solution. La tâche génère le fichier CommonAssemblyInfo.cs à l'aide d'albacore - github.com/derickbailey/Albacore L'une des valeurs AssemblyInfo que la tâche définit est AssemblyInformationalVersion.
Artisan
3
@John Jesus - comme Lazy Badger l'a suggéré, vous pouvez également utiliser des hooks git pour modifier AssemblyInfo.cs après validation / fusion, etc. (c'est ce que j'ai fini par faire). Voir kernel.org/pub/software/scm/git/docs/githooks.html
bavaza
Juste pour info, Albacore a déménagé dans une nouvelle organisation de hub: github.com/Albacore/albacore
kornman00
5
Le projet suivant https://github.com/jeromerg/NGitVersion propose une solution complète pour générer des GlobalAssemblyInfo.*fichiers au moment de la compilation pour les projets C # et C ++: Par défaut, la version d'assembly générée contient: le hachage de validation, un indicateur signalant les modifications locales et un incrément en comptant la quantité de validation de la racine du référentiel à la validation actuelle.
jeromerg
78

Vous pouvez incorporer un fichier version.txt dans l'exécutable, puis lire le fichier version.txt hors de l'exécutable. Pour créer le fichier version.txt , utilisezgit describe --long

Voici les étapes:

Utilisez un événement de construction pour appeler git

  • Faites un clic droit sur le projet et sélectionnez Propriétés

  • Dans les événements de construction, ajoutez un événement de pré-construction contenant (notez les guillemets):

    "C: \ Program Files \ Git \ bin \ git.exe" describe --long> "$ (ProjectDir) \ version.txt"

    Cela créera un fichier version.txt dans le répertoire de votre projet.

Incorporez le version.txt dans l'exécutable

  • Faites un clic droit sur le projet et sélectionnez Ajouter un élément existant
  • Ajoutez le fichier version.txt (modifiez le filtre du sélecteur de fichiers pour vous permettre de voir tous les fichiers)
  • Une fois version.txt ajoutée, cliquez dessus avec le bouton droit de la souris dans l'Explorateur de solutions et sélectionnez Propriétés
  • Changer l'action de génération en ressource intégrée
  • Modifier la copie dans le répertoire de sortie pour toujours copier
  • Ajoutez version.txt à votre fichier .gitignore

Lire la chaîne de version du fichier texte incorporé

Voici un exemple de code pour lire la chaîne de version du fichier texte incorporé:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;

namespace TryGitDescribe
{
    class Program
    {
        static void Main(string[] args)
        {
            string gitVersion= String.Empty;
            using (Stream stream = Assembly.GetExecutingAssembly()
                    .GetManifestResourceStream("TryGitDescribe." + "version.txt"))
            using (StreamReader reader = new StreamReader(stream))
            {
                gitVersion= reader.ReadToEnd();
            }

            Console.WriteLine("Version: {0}", gitVersion);
            Console.WriteLine("Hit any key to continue");
            Console.ReadKey();
        }
    }
}
Jean Jésus
la source
9
Cette approche fonctionne assez bien. J'ai cependant utilisé "git rev-parse --short HEAD".
Brian Reiter
3
Ah bien. J'ai utilisé "git describe" car c'est vraiment intéressant (pour moi) quand vous avez une balise; les informations de version ont la balise plus le nombre de validations après l'application de la balise; jamais vu quelque chose comme dans un SCM auparavant.
John Jesus
7
J'utilise git describe --dirty, qui ajoute un indicateur lorsque les développeurs travaillent avec un arbre de travail sale.
paulmelnikow
2
@ TamásSzelei, l'espace de noms du projet est TryGitDescribe. Une fois que le fichier version.txt est incorporé dans l'artefact exécutable / assembly, vous devez ajouter l'espace de noms au début pour le sortir.
John Jesus
2
Merci pour la solution complète. Dans mon cas, j'avais l'habitude GetEntryAssemblyde faire de l'assemblage. Dans tous les cas, vous pouvez appeler GetName().Namepour éviter de coder le nom en dur.
astrowalker
52

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:

  1. 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 SourceRevisionIdcomme le hachage abrégé (8 caractères). BeforeTargets provoque cette exécution avant la création de la version informative de l'assembly.

  1. Pour inclure le hachage dans les métadonnées du package nuget, le <RepositoryUrl>doit également être défini.

  2. <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 &gt; $(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 AssemblyInfoclasse 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.

MarkPflug
la source
2
Cela a parfaitement fonctionné. J'ai installé le package nuget et j'ai pu extraire le hachage git en utilisant Assembly.GetExecutingAssembly(), puis en examinant l'assembly CustomAttributes .
Gavin H
1
Si c'était ma question, j'aurais accepté cette réponse. Super truc.
Drew Noakes le
1
@GavinH, comment avez-vous obtenu le GitHash? Je peux voir que cette valeur existe mais existe-t-il une méthode pure pour obtenir un attribut personnalisé par nom? Il semble que je doive écrire une longue requête où sélectionner CustomAttributes, merci.
Okan Kocyigit
1
@ocanal oui - malheureusement, je n'ai pas trouvé de moyen plus propre de le faire que de lire le CustomAttributes. Par exemple, voici la fonction que j'utilise pour extraire la chaîne de hachage: pastebin.com/nVKGLhJC
Gavin H
2
@danmiser Je n'ai aucune idée de ce qu'est "UseMerge / SingleAssemblyName", donc je ne peux pas vous aider. Créez un problème sur github.com/MarkPflug/MSBuildGitHash et je pourrais y jeter un coup d'œil (ce n'est pas une promesse).
MarkPflug
14

Une autre façon de procéder consiste à utiliser NetRevisionTool avec un peu de magie à bord de Visual Studio. Je vais le présenter ici pour Visual Studio 2013 Professional Edition, mais cela fonctionnera également avec d'autres versions.

Alors téléchargez d'abord NetRevisionTool. Vous incluez NetRevisionTool.exe dans votre PATH ou archivez-le dans votre référentiel et créez une action de pré-build et post-build de Visual Studio et modifiez votre AssemblyInfo.cs.

Un exemple qui ajouterait votre git-hash à votre AssemblyInformationVersion serait le suivant: Dans les paramètres de votre projet:

entrez la description de l'image ici

dans AssemblyInfo.cs de votre projet, vous modifiez / ajoutez la ligne:

[assembly: AssemblyInformationalVersion ("1.1. {dmin: 2015}. {chash: 6} {!} - {branch}")]

dans la capture d'écran affichée, j'ai vérifié dans NetRevisionTool.exe dans le dossier External / bin

Après la construction, si vous cliquez avec le bouton droit sur votre binaire et accédez aux propriétés, vous devriez voir quelque chose comme ce qui suit:

entrez la description de l'image ici

J'espère que cela aide quelqu'un là-bas

Schmendrick
la source
Le hachage de validation pour moi finit toujours par 00000. Je pensais que c'était parce que j'avais des modifications non validées mais toujours les mêmes. Une idée pourquoi?
Viktor
3
Le problème était que NetRevision ne trouvait pas mon exécutable git. La raison en est que nous utilisons SourceTree et que git est intégré. La solution consistait à copier git.exe et libiconv-2.dll de% USERPROFILE% \ AppData \ Local \ Atlassian \ SourceTree \ git_local \ bin dans le dossier contenant NetRevision.exe. J'ai également dû modifier les événements comme suit: Événement de pré-construction: cd $ (ProjectDir) Bibliothèques NetRevisionTool.exe / patch $ (ProjectDir) Événement de post-construction: cd $ (ProjectDir) Bibliothèques NetRevisionTool.exe / restore $ (ProjectDir)
Viktor
Juste pour référence future, l'URL du dépôt du projet a changé il y a quelque temps en github.com/ygoe/NetRevisionTool . Plus d'informations sont également disponibles sur unclassified.software/apps/netrevisiontool .
ygoe
14

Je pense que cette question vaut la peine de donner une réponse complète étape par étape. La stratégie ici consiste à exécuter un script PowerShell à partir des événements de pré-construction qui prend un fichier modèle et génère un fichier AssemblyInfo.cs avec la balise git + les informations de comptage de validation incluses.

Étape 1: créez un fichier AssemblyInfo_template.cs dans le dossier Project \ Properties, basé sur votre AssemblyInfo.cs d'origine mais contenant:

[assembly: AssemblyVersion("$FILEVERSION$")]
[assembly: AssemblyFileVersion("$FILEVERSION$")]
[assembly: AssemblyInformationalVersion("$INFOVERSION$")]

Étape 2: Créez un script PowerShell nommé InjectGitVersion.ps1 dont la source est:

# InjectGitVersion.ps1
#
# Set the version in the projects AssemblyInfo.cs file
#


# Get version info from Git. example 1.2.3-45-g6789abc
$gitVersion = git describe --long --always;

# Parse Git version info into semantic pieces
$gitVersion -match '(.*)-(\d+)-[g](\w+)$';
$gitTag = $Matches[1];
$gitCount = $Matches[2];
$gitSHA1 = $Matches[3];

# Define file variables
$assemblyFile = $args[0] + "\Properties\AssemblyInfo.cs";
$templateFile =  $args[0] + "\Properties\AssemblyInfo_template.cs";

# Read template file, overwrite place holders with git version info
$newAssemblyContent = Get-Content $templateFile |
    %{$_ -replace '\$FILEVERSION\$', ($gitTag + "." + $gitCount) } |
    %{$_ -replace '\$INFOVERSION\$', ($gitTag + "." + $gitCount + "-" + $gitSHA1) };

# Write AssemblyInfo.cs file only if there are changes
If (-not (Test-Path $assemblyFile) -or ((Compare-Object (Get-Content $assemblyFile) $newAssemblyContent))) {
    echo "Injecting Git Version Info to AssemblyInfo.cs"
    $newAssemblyContent > $assemblyFile;       
}

Étape 3: enregistrez le fichier InjectGitVersion.ps1 dans le répertoire de votre solution dans un dossier BuildScripts

Étape 4: ajoutez la ligne suivante aux événements de pré-construction du projet

powershell -ExecutionPolicy ByPass -File  $(SolutionDir)\BuildScripts\InjectGitVersion.ps1 $(ProjectDir)

Étape 5: Créez votre projet.

Étape 6: Ajoutez éventuellement AssemblyInfo.cs à votre fichier git ignore

Atilio Jobson
la source
Et n'oubliez pas de rendre vos balises git compatibles avec les versions de fichiers: telles que 1.2.3. Si vous avez des balises plus compliquées, vous devrez analyser uniquement les parties compatibles
Atilio Jobson
2
Au lieu d'utiliser un modèle et de gitignoring réel, AssemblyInfo.cson pourrait modifier AssemblyInfo.cssur place, construire, puis git réinitialiser AssemblyInfo.csà la dernière version validée. Donc, dans le repo, il y aurait toujours AssemblyInfo.cs, avec $..$substitué uniquement pour le moment de la construction.
Kuba Wyrostek
Cela a très bien fonctionné. J'ai fini par utiliser git describe --match "v[0-9]*" --long --always --dirtypour filtrer certaines balises (celles contenant un numéro de version) et pour indiquer si l'arbre de travail était propre.
packoman
Vous devez également modifier votre RegEx dans le script PS:$gitVersion -match '[v](.*)-(\d+)-[g](.+)$';
packoman
4

C'est désormais très simple avec .NET Revision Task pour MSBuild et avec Visual Studio 2019.

Installez simplement le package NuGet Unclassified.NetRevisionTask , puis configurez les informations que vous souhaitez dans le AssemblyInfo.csfichier comme décrit dans la documentation GitHub .

Si vous ne voulez que le hachage du dernier commit (longueur = 8):

[assembly: AssemblyInformationalVersion("1.0-{chash:8}")]

Construisez votre projet / solution et vous aurez quelque chose comme ceci:

entrez la description de l'image ici

krlzlx
la source
Pour configurer le format dans une application NET.core, ajoutez le PropertyGroupau fichier .csproj comme vu dans le README github.com/ygoe/NetRevisionTask/blob/master/README.md
sc911
3

Comme l'autre réponse mentionne déjà le bit git, une fois que vous avez le SHA, vous pouvez envisager de générer le AssemblyInfo.csfichier de votre projet dans un hook de pré-construction.

Une façon de faire est de créer un AssemblyInfo.cs.tmplfichier de modèle, avec un espace réservé pour votre SHA, disons $$ GITSHA $$, par exemple

[assembly: AssemblyDescription("$$GITSHA$$")]

Votre hook de pré-génération doit ensuite remplacer cet espace réservé et générer le fichier AssemblyInfo.cs pour que le compilateur C # le récupère.

Pour voir comment cela peut être fait en utilisant SubWCRev pour SVN, consultez cette réponse . Cela ne devrait pas être difficile de faire quelque chose de similaire pour git.

D'autres moyens seraient une "étape de création" comme mentionné, c'est-à-dire écrire une tâche MSBuild qui fait quelque chose de similaire. Encore une autre façon peut être de post-traiter la DLL d'une manière ou d'une autre (par exemple ildasm + ilasm), mais je pense que les options mentionnées ci-dessus sont probablement les plus simples.

Marcus
la source
@Wint non, n'ajoutez pas le AssemblyInfo.cs généré à git. Si vous le faites, il sera impossible de faire une construction non sale: P
blague du
3

Pour une méthode de paiement entièrement automatisée et flexible https://github.com/Fody/Stamp . Nous l'avons utilisé avec succès pour nos projets Git (ainsi que cette version pour les projets SVN)

Mise à jour: Ceci est obsolète car Stamp.Fody n'est plus maintenu

mamuesstack
la source
1
sur la page github de Stamp.Fody, il est dit: "Ce projet n'est plus maintenu.". L'inclure dans mon projet a soulevé un CA0052 et un CA0055
sc911
2

Vous pouvez utiliser un PowerShell one-liner pour mettre à jour tous les fichiers assemblyinfo avec le hachage de validation.

$hash = git describe --long --always;gci **/AssemblyInfo.* -recurse | foreach { $content = (gc $_) -replace "\[assembly: Guid?.*", "$&`n[assembly: AssemblyMetadata(`"commithash`", `"$hash`")]" | sc $_ }
roh85
la source
1
  1. J'espère que vous savez comment appeler des programmes externes et intercepter la sortie au moment de la construction.
  2. J'espère que vous savez comment avoir dans le répertoire de travail de git ignorer les fichiers non versionnés.

Comme indiqué par @ Learath2, la sortie de git rev-parse HEADvous donnera un hachage brut.

Si vous utilisez des balises dans Git-repository (et que vous utilisez des balises, n'est-ce pas plus descriptif et lisible que git rev-parse), la sortie peut être reçue de git describe(tout en étant également utilisée avec succès plus tard dans git checkout)

Vous pouvez appeler rev-parse | describe dans:

  • certains font la scène
  • dans le hook post-commit
  • dans le filtre de maculage, si vous sélectionnez le mode de mise en œuvre des filtres de maculage / nettoyage
Blaireau paresseux
la source
0

J'utilise une combinaison de la réponse acceptée et d'une petite addition. J'ai installé l'extension AutoT4 ( https://marketplace.visualstudio.com/items?itemName=BennorMcCarthy.AutoT4 ) pour réexécuter les modèles avant la construction.

obtenir la version de GIT

J'ai git -C $(ProjectDir) describe --long --always > "$(ProjectDir)git_version.txt"dans mon événement de pré-construction dans les propriétés du projet. Ajouter git_version.txt et VersionInfo.cs à .gitignore est une très bonne idée.

intégration de la version dans les métadonnées

J'ai ajouté un VersionInfo.ttmodèle à mon projet:

<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.IO" #>
<#@ output extension=".cs" #>

using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

<#
if (File.Exists(Host.ResolvePath("git_version.txt")))
{
    Write("[assembly: AssemblyInformationalVersion(\""+ File.ReadAllText(Host.ResolvePath("git_version.txt")).Trim() + "\")]");
}else{
    Write("// version file not found in " + Host.ResolvePath("git_version.txt"));
}

#>

Maintenant, j'ai ma balise git + hash dans "ProductVersion".

jelinek.01
la source
0

En référence à l'autre réponse ( https://stackoverflow.com/a/44278482/4537127 ), j'ai également utilisé le VersionInfo.ttmodèle de texte pour générerAssemblyInformationalVersion sans AutoT4.

(Atleast fonctionne dans mon application C # WPF)

Le problème était que les événements de pré-construction étaient exécutés après les transformations du modèle, donc après le clonage, le git_version.txtfichier n'était pas là et la construction échouait. Après l'avoir créé manuellement pour permettre à la transformation de passer une fois, il a été mis à jour après la transformation et il y avait toujours un commit derrière .

J'ai dû faire deux ajustements au fichier .csproj (cela s'applique au moins pour Visual Studio Community 2017)

1) Importez les cibles de transformation de texte et effectuez des transformations de modèle à exécuter sur chaque build: (Réf https://msdn.microsoft.com/en-us/library/ee847423.aspx )

<PropertyGroup>
    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">15.0</VisualStudioVersion>
    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
    <TransformOnBuild>true</TransformOnBuild>
    <TransformOutOfDateOnly>false</TransformOutOfDateOnly>
</PropertyGroup>

et après <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

<Import Project="$(VSToolsPath)\TextTemplating\Microsoft.TextTemplating.targets" />

2) Faites la git describecourse avant les transformations du modèle (pour qu'il git_version.txty ait quand VersionInfo.ttest transformé):

<Target Name="PreBuild" BeforeTargets="ExecuteTransformations">
  <Exec Command="git -C $(ProjectDir) describe --long --always --dirty &gt; $(ProjectDir)git_version.txt" />
</Target>

..Et le code C # pour obtenir le AssemblyInformationalVersion(Ref https://stackoverflow.com/a/7770189/4537127 )

public string AppGitHash
{
    get
    {
        AssemblyInformationalVersionAttribute attribute = (AssemblyInformationalVersionAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false).FirstOrDefault();

        return attribute.InformationalVersion;
    }
}

..Et ajoutez les fichiers générés à .gitignore

VersionInfo.cs
git_version.txt
kimmoli
la source
0

Une autre façon serait de générer un fichier Version.cs à partir d'une étape de pré-construction. J'ai exploré cela dans un petit projet de preuve de concept qui imprime son hachage de commit actuel.

Le projet est téléchargé sur https://github.com/sashoalm/GitCommitHashPrinter .

Le code de lot qui crée le fichier Version.cs est le suivant:

@echo off

echo "Writing Version.cs file..."

@rem Pushd/popd are used to temporarily cd to where the BAT file is.
pushd $(ProjectDir)

@rem Verify that the command succeeds (i.e. Git is installed and we are in the repo).
git rev-parse HEAD || exit 1

@rem Syntax for storing a command's output into a variable (see https://stackoverflow.com/a/2340018/492336).
@rem 'git rev-parse HEAD' returns the commit hash.
for /f %%i in ('git rev-parse HEAD') do set commitHash=%%i

@rem Syntax for printing multiline text to a file (see https://stackoverflow.com/a/23530712/492336).
(
echo namespace GitCommitHashPrinter
echo {
echo     class Version
echo     {
echo         public static string CommitHash { get; set; } = "%commitHash%";
echo     }
echo }
)>"Version.cs"

popd    
sashoalm
la source
0

Endroit

<Target Name="UpdateVersion" BeforeTargets="CoreCompile">
  <Exec Command="php &quot;$(SolutionDir)build.php&quot; $(SolutionDir) &quot;$(ProjectDir)Server.csproj&quot;" />
</Target>

dans YOUR_PROJECT_NAME.csproj

<?php

function between(string $string, string $after, string $before, int $offset = 0) : string{
    return substr($string, $pos = strpos($string, $after, $offset) + strlen($after),
        strpos($string, $before, $pos) - $pos);
}

$pipes = [];
$proc = proc_open("git rev-parse --short HEAD", [
    0 => ["pipe", "r"],
    1 => ["pipe", "w"],
    2 => ["pipe", "w"]
], $pipes, $argv[1]);

if(is_resource($proc)){
    $rev = stream_get_contents($pipes[1]);
    proc_close($proc);
}

$manifest = file_get_contents($argv[2]);
$version = between($manifest, "<Version>", "</Version>");
$ver = explode("-", $version)[0] . "-" . trim($rev);
file_put_contents($argv[2], str_replace($version, $ver, $manifest));

echo "New version generated: $ver" . PHP_EOL;
PeratX
la source