しばやん雑記

Azure とメイドさんが大好きなフリーランスのプログラマーのブログ

Azure Web Apps へのデプロイ時に Git のコミットハッシュをアセンブリに埋め込む

Web アプリケーションのフッターに、バージョン情報や Git のコミットハッシュが埋め込まれているのを見ます。ちょっと違いますが、Kudu もコミットハッシュが表示されてます。

ASP.NET アプリケーションでも、同じようにバージョンとコミットハッシュを表示させてみたいので、コミットハッシュを埋め込む 2 つの方法を試してみました。

MSBuildTasks を使う

Web Deploy を使って Web Apps へデプロイする場合には、MSBuildTasks を使って埋め込むしか方法がありません。GitVersion タスクでコミットハッシュを取得して、AssemblyInfo.cs を丸ごと作成します。

実際の手順は以下のブログにとても分かりやすく書いてありました。MSBuild 初心者でも分かりやすい。

MSBuild: add git commit hash to AssemblyInfo · now from home

NuGet で MSBuildTasks をインストールし、csproj を編集してビルドすると埋め込まれます。

全く新しい AssemblyInfo.cs が生成されていることが確認できます。

実際に使う場合には .gitignore に AssemblyInfo.cs を入れておかないと、毎回コミット対象になってしまってちょっとめんどくさい感じでした。

コミット後に新しいコミットハッシュが埋め込まれるのでしょうがない感じはします。知らずに放置しておくと、無限にコミット出来てしまいそうですね。

カスタムデプロイスクリプトを使う

カスタムデプロイスクリプト内では SCM_COMMIT_ID という環境変数で、デプロイしようとしているコミットのハッシュが取れるので、これを利用して AssemblyInfo.cs にコミットハッシュを埋め込みます。

デフォルトのバッチファイルだと処理が大変すぎるので、PowerShell で書き直したバージョンを使います。

既に設定されている AssemblyVersion を読み取って、そのバージョンにコミットハッシュを追加したいので、正規表現で AssemblyInfo.cs からバージョンを抽出します。

実際に書いたスクリプトは以下のような感じです。イマイチな感がありますが、動くのでまあ良しとします。

$ASSEMBLY_INFO_PATH = "$DEPLOYMENT_SOURCE\WebApplication7\Properties\AssemblyInfo.cs"
$ASSEMBLY_INFO_CONTENT = Get-Content $ASSEMBLY_INFO_PATH

$ASSEMBLY_VERSION = [regex]::Match($ASSEMBLY_INFO_CONTENT, "AssemblyVersion\(`"(.+?)`"\)").Groups[1].Value
$ASSEMBLY_INFORMATIONAL_VERSION = [string]::Format("[assembly: AssemblyInformationalVersion(`"{0}-{1}`")]", $ASSEMBLY_VERSION, $env:SCM_COMMIT_ID.Substring(0, 7))

Add-Content -Path $ASSEMBLY_INFO_PATH -Value $ASSEMBLY_INFORMATIONAL_VERSION

これを deploy.ps1 の MSBuild 呼び出し前に追加して、Web Apps にプッシュすると埋め込まれます。

Kudu を使って Web Apps 上のリポジトリを確認すると、AssemblyInfo.cs に属性が埋め込まれているのが確認できます。リポジトリ内のファイルを変更しても、Kudu が更新時に面倒みてくれるので大丈夫です。

コミットハッシュ込みのバージョンを取得する

昔はカスタム属性を取得するのがめんどくさかった記憶があるのですが、.NET 4.5 からはジェネリックに対応した拡張メソッドが用意されているみたいで、とてもシンプルに書けるようになっていました。

CustomAttributeExtensions.GetCustomAttribute メソッド (System.Reflection) | Microsoft Learn

この拡張メソッドを使って AssemblyInformationalVersion 属性を取得して値を取り出します。

// 実行中のアセンブリを取得
var assembly = Assembly.GetExecutingAssembly();

// AssemblyInformationalVersion 属性を取得
var assemblyInformationalVersion = assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>();

// ex. 1.0.0.c33eac3
var informationalVersion = assemblyInformationalVersion.InformationalVersion;

カスタム属性は実行中に変化することがないので、アプリケーションの初期化時に取得しておきましょう。

それっぽくフッターに表示してみました。どのバージョンが Web Apps にデプロイされているか調べるためにはポータルを確認するしかなかったので、さっと確認出来るようになり少し便利になりました。

今回は Git のコミットハッシュでしたが、日付を付けるなど割と自由に出来ます。