Вставити git commit хеш у .Net dll


102

Я будую додаток C #, використовуючи Git в якості контролю версій.

Чи є спосіб автоматично вставити останній хеш комісій у виконуваний файл під час створення програми?

Наприклад, друк хеш-файлів на консоль виглядатиме приблизно так:

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

Зауважте, що це потрібно робити під час збирання , а не під час виконання , оскільки мій розгорнутий виконуваний файл не матиме доступ до репортажу git.

Пов’язане запитання щодо C ++ можна знайти тут .

EDIT

За запитом @ Mattanja, я публікую сценарій гак-гака, який використовую у своїх проектах. Установка:

  • Гачки - це сценарії оболонки Linux, які розміщуються під: path_to_project \ .git \ hooks
  • Якщо ви використовуєте msysgit , папка гаків уже містить деякі приклади сценаріїв. Щоб змусити git викликати їх, видаліть розширення '.sample' із імені сценарію.
  • Назви скриптів гачка відповідають події, яка викликає їх. У моєму випадку я змінив функцію після завершення і після злиття .
  • Мій файл AssemblyInfo.cs знаходиться безпосередньо під проектом (той самий рівень, що і папка .git ). Він містить 23 рядки, і я використовую git для створення 24-го.

Оскільки мій Linux-обстріл трохи іржавий, сценарій просто зчитує перші 23 рядки AssemblyInfo.cs до тимчасового файлу, повторює git-хеш до останнього рядка та перейменовує файл назад у AssemblyInfo.cs . Я впевнений, що є кращі способи зробити це:

#!/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

Сподіваюся, це допомагає.

Відповіді:


63

Ми використовуємо теги в git для відстеження версій.

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

Ви можете отримати версію з хешем від git за допомогою:

git describe --long

Наш процес збирання додає git-хеш в атрибут AssemblyInformationalVersion файла AssemblyInfo.cs:

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

Після компіляції ви можете переглянути версію з Windows Explorer:

введіть тут опис зображення

Ви також можете отримати це програмно за допомогою:

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

де YOURTYPE - це будь-який тип у Асамблеї, який має атрибут AssemblyInformationalVersion.


14
Привіт, я хотів запитати місяць тому, але мені не вистачало респондентів для коментарів. Коли ви говорите: "Наш процес збирання додає git-хеш в атрибут AssemblyInformationalVersion AssemblyInfo.cs", що саме там відбувається? Ви просто займаєтеся побудовою візуальної студії, або ви використовуєте щось на зразок NAnt чи якийсь інший інструмент?
Іван Ісус

3
Ми використовуємо рубін (граблі) для автоматизації побудови. Один із наших завдань щодо збирання граблів оновлює файл CommonAssemblyInfo.cs, який використовується у всіх проектах рішення. Завдання генерує файл CommonAssemblyInfo.cs, використовуючи albacore - github.com/derickbailey/Albacore Одним із значень AssemblyInfo, який задає завдання, є AssemblyInformationalVersion.
Рукодільник

3
@John Jesus - як запропонував Ледачий борсук, ви також можете використовувати гачки для змінення AssemblyInfo.cs після фіксації / злиття тощо (саме це я і зробив). Дивіться на kernel.org/pub/software/scm/git/docs/githooks.html
bavaza

Тільки FYI, Albacore перейшов до нової організації центру: github.com/Albacore/albacore
kornman00

5
Після проекту https://github.com/jeromerg/NGitVersion пропонує повне рішення для генерування GlobalAssemblyInfo.*файлів під час компіляції для проектів C # та C ++: Створена версія збірки за замовчуванням містить: хеш фіксації, прапор, що сигналізує про локальні зміни та приріст підрахунку суми комітів від кореня сховища до поточного комітету.
jeromerg

77

Ви можете вставити файл version.txt у виконуваний файл, а потім прочитати version.txt із виконуваного файлу. Щоб створити файл version.txt , використовуйтеgit describe --long

Ось такі кроки:

Використовуйте подію Build для виклику git

  • Клацніть правою кнопкою миші проект і виберіть Властивості

  • У події збирання додайте подію попереднього збирання, що містить (зверніть увагу на лапки):

    "C: \ Програмні файли \ Git \ bin \ git.exe" описують - long> "$ (ProjectDir) \ version.txt"

    Це створить файл version.txt у вашому каталозі проекту.

Вставте version.txt у виконуваний файл

  • Клацніть правою кнопкою миші на проект та виберіть Додати існуючий елемент
  • Додайте файл version.txt (змініть фільтр вибору файлу, щоб він бачив усі файли)
  • Після додавання версії.txt клацніть правою кнопкою миші на ній у Провіднику рішень та виберіть Властивості
  • Змініть дію збірки на вбудований ресурс
  • Змініть Копія у вихідний каталог на Копіювати завжди
  • Додайте version.txt у свій .gitignore файл

