Git
iOS
CircleCI
Swift

CFBundleVersion❤Git

More than 1 year has passed since last update.

CircleCIでiOSプロジェクトをビルドした際にBuild(CFBundleVersion)をうまく更新したい。

今まではスプリクトを作成し、CFBundleVersionをインクリメントするスプリクトを作成しCircleCIからコミットするようにしていたが、GitHubの新しい機能とバッティングしてしまった。

そこで対応方法を考えた。一つは$CIRCLE_BUILD_NUMを使うことである。これはとてもうまくいく。
https://ja.ngs.io/2015/04/05/circleci-ios/

そこから発想を展開させ検索し、次の記事を見つけた。
CFBundleVersionとタイムスタンプを使う手法で、これもうまくいく。
http://www.tokoro.me/2014/05/19/xcode-versioning/

ここで、現在の状態からCFBundleVersionを生成するとコミットしなくてすむことが分かった。
そこで、前述の手法を参考に次のようなスプリクトを考えた。

plistBuddy="/usr/libexec/PlistBuddy"
infoPlistFileSource="${SRCROOT}/${INFOPLIST_FILE}"
infoPlistFileDestination="${TEMP_DIR}/Preprocessed-Info.plist"

if ! git diff-index --quiet HEAD --; then
gitChangedSuffix="*"
fi

branchName=$(git rev-parse --abbrev-ref HEAD)
shortGitVersionHash=$(git rev-parse --short HEAD)
gitBaseVersion="$branchName:$shortGitVersionHash"

if [ -n "$CIRCLE_BUILD_NUM" ] && [ $branchName = "master" ]; then
  versionString=${CIRCLE_BUILD_NUM}
elif [ -n "$CIRCLE_BUILD_NUM" ]; then
  versionString=$gitBaseVersion#${CIRCLE_BUILD_NUM}
else
  versionString=$gitBaseVersion${gitChangedSuffix}
fi

$plistBuddy -c "Set :CFBundleVersion $versionString" $infoPlistFileDestination

これは4つの結果になる。

A: master:db4e1e6
B: master:db4e1e6*
C: master:db4e1e6#1
D: 1
  • Aは、CircleCI以外でビルドした場合
  • Bは、Aの場合でaddされてないコミットがある場合
  • Cは、CircleCIでmaster以外でビルドした場合
  • Dは、CircleCIでmasterでビルドした場合

実際には次の要素で構成される。

(GIT_BRANCH):(GIT_SHORT_HASH)(GIT_CHANGE)(#CIRCLE_BUILD_NUM)

結論として、このようにすることでgitの状態からCFBundleVersionを決定することが出来るので、CFBundleVersionからアプリの実際のコードを逆引きし問題を解決しやすくなると考えられる。

Dが必要な理由は、申請時にはCFBundleVersionがピリオドで区切られた非負の整数の必要があるため。
ITMS-90060エラーでiTunes Connectへバイナリがアップロードできない件