NET dllにgit commit hashを埋め込む


102

バージョンコントロールとしてGitを使用して、C#アプリケーションを構築しています。

アプリケーションをビルドするときに、最後のコミットハッシュを実行可能ファイルに自動的に埋め込む方法はありますか?

たとえば、コンソールにコミットハッシュを出力すると、次のようになります。

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 ++に関連する質問はここにあります

編集

@mattanjaのリクエストに従って、私は自分のプロジェクトで使用するgitフックスクリプトを投稿しています。セットアップ:

  • フックはLinuxシェルスクリプトで、次の場所に配置されています:path_to_project \ .git \ hooks
  • msysgitを使用している場合、hooksフォルダーにはすでにいくつかのサンプルスクリプトが含まれています。gitでそれらを呼び出すようにするには、スクリプト名から「.sample」拡張子を削除します。
  • フックスクリプトの名前は、それらを呼び出すイベントと一致します。私の場合、ポストコミットポストマージを変更しました
  • 私のAssemblyInfo.csファイルは、プロジェクトパスの直下にあります(.gitフォルダーと同じレベル)。23行ありますが、24行目はgitを使って生成しています。

私のlinux-shellは少し錆びているので、スクリプトは単にAssemblyInfo.csの最初の23行を一時ファイルに読み取り、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ハッシュをAssemblyInfo.csファイルのAssemblyInformationalVersion属性に配置します。

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

コンパイルしたら、Windowsエクスプローラーからバージョンを表示できます。

ここに画像の説明を入力してください

プログラムで取得することもできます。

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

YOURTYPEは、AssemblyInformationalVersion属性を持つアセンブリ内の任意のタイプです。


14
こんにちは。1か月前に聞きたかったのですが、コメントするのに十分な担当者がいませんでした。「私たちのビルドプロセスは、GitハッシュをAssemblyInfo.csのAssemblyInformationalVersion属性に配置する」と言うと、そこで何が起こっているのでしょうか。ビジュアルスタジオビルドを行っているだけですか、それともNAntなどのツールを使用していますか?
ジョンジーザス

3
ビルドを自動化するためにruby(rake)を使用します。レイクビルドタスクの1つは、ソリューションのすべてのプロジェクトで使用されるCommonAssemblyInfo.csファイルを更新します。タスクはalbacoreを使用してCommonAssemblyInfo.csファイルを生成します-github.com/derickbailey/Albacore タスクが設定するAssemblyInfo値の1つはAssemblyInformationalVersionです。
職人2013年

3
@ジョンジーザス-レイジーバジャーが示唆したように、gitフックを使用して、commit / mergeなどの後にAssemblyInfo.csを変更することもできます(これが私がやったことです)。kernel.org/pub/software/scm/git/docs/githooks.htmlを
bavaza 2013


5
次のプロジェクトhttps://github.com/jeromerg/NGitVersionは、GlobalAssemblyInfo.*C#およびC ++プロジェクトのコンパイル時にファイルを生成するための完全なソリューションを提供します。デフォルトでは、生成されたアセンブリバージョンには、コミットハッシュ、ローカル変更を通知するフラグ、およびリポジトリルートから現在のコミットへのコミット量をカウントする増分。
jeromerg 2015

77

実行可能ファイルにversion.txtファイルを埋め込み、実行可能ファイルからversion.txtを読み取ることができます。version.txtファイルを作成するには、git describe --long

手順は次のとおりです。

ビルドイベントを使用してgitを呼び出す

  • プロジェクトを右クリックし、[プロパティ]を選択します

  • ビルドイベントで、以下を含むプレビルドイベントを追加します(引用符に注意してください)。

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

    これにより、プロジェクトディレクトリにversion.txtファイルが作成されます。

実行可能ファイルにversion.txtを埋め込む

  • プロジェクトを右クリックし、[既存の項目を追加]を選択します
  • version.txtファイルを追加します(ファイル選択フィルターを変更して、すべてのファイルを表示できるようにします)
  • のversion.txtが追加され、ソリューションエクスプローラで、それを右クリックして[プロパティ]を選択します
  • ビルドアクションを埋め込みリソースに変更する
  • コピーを出力ディレクトリに変更して常にコピーする
  • .gitignoreファイルにversion.txtを追加します

埋め込まれたテキストファイルのバージョン文字列を読み取る

次に、埋め込みテキストファイルのバージョン文字列を読み取るサンプルコードをいくつか示します。

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」を使用しました。
ブライアンライター2014年