Прочитайте вбудований рядок текстового файлу

Ось приклад коду для читання вбудованого рядка текстового файлу:

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();
        }
    }
}

9
Цей підхід працює досить добре. Однак я використав "git rev-parse - short HEAD".
Брайан Рейтер

3
Ах, добре. Я використав "git description", тому що це дуже цікаво (мені), коли у вас є тег; інформація про версію має тег плюс кількість комітів після застосування тегу; ніколи раніше не бачив подібного в СКМ.
Іван Ісус

7
Я використовую git describe --dirty, що додає прапор, коли розробники працюють з брудним робочим деревом.
paulmelnikow

2
@ TamásSzelei простір імен проектів - TryGitDescribe. Після того, як файл version.txt вбудовується у артефакт, що виконується / збирається, вам потрібно додати простір імен, щоб вийти з нього.
Іван Ісус

2
Дякую за повне рішення. У моєму випадку я GetEntryAssemblyзбирався збирати. У будь-якому випадку ви можете зателефонувати, GetName().Nameщоб уникнути жорсткого кодування імені.
astrowalker

51

ОНОВЛЕННЯ:

Речі склалися з моменту, коли я спочатку відповів на це питання. Microsoft.NET.Sdk(Тобто ви повинні використовувати проект СОК-стиль) тепер включає підтримку для додавання фіксації хеша як на складальний інформаційну версію, а також метадані NuGet пакета, якщо дотримані деякі умови:

  1. <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 спричиняють це до запуску до створення інформаційної версії збірки.

  1. Щоб включити хеш до метаданих пакунків на нуті, <RepositoryUrl>необхідно також визначити.

  2. <SourceControlInformationFeatureSupported>властивості повинно бути true, це призводить до того, що завдання пакету «nuget» також підбирає SourceRevisionId.

Я б ухиляв людей від використання пакету MSBuildGitHash, оскільки ця нова методика є більш чистою та найбільш послідовною.

ОРИГІНАЛ:

Я створив простий пакунок, який ви зможете включити у свій проект, який буде за вас подбати про це: https://www.nuget.org/packages/MSBuildGitHash/

Цей пакунок від «nuget» реалізує «чисте» рішення MSBuild. Якщо ви бажаєте не залежати від пакета нута, ви можете просто скопіювати ці цілі у свій файл 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 &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>

Тут є дві цілі. Перший, "GetGitHash", завантажує git-хеш у властивість MSBuild під назвою BuildHash, це робиться лише тоді, коли BuildHash ще не визначений. Це дозволяє вам передати його MSBuild у командному рядку, якщо ви хочете. Ви можете передати його MSBuild так:

MSBuild.exe myproj.csproj /p:BuildHash=MYHASHVAL

Друга ціль, "WriteGitHash", запише хеш-значення у файл у тимчасовій папці "obj" під назвою "CustomAssemblyInfo.cs". Цей файл буде містити рядок, який виглядає так:

