iOSアプリのバージョニング方針草案


目的

バージョニングのプラクティス化

前提環境

iOSApp/MacApp開発、CI/CDが構築されている。

iOSのバージョニング概要

iOSのバージョン管理では、以下の二つが利用されます。

  • CFBundleShortVersionString
  • CFBundleVersion

詳しくはこちらに書いてあります。

一言で説明すると
CFBundleShortVersionString: ユーザーから見えるバージョン。セマンティックバージョニングが推奨。2.3.0のようなピリオド区切りでメジャー、マイナー、パッチを管理する。
CFBundleVersion: アプリの内部バージョンでユーザーからは見えない。しかし、AppStoreConnectへバイナリをアップロードする際に、前のビルドよりも数値が上がっている必要がある。

となります。

草案

1. CFBundleShortVersionStringはセマンティックバージョニングで手動管理

こちらは、プロダクトの意図に合わせて変更する必要があるので、手動でplistを弄って変更を行いコミットします。

他に考えられる案

CIを前提にしているので、git tagをトリガーにデプロイフロー→gitのバージョンタグを拾ってCFBundleShortVersionStringにセット。のようなフローも考えられます。

ただ、2.0.0のようなタグを打ってバイナリをアップデートし終わった後に問題が発覚すると、修正し終わった後に前のタグを消して同じタグを新しいコミットに付けるか、もしくは2.0.1のようなパッチバージョンで新しいタグをつけるかしかないので、開発側にある程度パッチバージョンレベルの決定権がないと難しそうです。

2. CFBundleVersionはCIでの自動管理に任せる

要件

この内部バージョンでまず必須なのは
バイナリアップロード時に前のバージョンより大きいこと

そして、あると便利なのが
問題が発生した時にコミットを一意に特定できること

だと考えています。前者はApple側の仕様ですが、後者はこのようなケースが考えられます。

「ユーザーからエラー報告が上がってきたが、ユーザーから見えているバージョンと内部番号は必ずしも一致しないので(リリースはひとつだがビルドが複数存在するケース)、内部番号を使ってどのコミット/ビルドで問題が発生していたのか一意に特定して追跡したい。」

上記の要件を踏まえて「毎回数値が増えていて一意で特定可能」であれば良いので、バイナリアップデートごとにまめに手で数字を増やしても実現可能なのですが、かなり面倒でミスの入り込む余地がありそうなので、CI/CDでの自動管理を提案したいです。

提案手法

自動デプロイフローの際に、CI/CDでのビルド番号をCFBundleVersionにセットする。

TravisCIではTRAVIS_BUILD_NUMBERCircleCIではCIRCLE_BUILD_NUMとして環境変数でビルド番号が取得でき、特にBitriseではステップとしてSet Xcode Project Build Numberというステップを用意しており、plistのパスを指定するだけでCIのバージョン番号を自動設定してくれます。

このCI/CDのビルド番号は、毎回インクリメントされ、かつ、ビルド番号からビルドを特定でき、クローンしているgitのコミットハッシュを特定する事が可能なので、先ほど上げた2つの条件を満たしていると言えます。

ただ1つ問題として、内部バージョンはアーカイブ後に毎回捨てられ、コミットには載らないので気になる人もおられるかもしれません。

まとめ

今回はこのようにCFBundleShortVersionStringはセマンティックバージョニングでプロダクトに応じて手動管理し、CFBundleVersionは手元では一切触らず、CI/CDのビルド番号をセットする自動管理に任せる」というバージョニング方針を提案させて頂きました。

「~な理由でこうした方が良いよ!」「これは~な理由でやめた方が良いよ!」など、ご意見是非コメントいただけると助かります。