3
あぁ、いいね。「git describe」を使用したのは、タグがあると(私にとって)とても興味深いからです。バージョン情報には、タグと、タグが適用された後のコミット数が含まれます。これまでにSCMのようなものを見たことがない。
ジョンジーザス

7
私はを使用しますgit describe --dirty。これは、開発者がダーティな作業ツリーで作業しているときにフラグを追加します。
paulmelnikow 14年

2
@TamásSzeleiプロジェクトの名前空間はTryGitDescribeです。version.txtファイルが実行可能ファイル/アセンブリアーティファクトに埋め込まれた後、名前空間を付加して取得する必要があります。
ジョンジーザス

2
完全な解決に感謝します。私の場合、以前はGetEntryAssemblyアセンブリを取得していました。いずれの場合でもGetName().Name、名前をハードコーディングしないように呼び出すことができます。
astrowalker

51

更新:

私が最初にこの質問に答えて以来、物事は進化してきました。Microsoft.NET.Sdkいくつかの条件が満たされた場合には(あなたは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. ハッシュをnugetパッケージメタデータに含めるには、<RepositoryUrl>も定義する必要があります。

  2. <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 &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>

ここには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ファイルとともにソース管理されます。


2
これは完全に機能しました。私はnugetパッケージをインストールし、を使用してgitハッシュを引き出してAssembly.GetExecutingAssembly()、アセンブリを調べることができましたCustomAttributes
Gavin H

1
これが私の質問だったら、私はこの答えを受け入れたでしょう。素晴らしいもの。
Drew Noakes

1
@GavinH、どうやって手に入れたのGitHash?値が存在することがわかりますが、カスタム属性を名前で取得する純粋な方法はありますか?CustomAttributesおかげで私は長いwhere-selectクエリを書かなければならないようです。
Okan Kocyigit

1
@ocanalはい-残念ながら、私はを読むよりもそれを行うためのより明確な方法を見つけることができませんでしたCustomAttributes。たとえば、ハッシュ文字列を抽出するために使用する関数は次のとおりです。pastebin.com
Gavin H

2
@danmiser「UseMerge / SingleAssemblyName」が何かわからないので、私はあなたを助けることはできません。github.com/MarkPflug/MSBuildGitHashで問題を作成し、私はそれを見るかもしれません(それは約束ではありません)。
MarkPflug 2018

14

これを行うもう1つの方法は、NetRevisionToolをいくつかのオンボードVisual Studioマジックで使用することです。ここではVisual Studio 2013 Professional Editionについて紹介しますが、これは他のバージョンでも機能します。

したがって、最初にNetRevisionToolをダウンロードします。NetRevisionTool.exeをPATHに含めるか、リポジトリにチェックインして、ビジュアルスタジオのビルド前およびビルド後のアクションを作成し、AssemblyInfo.csを変更します。

git-hashをAssemblyInformationVersionに追加する例は次のようになります。プロジェクト設定で:

ここに画像の説明を入力してください

プロジェクトのAssemblyInfo.csで、次の行を変更または追加します。

[アセンブリ:AssemblyInformationalVersion( "1.1。{dmin:2015}。{chash:6} {!}-{branch}")]

表示されているスクリーンショットで、External / binフォルダーのNetRevisionTool.exeでチェックインしました

ビルド後、バイナリを右クリックしてプロパティに移動すると、次のようなものが表示されます。

ここに画像の説明を入力してください

これが誰かを助けることを願っています


私のコミットハッシュは常に00000になります。コミットされていない変更があったが、それでも変わらないからだと思いました。なぜか?
Viktor

3
問題は、NetRevisionが私のgit実行可能ファイルを見つけられなかったことでした。その理由は、SourceTreeを使用していて、gitに組み込まれているためです。解決策は、git.exeおよびlibiconv-2.dllを%USERPROFILE%\ AppData \ Local \ Atlassian \ SourceTree \ git_local \ binからNetRevision.exeを含むフォルダーにコピーすることでした。また、次のようにイベントを変更する必要がありました:ビルド前のイベント:cd $(ProjectDir)Libraries NetRevisionTool.exe / patch $(ProjectDir)ビルド後のイベント:cd $(ProjectDir)Libraries NetRevisionTool.exe / restore $(ProjectDir)
Viktor

将来の参考のために、プロジェクトリポジトリのURLは少し前にgithub.com/ygoe/NetRevisionToolに変更されましたunclassified.software/apps/netrevisiontoolにも詳細情報があります。
ygoe

14

この質問は、完全な段階的な回答を提供する価値があると思います。ここでの戦略は、テンプレートファイルを取り込み、gitタグ+コミットカウント情報を含むAssemblyInfo.csファイルを生成するビルド前イベントからPowerShellスクリプトを実行することです。

手順1:元のAssemblyInfo.csに基づいて、Project \ PropertiesフォルダーにAssemblyInfo_template.csファイルを作成します。

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

ステップ2:ソースが以下であるInjectGitVersion.ps1という名前のPowerShellスクリプトを作成します。

# 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:プロジェクトのPre-Buildイベントに次の行を追加します

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

ステップ5:プロジェクトをビルドします。

ステップ6:オプションで、AssetInfo.csをgit ignoreファイルに追加します


そして、gitタグを1.2.3などのファイルバージョンと互換性があるようにすることを忘れないでください。より複雑なタグがある場合は、互換性のある部分のみを解析する必要があります
Atilio Jobson '22

2
テンプレートを使用して実際のテンプレートをgitignoringする代わりに、AssemblyInfo.cs変更AssemblyInfo.csを加えてビルドし、git AssemblyInfo.csを最後にコミットしたバージョンにリセットできます。そのため、レポには常にがありAssemblyInfo.cs$..$ビルド時のみが置換されます。
Kuba Wyrostek 2017年

これはうまくいきました。私が使用して終了git describe --match "v[0-9]*" --long --always --dirty(バージョン番号を含むもの)、特定のタグのためにフィルターにし、作業ツリーがきれいだった場合は、指示します。
packoman

あなたはPSスクリプトであなたの正規表現を変更することもあります:$gitVersion -match '[v](.*)-(\d+)-[g](.+)$';
packoman

4

MSBuildの.NETリビジョンタスクと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、事前ビルドフックでプロジェクトのファイルを生成することを検討できます。

これを行う1つの方法はAssemblyInfo.cs.tmpl、たとえば$$ GITSHA $$にSHAのプレースホルダーを含むテンプレートファイルを作成することです。

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

ビルド前のフックは、このプレースホルダーを置き換えて、C#コンパイラが取得するAssemblyInfo.csファイルを出力する必要があります。

SVNのSubWCRevを使用してこれを行う方法を確認するには、この回答を参照してください。gitに対して同様のことを行うのは難しくありません。

他の方法は、前述のように「makeステージ」です。つまり、同様のことを行うMSBuildタスクを記述します。さらに別の方法としては、DLLを何らかの方法で後処理することもできます(ildasm + ilasmが言う)が、上記のオプションがおそらく最も簡単だと思います。


@Wintいいえ、生成されたAssemblyInfo.csをgitに追加しないでください。これを行うと、ダーティーでないビルドを行うことができなくなります:P
jokedst

3

完全に自動化された柔軟なメソッドチェックアウトについては、https://github.com/Fody/Stampをご覧ください。私たちはこれをGitプロジェクト(およびSVNプロジェクトのこのバージョン)に正常に使用しました

更新:Stamp.Fodyがメンテナンスされなくなったため、これは古くなっています


1
Stamp.Fodyのgithubページには、「このプロジェクトはもうメンテナンスされていません」と書かれています。それを私のプロジェクトに含めるとCA0052およびCA0055が発生しました
sc911

2

powershellワンライナーを使用して、すべてのassemblyinfoファイルをコミットハッシュで更新できます。

$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-repositoryでタグを使用している場合(そして、タグを使用している場合、は説明よりも読みやすくなりますgit rev-parse)、出力を受け取ることがありますgit describe(後ででも正常に使用されますgit checkout

次の場所でrev-parse | describeを呼び出すことができます。


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

#>

これで、「ProductVersion」にgitタグとハッシュが追加されました。


0

別の回答(https://stackoverflow.com/a/44278482/4537127)を参照して、AutoT4なしでVersionInfo.tt生成するためにテキストテンプレートも利用しAssemblyInformationalVersionました。

(少なくとも私のC#WPFアプリケーションで動作します)

問題は、テンプレートの変換後にPre-buildイベントが実行されるため、クローン作成後、git_version.txtファイルがそこになく、ビルドが失敗することでした。トランスフォーメーションが1回通過できるように手動で作成した後、トランスフォーメーション後に更新され、常に1つのコミットが遅れていました

.csprojファイルに2つの調整を加える必要がありました(これは少なくとも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ファイルを生成することです。私は、現在のコミットハッシュを出力する小さな概念実証プロジェクトでこれを調査しました。

Thaプロジェクトは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;
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.