📄

最終コミット情報をアプリに含める方法

2023/03/24に公開

アプリのバージョン情報などに、コミットハッシュや最終コミット日などのコミット情報が含まれるアプリってありますよね?

バージョン情報に表示されるコミット情報
バージョン情報に表示されるコミット情報(画像はAudacityのもの)

特にクローズドソースでお客さん向けアプリを開発している時など、お客さんの環境に同じバージョンだけど違うコミットのビルドがたまることがあり、お客さんが「バグが見つかりました」といってももう修正したものなのか未修正のものなのかがわからなくなることがあります。

そんな時にバージョン情報ダイアログなどでコミット情報が参照できるようになってると、それを伝えてもらうことで、すでに修正したものなのか、未知のバグなのかを切り分けしやすくなるという利点があります。それとなんとなくかっこいい。

さて、こんなコメント情報ですが、リリース環境では当然gitリポジトリに関する情報が使えなくなってしまうので、リリースした時にどうやってコミット情報を得るかどうかというのが問題になります。

一番簡単なのはGitのフックスクリプトを使ってコミット情報が書かれたファイルを生成し、保存すること。JSONあたりにしておくとElectronのアプリケーションなどならそのままrequireできるので楽かもしれません(もちろん形式は使いやすければ何でもいいんですが)。

さっそくフックスクリプトを書いてみる

では本題。フックスクリプトはこんな感じで作っておきます。

#!/bin/bash
commit_hash=$(git log -1 --pretty=%h)
commit_date=$(git log -1 --pretty=%cd --date=format:'%Y/%m/%d %H:%M:%S')

# Create a JSON object 
json='{
  "commit": "'$commit_hash'",
  "date": "'$commit_date'"
}'

# Save the JSON object to a file
echo $json > res/lastcommit.json
echo created res/lastcommit.json

本来の配置場所は/.git/hooks/なのですが、.git配下に置いたファイルはコミット対象にできないので、まずは/hooks/last-commitあたりに置いておきます。

フックスクリプトのリンクを作成する

次にフックスクリプトのリンクを/.git/hooksディレクトリ配下に配置します。

とは言えそのままコピーしてしまうと/hooks配下のファイルを変更したときに更新が反映されないので、リンク作っておくと良いです。

# Windowsの場合
$dir = (Convert-Path "$PSScriptRoot/")
if((Test-Path "${dir}.git") -and !(Test-Path "${dir}.git\hooks\post-commit")){
  New-Item -Value "${dir}hooks\last-commit" -Path "${dir}.git\hooks\post-commit" -ItemType HardLink
  New-Item -Value "${dir}hooks\last-commit" -Path "${dir}.git\hooks\post-checkout" -ItemType HardLink
}
if((Get-Command sh -ErrorAction Silent) -and !(Test-Path "${dir}res\lastcommit.json")){ sh "${dir}hooks\post-commit" }

post-commitフックは「コミットをしたあと」に、post-checkoutは「チェックアウトをしたあと(ブランチを切り替えた直後など)」に呼び出されるコミットフックです。

このためこの二つにフックを設定することによって、コミットしても、ブランチを切り替えても常に最新の情報がJSONファイルに書き込まれるという形になります。

このへんをinit.ps1などとして保存し、リポジトリをクローンした後すぐに呼び出すような運用にしておくと良いでしょう。

ファイルを参照する

実際にコミット情報を参照する時は、次のような形でrequireします(Electronアプリケーションの場合。それ以外の場合は適宜読み替えてください)。

require("/res/lastcommit.json").commit;

コミットフックを設定しておくことで、/res/lastcommit.jsonは常に最新の状態になるはずです。

リリース版とデバッグ版でコミット情報の参照方法が異なるようなことになるとあとあとコミット情報の取得方法が変わったときに対応しづらくなるので、デバッグ実行する際も、お客さんへのリリースパッケージを作成する際も、常にこのファイルを参照するようにしましょう。

任意のタイミングで呼び出したいときは?

ソースコードお客さんに提出するときなど、念のため最新のファイルを生成したいというときは、/hooks/last-commitを直接呼び出します。

Windowsだと当然シェルスクリプトは呼び出せませんが、Git bashを使ってやるといちいち別のソフトをインストールする必要がなく、楽です。

c:\Program Files\Git\binあたりにパスを通しておくとシェルスクリプトを直接呼べるようになりますので、それがいいでしょう。

Discussion