アプリのバージョン情報にgitのコミットIDが埋め込まれていることがよくあると思います。
> 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の情報をファイルに書き出します。
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つのファイルができます。
(古いcsprojを使っている場合は「追加>既存の項目」で2ファイルをプロジェクトに追加してください)
この2ファイルのプロパティで「ビルドアクション」を 「埋め込みリソース」 に変更します。
3. .gitignoreに追記
この2ファイルをgitの管理対象外とするためにソリューションの「.gitignore」ファイルに1行追記します。
git_*.txt
VisualStudio上ではこのファイルにgitの管理対象外になったマークがつきます。
VisualStudio2022(17.4)以降なら「ソリューションエクスプローラー」や「git変更」画面でもこの作業は可能です。ファイルを右クリックして「このローカル項目を無視」として .gitignore
に1ファイルずつ追加します。
4.C#からコミットID情報を読み出し
C#側からは埋め込みリソースを読み出せばよいだけになります。
簡単なヘルパークラスGitInfo
を作ってみました。
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対応を無くせばもっとすっきり書けるのですが...
出力ファイル名を変えた方は適宜修正してください。
このクラスを使ってみます。
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編と変わりません。
<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 >$(ProjectDir)git_id.txt
git branch --show-current > $(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内の機能として実装してほしいですね・・。