[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.


2
Це спрацювало чудово. Я встановив пакунок nuget і зміг витягнути git-хеш за допомогою Assembly.GetExecutingAssembly(), потім вивчивши збірку CustomAttributes .
Гевін Н

1
Якби це було моє запитання, я би прийняв цю відповідь. Чудові речі.
Дрю Ноакс

1
@GavinH, як ти дістався GitHash? Я можу бачити, що це значення існує, але чи є чистий метод отримати спеціальний атрибут за назвою? Здається, що я повинен довго писати запит CustomAttributes, де вибрати , спасибі.
Окан Кочігіт

1
@ocanal так - на жаль, я не зміг знайти більш чистий спосіб зробити це, ніж читати CustomAttributes. Наприклад, ось функція, яку я використовую для вилучення хеш-рядка: pastebin.com/nVKGLhJC
Gavin H

2
@danmiser Я поняття не маю, що таке "UseMerge / SingleAssemblyName", тому я не можу вам допомогти. Створіть проблему на github.com/MarkPflug/MSBuildGitHash, і я можу поглянути на це (це не обіцянка).
MarkPflug

14

Ще один спосіб зробити це - використовувати NetRevisionTool з деякими магіями бортової Visual Studio. Я продемонструю це для Visual Studio 2013 Professional Edition, але це буде працювати і з іншими версіями.

Тому спочатку завантажте NetRevisionTool. Ви включаєте NetRevisionTool.exe у свій PATH або реєструєте його у своєму сховищі та створюєте візуальну студію попереднього збирання та дії після збирання та змініть свій AssemblyInfo.cs.

Прикладом, який би додав ваш git-хеш до AssemblyVinformationVersion, буде такий: У налаштуваннях вашого проекту:

введіть тут опис зображення

у AssemblyInfo.cs свого проекту ви змінюєте / додаєте рядок:

[збори: AssemblyInformationalVersion ("1.1. {dmin: 2015}. {{chash: 6} {!} - {гілка}")]

на показаному скріншоті я перевірив у NetRevisionTool.exe у папці External / bin

Після складання, якщо ви клацніть правою кнопкою миші бінарний файл і перейдіть до властивостей, ви повинні побачити щось на зразок наступного:

введіть тут опис зображення

Сподіваюся, це допомагає комусь там


Хеш-код для мене завжди закінчується як 00000. Я думав, що це тому, що я змінив зміни, але все одно. Будь-яка ідея чому?
Віктор

3
Проблема полягала в тому, що NetRevision не знаходив мій git у виконанні. Причина полягає в тому, що ми використовуємо SourceTree і git вбудований в нього. Рішенням було скопіювати git.exe та libiconv-2.dll з% USERPROFILE% \ AppData \ Local \ Atlassian \ SourceTree \ git_local \ bin у папку, що містить NetRevision.exe. Я також повинен був змінити такі події, як так: Попередня збірка: cd $ (ProjectDir) Бібліотеки NetRevisionTool.exe / patch $ (ProjectDir) Подія після складання: cd $ (ProjectDir) Бібліотеки NetRevisionTool.exe / відновлення $ (ProjectDir)
Віктор

Щойно для подальшої довідки URL-адреса репортажу проекту певний час була змінена на github.com/ygoe/NetRevisionTool . Більш детальна інформація також доступна на unclassified.software/apps/netrevisiontool .
ygoe

14

Я думаю, що на це питання варто дати повну поетапну відповідь. Тут є стратегія запуску скрипта повноважень з подій перед складанням, який бере файл шаблону та генерує файл AssemblyInfo.cs з включеною інформацією про git тег + інформацію про кількість комісій.

Крок 1. Створіть файл AssemblyInfo_template.cs у папці Project \ Properties, виходячи з оригінального AssemblyInfo.cs, але містить:

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

Крок 2: Створіть скрипт powerhell на ім'я InjectGitVersion.ps1, джерелом якого є:

# 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;       
}

Крок 3: Збережіть файл InjectGitVersion.ps1 у каталозі свого рішення у папці BuildScripts

Крок 4: Додайте наступний рядок до подій попереднього збирання проекту

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

Крок 5: Створіть свій проект.

Крок 6. За бажанням додайте AssemblyInfo.cs у файл ігнорування git


І не забудьте зробити свої теги git сумісними з версіями файлів: наприклад, 1.2.3. Якщо у вас є складніші теги, вам доведеться розібрати лише сумісні частини
Атіліо Джобсон

2
Замість використання шаблону та gitignoring реальний AssemblyInfo.csможна змінити AssemblyInfo.csна місці, скласти, а потім git скинути AssemblyInfo.csдо останньої зафіксованої версії. Тож у репо завжди було б AssemblyInfo.cs, із $..$заміною лише на час побудови.
Kuba Wyrostek

Це спрацювало чудово. Я в кінцевому підсумку використовував git describe --match "v[0-9]*" --long --always --dirtyдля фільтрування певних тегів (тих, що містять номер версії) та щоб вказати, чи робоче дерево чисте.
packoman

Ви також повинні змінити свій RegEx в сценарії PS:$gitVersion -match '[v](.*)-(\d+)-[g](.+)$';
packoman

4

Це дуже просто за допомогою .NET Revision Task для MSBuild та роботи з Visual Studio 2019.

Просто встановіть пакет NuGet Unclassified.NetRevisionTask , а потім налаштуйте потрібну інформацію у AssemblyInfo.csфайлі, як описано в документації на GitHub .

Якщо ви хочете лише хеш останнього коміту (довжина = 8):

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

Створіть свій проект / рішення, і у вас вийде щось подібне:

введіть тут опис зображення


Щоб налаштувати формат в додатку NET.core додати PropertyGroupдо .csproj файл , як видно в README github.com/ygoe/NetRevisionTask/blob/master/README.md
sc911

3

Оскільки в іншій відповіді вже згадується біт git, як тільки ви отримаєте SHA, ви можете розглянути можливість створення AssemblyInfo.csфайлу свого проекту в гачку перед складанням.

Один із способів зробити це - створити AssemblyInfo.cs.tmplфайл шаблону із заповненням для вашої SHA, наприклад, $$ GITSHA $$, наприклад

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

