Edited at
DiverseDay 2

git のコミットハッシュを取得して android アプリのバージョン番号にする

More than 3 years have passed since last update.


背景

弊社は git でソースコードの管理をしています。

ブランチを作って開発し、pull request を出してレビューが通れば master にマージする運用をしています。

開発時には、リリース時期の異なる複数のブランチを渡り歩き、機能の実装や検証や修正を平行して行うことがあります。

この場合、android アプリ側にそれぞれの機能に対応したブランチがあり、サーバ側の api 実装にも同様の分け方のブランチが存在しています。

私が関わっているプロダクトの場合、サーバ側は、ブランチごとにプロセスを立ち上げ、ブランチごとにアクセスできるような仕組みがあります。

また、開発中のアプリからは、アプリに合ったサーバ側ブランチを自由に選べる仕組みがあります。

開発期間中は、実際に開発関係者で使ってみてフィードバックを得て改善することが日常です。

この時点で不具合などが報告された場合、そもそも、どの時点のビルドのアプリで、どのブランチのサーバ側の api にアクセスしたのかを知る必要があります。

サーバ側のログにアプリのビルド情報が残っていない場合、問題が起きている端末を物理的に手にとるしか組み合わせを確認する方法がありません。

デバッグ版アプリをアップデートしたつもりであったり、アプリから接続先を変更したつおもりであったりと、どうしてもやったつもりになることが多々発生します。

そのため、サーバ側の api のログを見ただけで、どのアプリからのアクセスかわかるようにしたい気持ちが強くありました。


git の状態を得る


HEAD のコミットハッシュを得る

コミットハッシュがわかれば、即座に状態を git checkout で取り出すことができるため、コミットハッシュを使うことにしました。

$ git rev-parse --short HEAD

2e6a95c


git status を parse しやすい形式で出す

ビルドに使った作業ディレクトリに未コミットのファイル等があった場合、その把握もできるようにします。

$ git status --porcelain

M build.gradle
?? woremacx.log


上記2つをスクリプトにまとめる

#!/bin/sh

# commithash-and-dirty.sh

commithash=`git rev-parse --short HEAD`

dirty=""
status=`git status --porcelain`
if [ -n "$status" ]; then
dirty="X"
fi

echo "$commithash$dirty"


上記スクリプトを build.gradle に組み込む

def commitHash = ["sh",  "-c",  "cd ${project.rootDir} ; ./script/commithash-and-dirty.sh"].execute().in.text.trim()

def debugTag = "-debug-" + commitHash

android {
buildTypes {
debug {
versionNameSuffix debugTag
}
}
}


api にアクセスする際の UserAgent 名に PackageManager でとれる versionName をつかう

public class WoremacxUtil {

private static final String USER_AGENT_BASE = "WoremacxAndroidApp";
private String mVersionName;
private String mUserAgentName;

public void buildUserAgentName() { // UA をセットするときにこのメソッドで生成
PackageInfo packageInfo;
try {
packageInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
mVersionName = packageInfo.versionName;
mUserAgentName = USER_AGENT_BASE + "/" + mVersionName;
} catch (NameNotFoundException e) {
throw new RuntimeException(e);
}
}
public String getUserAgentName() {
return mUserAgentName;
}
}

ここで生成された UserAgentName で api にアクセスすれば、

WoremacxAndroidApp/1.1.0-2e6a95cWoremacxAndroidApp/1.1.0-2e6a95cX が記録され、

api のログを見るだけでどの開発中のアプリを使ったかが容易にわかるようになりました。