17
13

More than 1 year has passed since last update.

[.NET/C#] アプリにgitのコミットIDを埋め込む

Last updated at Posted at 2022-10-26

アプリのバージョン情報にgitのコミットIDが埋め込まれていることがよくあると思います。

ffmpegの場合
> ffmpeg
ffmpeg version 2021-10-21-git-2aa343bb6f-full_build-www.gyan.dev Copyright (c) 2000-2021 the FFmpeg developers

これをC#で簡単に実現したいと思います。
今回はコミットIDとブランチ名を埋め込みます。

VisualStudio利用時

説明文にすると長いですが、簡単です。

1.ビルド前イベントの登録

プロジェクトのプロパティ「ビルド前イベント」を利用してgitの情報をファイルに書き出します。
image.png

git rev-parse --short HEAD > $(ProjectDir)git_id.txt
git branch --show-current > $(ProjectDir)git_branch.txt

1行目は短いコミットID、2行目はブランチ名です。
ブランチ名が不要なら2行目は不要です。
ファイル名や出力ディレクトリは好きに変えてOKです。

2.埋め込みリソース化

gitのコミットがある状態で一度ビルドすると2つのファイルができます。
image.png
(古いcsprojを使っている場合は「追加>既存の項目」で2ファイルをプロジェクトに追加してください)

この2ファイルのプロパティで「ビルドアクション」を 「埋め込みリソース」 に変更します。
image.png

3. .gitignoreに追記

この2ファイルをgitの管理対象外とするためにソリューションの「.gitignore」ファイルに1行追記します。

.gitignore
git_*.txt

VisualStudio上ではこのファイルにgitの管理対象外になったマークがつきます。
image.png
VisualStudio2022(17.4)以降なら「ソリューションエクスプローラー」や「git変更」画面でもこの作業は可能です。ファイルを右クリックして「このローカル項目を無視」として .gitignoreに1ファイルずつ追加します。
image.png

4.C#からコミットID情報を読み出し

C#側からは埋め込みリソースを読み出せばよいだけになります。
簡単なヘルパークラスGitInfoを作ってみました。

GitInfo.cs
using System.IO;
using System.Linq;
using System.Reflection;

internal static class GitInfo
{
    public static string CommitId => GetResource("git_id.txt");
    public static string BranchName => GetResource("git_branch.txt");

    private static string GetResource(string name)
    {
        var asm = Assembly.GetExecutingAssembly();
        var resName = asm.GetManifestResourceNames().FirstOrDefault(a => a.EndsWith(name));
        if (resName == null)
            return string.Empty;
        using (var st = asm.GetManifestResourceStream(resName))
        {
            if (st == null) return string.Empty;
            var reader = new StreamReader(st);
            return reader.ReadToEnd().Trim('\r', '\n');
        }
    }
}

.NET Framework対応を無くせばもっとすっきり書けるのですが...
出力ファイル名を変えた方は適宜修正してください。

このクラスを使ってみます。

Program.cs
private static void Main(string[] args)
{
    Console.WriteLine(GitInfo.CommitId);
    Console.WriteLine(GitInfo.BranchName);
}

以下のようにコミットIDとブランチ名が表示されました。

667a776
main

VisualStudio以外の場合

VisualStudio編で行った上記1,2の作業を csprojファイル編集で実現します。
通常は <PropertyGroup>しかないので以下にあるように<Target>以降を丸ごとコピペします。作業3,4はVisualStudio編と変わりません。

ConsoleApp1.csproj
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <!-- ここ以降を追記 -->

  <Target Name="PreBuild" BeforeTargets="PreBuildEvent">
    <Exec Command="git rev-parse --short HEAD &gt;$(ProjectDir)git_id.txt&#xD;&#xA;git branch --show-current &gt; $(ProjectDir)git_branch.txt" />
  </Target>

  <ItemGroup>
    <None Remove="git_branch.txt" />
    <None Remove="git_id.txt" />
  </ItemGroup>

  <ItemGroup>
    <EmbeddedResource Include="git_branch.txt" />
    <EmbeddedResource Include="git_id.txt" />
  </ItemGroup>

  <!-- ここまで -->
</Project>

おわりに

以前は AssemblyInfo.cs の書き換えが主流でしたが、今回は別ファイル出力で対応しています。
これぐらいの機能はVisualStudio内の機能として実装してほしいですね・・。

17
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
13