Після цього ваш гачок попереднього збирання повинен замінити цей заповнювач і вивести файл AssemblyInfo.cs для компілятора C #.

Щоб побачити, як це можна зробити за допомогою SubWCRev для SVN, дивіться цю відповідь . Зробити щось подібне для git не повинно бути важко.

Іншими способами було б "зробити етап", як згадувалося, тобто написати MSBuild завдання, яке робить щось подібне. Ще один спосіб може бути як-небудь опублікувати обробку DLL (ildasm + ilasm кажу), але я думаю, що варіанти, згадані вище, мабуть, найпростіші.


@Wint ні, не додайте створений AssemblyInfo.cs до git. Якщо ви це зробите, неможливо зробити не брудне будівництво: P
пожартував

3

Для повністю автоматизованої та гнучкої методики замовлення https://github.com/Fody/Stamp . Ми успішно використали це для наших Git-проектів (як і цю версію для SVN-проектів)

Оновлення: це застаріло, оскільки Stamp.Fody більше не підтримується


1
На сторінці github Stamp.Fody написано: "Цей проект більше не підтримується." Включивши його у мій проект, було піднято CA0052 та CA0055
sc911

2

Для оновлення всіх файлів асемблерних файлів за допомогою хеша фіксації можна скористатись однорозмірним пакетом повноважень.

$hash = git describe --long --always;gci **/AssemblyInfo.* -recurse | foreach { $content = (gc $_) -replace "\[assembly: Guid?.*", "$&`n[assembly: AssemblyMetadata(`"commithash`", `"$hash`")]" | sc $_ }

1
  1. Я сподіваюся, що ви знаєте, як викликати зовнішні програми та перехоплювати вихід у час нарощування.
  2. Я сподіваюся, що ви знаєте, як у робочому каталозі git ігнорувати неперевершені файли.

Як зазначає @ learath2, вихідний файл git rev-parse HEADдасть вам звичайний хеш.

Якщо ви використовуєте теги в Git-сховищі (і ви використовуєте теги, чи не він є більш описовим і читабельним, ніж git rev-parse), вихід може бути отриманий від git describe(при цьому він також успішно використовується пізніше в git checkout)

Ви можете зателефонувати за rev-parse | описувати у:

  • деякі роблять сцену
  • у гачку після фіксації
  • у фільтрі розмазання, якщо ви вибрали спосіб імплементації / очищення фільтрів

0

Я використовую комбінацію прийнятої відповіді та невеликого дозволу. У мене встановлено розширення AutoT4 ( https://marketplace.visualstudio.com/items?itemName=BennorMcCarthy.AutoT4 ) для повторного запуску шаблонів перед збіркою.

отримання версії від GIT

Я маю git -C $(ProjectDir) describe --long --always > "$(ProjectDir)git_version.txt"в моїй події перед складанням властивості проекту. Додавання git_version.txt та VersionInfo.cs до .gitignore є досить хорошою ідеєю.

вбудована версія в метадані

Я додав VersionInfo.ttшаблон до свого проекту:

<#@ 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"));
}

#>

Тепер у мене є свій git tag + хеш у "ProductVersion".


0

Посилаючись на іншу відповідь ( https://stackoverflow.com/a/44278482/4537127 ), я також використовував VersionInfo.ttтекстовий шаблон для створення AssemblyInformationalVersionбез AutoT4.

(Atleast працює в моєму додатку C # WPF)

Проблема полягала в тому, що події попередньої збірки були запущені після перетворень шаблону, тому після клонування git_version.txtфайл не був там, і збірка не вдається. Після створення вручну, щоб перетворення дозволило пройти один раз, воно було оновлене після трансформації і завжди було одним комітом позаду .

Мені довелося внести два корективи у файл .csproj (це стосується принаймні для Visual Studio Community 2017)

1) Імпортуйте цілі трансформації тексту та зробіть перетворення шаблонів для виконання кожної збірки: (Посилання 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>

і після <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

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

2) Зробіть git describeзапуск перед перетвореннями шаблону (так, що git_version.txtє, коли VersionInfo.ttперетворюється):

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

..І код C #, щоб отримати AssemblyInformationalVersion(Посилання https://stackoverflow.com/a/7770189/4537127 )

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

        return attribute.InformationalVersion;
    }
}

..І додайте створені файли до .gitignore

VersionInfo.cs
git_version.txt

0

Іншим способом було б генерувати файл Version.cs із кроку попереднього збирання. Я дослідив це в невеликому доказовому проекті, який виводить його поточний хеш-код.

Проект завантажено на https://github.com/sashoalm/GitCommitHashPrinter .

Пакетний код, який створює файл Version.cs, такий:

@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    

0

Місце

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

в 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;
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.