Xcode
iOS
Swift
swift4
Xcode9

XCodeビルド時、バージョン番号にコミットハッシュを含めるやり方

何がしたいか

Xcodeのinfo.plistからアプリのバージョンが確認できると思います。

今回やりたいことは
従来のバージョン番号: 21.0.0
-> 今回: 21.0.0_b7403112
のようにバージョン番号の後ろにビルドしたときのコミットハッシュを含めます。

なぜ必要か

業務において、アプリのステージング版を配布してフィードバックをもらうときに、どのタイミングで発生した不具合なのか確かめたいときがあると思います。
アプリのビルド番号を辿るとかは現実的でないですが、コミットハッシュがあれば容易に辿れます。

今回僕が働いているインターン先で、自動でアプリのバージョン番号にコミットハッシュを含めるようにしたのでその時の流れを説明します。

流れ

  1. ビルド時のコミットハッシュを取得
  2. ビルド時のバージョン番号取得
  3. バージョン番号を1と2を足したものに差し替え
  4. 上記をまとめたshellスクリプトをxcode上で実行

大まかな流れとしてはこんな感じでシンプルにできます。

コレができると、今後info.plistの中身を動的に書き換えたいときに今回のやり方を応用して対応することができます。
他にはビルド番号を自動で上げたいときによく使わレイチェルです。

ビルド時のコミットハッシュを取得

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

これでコミットハッシュの短縮版をもってこれます。

shell初心者なのでコマンドの部分を’で囲ってて何で動かないんだろうって無駄に悩んでました。。。
`で囲うようにしなきゃ認識してくれないんですね。

ビルド時のバージョン番号取得

後に作成するrun script上で

versionString=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${SRCROOT}/${INFOPLIST_FILE}")

でいけます。
ここで取得したバージョン番号にコミットハッシュを加えて設定し直したいと思います。

書き込み、読み込みにPlistBuddyというのを使っていて、いくつか調べると今は対応していないという記事が見つかったのですが、それは間違いっぽいです。

CFBundleShortVersionStringのところは自分が変更したい項目に応用ができます。
僕はここから探してきました。

バージョン番号を1と2を足したものに差し替え

newVersionString=${versionString}_${commithash}
/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $newVersionString" "${TEMP_DIR}/Preprocessed-Info.plist"

PlistBuddyのSetで書き込みが出来ます。

読み込むファイルと書き込むファイルパスには工夫をしていて、そうしないとinfo.plistに差分が出来てしまったり、コミットハッシュが連続で作成されたりします。
詳しくは以下リンクをどうぞ
これがXcodeでのバージョニングの決定版になるかも

上記をまとめたshellスクリプトをxcode上で実行

Xcode上で自分が指定したいtarget(今回はアプリのstaging版)-> Build Phasesと移動したら、nav menuのEditor -> Add Build Phase -> Add Run Script Build PhaseでRun Scriptが追加できます。
(参考: 【iOS】RunScriptはいったいどこに行ってしまったの???

そこに先ほど書いたスクリプトを貼りつけます。

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

infoPlist="${TEMP_DIR}/Preprocessed-Info.plist"
infoPlistSource="${SRCROOT}/${INFOPLIST_FILE}"

versionString=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "$infoPlistSource")
newVersionString=${versionString}_${commithash}

/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $newVersionString" "$infoPlist"

加えてPreprocessed-Info.plistに書き込みたいのでBuild SettingsからPreprocessed-Info.plist FileをYesに設定しておきます。

確認の方法

今回書き込んでいるファイルはPreprocessed-Info.plistというビルドしたら作成されるファイルなので、単純にxcode上でversion string見ても変更は確認できないと思います。
Jenkinsのログでも変更が確認できませんでした。

とりあえずはechoでログを見つつ、ビルドしてHockeyAppなどにあがっているもの確認しましょう。

今回参考にした記事

RunScript周り
XCodeのRun Scriptを試しに触ってみる
【iOS】RunScriptはいったいどこに行ってしまったの???
Xcode でのビルド時に Run Script でメッセージを表示する

PlistBuddyのkey指定
Core Foundation Keys

その他
git のコミットハッシュを取得して android アプリのバージョン番号にする
Build 番号の自動更新スクリプトで Info.plist そのものに書き込まないための考察
iPhone アプリのビルド番号を自動的に更新する
これがXcodeでのバージョニングの決定版になるかも
PlistBuddyからplutilに乗り換え
info.plist書き換え
Xcodeのrun scriptで、iOSアプリのビルド番号を手軽に自動採番する
sekati/xcode-build-bump.sh

shell初心者向け
shellスクリプト上でコマンド実行した結果を変数に格納
複数の変数を連結する