TestFlight のビルド番号が食い違う問題と、審査に出す前の7つの自動検査

TestFlight のビルド番号(CFBundleVersion)を上げても git に残らず、App Store Connect の番号と食い違いました。番号の決め方とアーカイブを1つのコマンドにまとめ、App Store 版では接続先や切り替えの部品など7項目を自動で検査するようにした記録です。

「ビルド番号」と「7つの検査」の文字と、検査の名前の札

TestFlight のビルド番号(CFBundleVersion。同じ番号は2回アップロードできない)の食い違いは、番号を決めてアーカイブ(アップロード用のまとまり)を作るまでを1つのコマンドにまとめて防ぎました。番号は XcodeGen の設定ファイル(project.yml)に書き、App Store 版ではアーカイブの中身を7項目で自動検査して、通った時だけ番号を記録します。

TestFlight(Apple のテスト配信)にアプリを上げるたびに、ビルド番号を1つ上げる必要があります。同じ番号は2回アップロードできないからです。私たちの業務アプリ(Kaitori Base)では、この番号の更新が git に残らず、App Store Connect に上がっている番号とリポジトリの番号が食い違いました。

そこで、番号を決めてアーカイブ(アップロード用のまとまり)を作るまでを1つのコマンドにまとめました。審査に出す App Store 版では、さらに、できたアーカイブの中身を7つの項目で自動で検査し、通った時だけ番号を記録するようにしています。

TestFlight のビルド番号が git に残っていなかった

最初は、番号を上げる小さなスクリプトと、Xcode でのアーカイブを、別々に行っていました。番号を上げてアーカイブし、アップロードしても、その番号の変更をコミットし忘れることがありました。

黒い数字が並ぶ、パタパタ式の置き時計の写真
番号は、ただ上げるだけでは足りない(イメージ写真)

もう1つ、番号の置き場所の問題もありました。私たちは XcodeGen(設定ファイルから Xcode のプロジェクトを作る道具)を使っています。プロジェクトを作り直すと、Xcode の中で直接書き換えた値は消えてしまいます。そこで、ビルド番号は XcodeGen の設定ファイル(project.yml)に書くことにしました。

git に残っていたビルド番号が6の次にいきなり25になっていた図。リポジトリの番号を信じると、アップロード済みの番号とぶつかる
ビルド番号の食い違い

番号を決めてアーカイブするまでを1つのコマンドに

番号を上げるスクリプトをやめて、番号の決定とアーカイブを1つのコマンドにまとめました。

ビルド番号を決めてアーカイブを作り、project.yml に書いてコミットするまでを1つのコマンドにまとめた。始める前に、変更なし・main のブランチ・リモートと同じ、の3つを確かめる
人がするのは、最後のアップロードだけ
シェル番号の決め方(仕組みが分かる短い見本)
# 過去のアーカイブの Info.plist から、ビルド番号の最大を探す
max=0
for plist in ~/Library/Developer/Xcode/Archives/*/*.xcarchive/Info.plist; do
  v=$(/usr/libexec/PlistBuddy -c 'Print :ApplicationProperties:CFBundleVersion' "$plist" 2>/dev/null || echo 0)
  [ "$v" -gt "$max" ] 2>/dev/null && max=$v
done
next=$((max + 1))
# リポジトリの番号のほうが大きければ、そちらを使う
[ "$repo_ver" -ge "$next" ] && next=$repo_ver

決めた番号は project.yml に書き込み、コミットまでを同じコマンドの中で行います。人がするのは、最後のアップロードだけです。

審査に出す版では、アーカイブの中身を7項目で検査する

TestFlight で自分が試す版と、審査に出す App Store 版は、同じアプリでも中身が違います。App Store 版は本番のサーバーにだけつながり、テスト環境への切り替えのボタンは入っていません。この違いを、アーカイブができたあとに、中身を開いて確かめます。

クリップボードの点検の紙と、ノートパソコンが机に置かれた写真
審査に出す前の検査は、チェックリストのように並べた(イメージ写真)
検査 確かめること
1 ビルドの構成が Release(App Store 用)であること
2 接続先が本番であること
3 テスト環境への切り替えの部品が入っていないこと
4 通知の拡張(通知を受け取る小さなプログラム)が正しく入り、本体と同じ App Group の権限があること
5 本体と通知の拡張で、バージョンとビルド番号が一致し、狙いどおりであること
6 iPhone 専用であること(本体と拡張の両方)
7 プライバシーの申告ファイル(PrivacyInfo.xcprivacy)が入っていて、壊れていないこと
番号を決め、アーカイブし、7項目の検査をして、通った時だけ番号をコミットする流れ
App Store 版のコマンドの順番。1つでも通らなければ、何も残さない
ターミナルの再現。アーカイブの7項目の検査がすべて通り、ビルド番号を記録しますと表示されている。表示は見本
7項目の検査の表示(見本)

検査3が、実は何も確かめていなかった

検査3は、テスト環境への切り替えの部品が、アプリの実行ファイルに入っていないことを確かめるものです。最初は、その部品だけが持つ日本語の文字を、実行ファイルの中から探していました。

検査3は切り替えの部品が実行ファイルに入っていないことを確かめるもの。strings は日本語を拾わないので、部品が入っていても入っていなくても見つからず検査はいつも通っていた。英字の目印を実際のビルドで確かめてから使うことにした
いつも通る検査は、無いのと同じ

検査を作ったら、「通る時に通る」だけでなく、「通ってはいけない時に止まる」ことも確かめる必要があります。いつも通る検査は、無いのと同じです。

まとめ

TestFlight のビルド番号が食い違う問題と、審査に出す前の7つの自動検査:要点のまとめ。ビルド番号の更新が git に残らず、アップロード済みの番号と食い違った
この記事の要点
  • ビルド番号の更新が git に残らず、アップロード済みの番号と食い違った
  • 番号は「過去のアーカイブの最大+1(リポジトリの値が大きければそちら)」で決め、アーカイブと同じコマンドで記録する
  • App Store 版は、アーカイブの中身を7項目で検査し、通った時だけ番号をコミットする。失敗したら何も残さない
  • 検査そのものが効いているかを、止まるべき場面で確かめる

App Store 版に切り替えのボタンを入れない理由は、次の記事に書いています。

「切り替えボタンは App Store 版に入れない」の文字と、Debug・TestFlight・Release の札アプリ開発本番のアプリから「テスト環境に切り替えるボタン」を消した理由と、#if DEBUG では足りなかった話本番とテストの接続先を切り替えるボタンを、開発用と TestFlight 用のビルドにだけ出し、App Store 版には入れないことにしました。TestFlight のビルドは Debug ではないので #if DEBUG では分けられず、SWIFT_ACTIVE_COMPILATION_CONDITIONS の独自フラグで切った方法です。

この記事は、AI(Claude)の支援を受けて作成し、筆者が内容を確認しています。

  • TestFlight
  • App Store Connect
  • ビルド番号
  • Xcode
  • アーカイブ
  • シェルスクリプト

関連する記事

この記事に関連するサービス・アプリ

ブログの一覧へ