← 開発日記に戻る

Fastlane デュアルクラウド Mac:ビルドとアップロード分離後に多い 3 つの失敗パターン

Runbook · 2026.06.04 · 約 8 分 · オンコール手順に貼れる

デュアルクラウド Mac:香港で archive、カナダで Fastlane upload

オンコール中で、2 台以上のレンタルクラウド Mac 上の Fastlane で iOS をリリースしており、「ビルドログは緑なのに TestFlight に新しいビルドが無い」「アップロードしたパッケージが違う」といった事象が出ている方が対象です。クラウド導入や 2 台目の要否は TestFlight 専用 Mac または Xcode ビルドのクラウド移行 を先に — 本稿はすでに1 台がビルド、1 台がアップロードに分かれている前提です。

読み終えたら、次の 2 点が言えるはずです。① ログから、証明書・成果物・ネットワークのどれが疑わしいか② 2 台の役割分担が正しいか、マシンを増やすべきか

用語の整理(以降で繰り返し使用)
  • ビルド機:Xcode でプロジェクトをコンパイルし、インストールパッケージ(.ipa)をエクスポートするだけ
  • アップロード機:リリース証明書で署名し .ipa を TestFlight に送る。App Store Connect に登録する出口 IP はこの 1 台に合わせる
  • Archive / ビルド成果:Xcode の配布用出力。機間では完成した .ipa だけを渡し、プロジェクトキャッシュ一式は移さない
  • match:Fastlane の証明書・プロビジョニング統合ツール — 1 台でのみ実行

読まなくてよい場合: Mac が 1 台だけ、または TestFlight アップロードが安定しており、まだ「ビルド + アップロード」の 2 台構成にしていない。複数のクラウド Mac でリリースしておりパイプラインに問題がある場合は、続きを読んでください。

TL;DR(30 秒)
香港ビルド + カナダアップロードのようなデュアルクラウド Mac 構成では、ボトルネックは CPU ではなく Fastlane の3 種類の境界エラーであることが多いです。
  1. 証明書の境界 — リリース証明書がビルド機に同期され、アップロード機が署名できない(最も危険)
  2. 成果物の境界 — 検証可能な .ipa ではなく .xcarchive を DC 間で送っている(最も見つけにくい)
  3. ネットワーク ID のドリフト — ASC の IP 許可リストが古い IPv4 のまま(調査が最も難しい)
以降は30 秒トリアージ木、3 故障モードの詳細、検収表、4 段階の成熟度判断、そして「最終結論」ブロック(そこだけ読んでも意思決定できる)の順です。

背景(1 分):2 台にしたあと壊れるのは境界で、CPU ではない

多くのチームは 2 台のクラウド Mac を使います。アジアに近い 1 台が昼間に App をインストールパッケージにコンパイルし、カナダの 1 台がApple にパッケージを渡す(TestFlight / App Store)。2 台目は速度のためであることが多いですが、オンコールで時間を取るのは両方が証明書とファイル転送に手を出していること — ビルドは成功表示なのに TestFlight に新版が無い、というパターンです。

まずよくある誤った分け方(モデル B)、次に当社の分け方(モデル A)と検証方法を述べます。

推奨:モデル A(ビルドはパッケージのみ、アップロードは公開のみ)

要約:ビルド機は .ipa だけを出す。アップロード機だけが証明書と TestFlight を担当する。 両方で match を走らせない — 秘密鍵が誤ったホストに残り、アップロード機で配布証明書が見つからなくなります。

2 台のクラウド Mac の役割(モデル A)
Role ビルド機(香港) 例:APAC 昼間のビルド アップロード機(カナダ) 固定 IP で Apple へ
Doコード取得 → Xcode ビルド → .ipa エクスポート.ipa 受領 → リリース署名 → TestFlight へ
Do notmatch 禁止・TestFlight アップロード禁止
Hand offPackage file + build ID (RUN_ID)None (endpoint is App Store Connect)

当社の 2 台は Hashvps の独立 Mac mini 上で動かしています。選定理由は固定 IP とロール分離(アップロード機 IP のみ ASC に記載し、ビルド機は不要)です。香港ノードのスペックは 香港 Mac mini レンタル を参照してください。

ビルド機 · パッケージのみ アップロード機 · Apple へ提出 build → export .ipa no certs · no upload includes build ID certs + TestFlight upload fixed public IP registered in ASC .ipa → DC 間の最小単位は xcarchive ではなく、検証可能な IPA
モデル A:match と署名はアップロード機のみ。ビルド機は IPA を渡すだけ

当社の 2 台は Hashvps の独立 Mac mini 上で動かしています。選定理由は固定 IP とロール分離(アップロード機 IP のみ ASC に記載し、ビルド機は不要)です。香港ノードのスペックは 香港 Mac mini レンタル を参照してください。

よくある誤り:モデル B(両方が「手伝って」いる)

モデル B は役割が分かれていない状態です。当社も 1 週目はこう運用しました。見た目は 2 台分担ですが、実際は:

  • 両方で match → リリース用秘密鍵がビルド機に残る → アップロード機で署名不可 → TestFlight が失敗し続ける
  • .xcarchive 一式を他ホストへコピーして再エクスポート → 設定不一致 → Apple がパッケージを拒否
  • 両ホストでそれぞれ .ipa をエクスポート → オプション不一致 → ログは成功、TestFlight に使えるビルドが無い

既存パイプラインのどれかに当てはまるなら、解決策は「Mac をもう 1 台」ではなく、build / upload の role split(モデル A)が必須です。

可観測性:build と upload が同一ビルドかどうか

最も多い運用事故は「昨夜の IPA を今日アップロードした」ことです。ビルド機・アップロード機の両ログに同じフィールドを必ず出します:

  • RUN_ID(パイプライン 1 回分の ID。例 hk-build-88421
  • GIT_SHA(短い commit hash)
  • 成果物パス + SHA256(build/manifest.json に記録)
ビルド成功 · アップロード成功(同一 RUN_ID)
# 香港 · build · build
[15:11:42]: Successfully exported: ./build/MyApp-20260604-1502.ipa
[15:11:42]: RUN_ID=hk-build-88421  GIT_SHA=a3f91c2  SHA256=9f2a…

# カナダ · upload · upload
[02:22:01]: RUN_ID=hk-build-88421  GIT_SHA=a3f91c2  ipa_sha256=9f2a…
[02:24:18]: Successfully uploaded package to App Store Connect

オンコールの鉄則:アップロード機ログに同じ RUN_ID が無ければ、成果物ミスマッチとして扱う。先に ASC を疑わない。

30 秒トリアージ:TestFlight に新しい build が無い?

まず全ログは開かないでください。下の木を 1 段だけ辿れば、該当セクションに着けます(Runbook にブックマーク推奨)。

オンコール診断木(Runbook にコピー可)
TestFlight に新 build が無い?
 ├─ アップロード機 RUN_ID ≠ ビルド機 RUN_ID(または manifest 欠落)
 │     → 坑 2 · 成果物境界
 ├─ ログに match / AppStoreDistribution / code signing identity
 │     → 坑 1 · 証明書境界
 └─ upload 成功表示だが ASC に無い / 403 / Invalid Binary(ビルド機は全緑)
       → 坑 3 · ネットワーク ID ドリフト
3 故障 · 一覧(オンコール用)
モード ログキーワード(grep) Release への影響
坑 1 証明書境界 AppStoreDistributionNo matching provisioningmatch failed ブロッキング:TestFlight / ストア提出が全面停止
坑 2 成果物境界 RUN_ID 不一致、Invalid Binaryexport_method 衝突 :誤パッケージ・昇格不可の可能性
坑 3 ID ドリフト 403、upload OK だが processing 無し、ASC ネットワーク制限 間欠ブロッキング:「謎の欠落」に見える

3 つの失敗モード(詳細)

坑 1:証明書境界エラー

30 秒判別:ビルド機の archive は緑、アップロード機が赤で、match / signing ステップで落ちている。

ログキーワード:AppStoreDistributionCould not find a matching code signing identityNo matching provisioning profiles

Release 影響:ブロッキング級 — 秘密鍵がアップロード機に戻るまで TestFlight / App Store アップロードは続行不可。

現象:ビルド機 archive 緑、アップロード upload 赤。TestFlight に新 build 無し。

典型ログ
Could not find a matching code signing identity for type 'AppStoreDistribution'
❌  Lane upload failed

根因:モデル B — ビルド機がまだ match(appstore) を実行し、Distribution 秘密鍵がアップロード機に無い。

修復:ビルド機からすべての match を削除。アップロード機だけが match を実行(rotate はアップロード機のみ・独立メンテ窓)。match readonly を参照。

坑 2:成果物境界エラー

30 秒判別:ビルド機 / アップロード機ログの RUN_IDipa_sha256 を突合。または ASC が Invalid Binary なのにビルド機に signing エラーが無い。

ログキーワード:RUN_ID 不一致、Invalid Binary、両機で 2 回 export_ipa / ExportOptions

Release 影響: — 古いパッケージ・誤 commit のアップロード、processing 停止。パイプラインは即赤にならないこともある。

根因:DC 間で .xcarchive を送っている、または両機で export している。DC 間の最小単位は SHA 照合可能な IPA であり、archive ディレクトリではない。

修復:ビルド機で 1 回だけ export_ipa + manifest.json。アップロード機は upload のみ、再 export しない。

坑 3:ネットワーク ID ドリフト

30 秒判別:Fastlane は upload 成功。ビルド・アップロードとも signing は緑。TestFlight にパッケージが無い、または ASC 403。

ログキーワード:403Successfully uploaded だが build 無し、ASC のネットワーク拒否(ビルド機ログは正常)。

Release 影響:間欠ブロッキング — 時々通り時々落ち、オンコールの忍耐を最も消耗させる。

根因:アップロード機の IPv4 と ASC IP 許可リストが一致しない(第 3 類の潜在故障)。

修復:アップロード機で毎日 curl -4 ifconfig.me を ASC と照合。ドリフトしたら許可リスト更新 + アラート。

本当に切り分けできているかの判断

ゲート、FAQ、オンコール項目を下の検収表に統合しました。分割から 1 週間後、各行が自動的に「はい」になるべきです。

デュアル Mac 分割の検収(モデル A)
検収項目 期待結果
RUN_ID 整合ビルド機 export とアップロード機 upload のログで RUN_IDGIT_SHAipa_sha256 が一致
ビルド機に Distribution 無しビルド機のキーチェーン / ログに AppStoreDistributionmatch ステップが一切出ない
アップロード機は upload のみアップロード機 lane のログに match(または resign)+ upload_to_testflight のみ。ARCHIVE SUCCEEDED は無い
成果物の形DC 間ファイルは 200MB 未満の .ipa + manifest。.xcarchive の rsync は無い
ASC IDアップロード機の現在 IPv4 = ASC 許可リスト。ビルド機 IP は ASC に未登録
Runner 分離role=ios-build-hkrole=ios-upload-ca ラベル分離。workflow は needs で直列

成熟度:いまどの段階か

障害対応は「今夜どう消すか」、段階判断は「来週アーキテクチャを変えるべきか」を決めます。下の 4 段階で、維持・修正・role split のどれが適切かを見てください。

Stage 1:単一 Mac の Fastlane

特徴:Mac runner 1 台。match + build + upload が同一 Fastfile・同一キーチェーン。先にディスク、Derived Data、GitHub Actions の課金ウィンドウを最適化し、その後 build ノード追加を検討。

結論:デュアル Mac は不要。APAC のビルドが遅いだけなら、先にbuild ノードを足す。upload の分割は後回しでよい。

Stage 2:2 台あるが role split 未実施(モデル B)

特徴:Mac が 2 台以上。複数台で match / export / upload を実行。ログに本稿の 3 境界エラーが頻出。

結論:3 台目を足しても解決しない。証明書ドリフトと成果物ミスマッチだけが増える。次は runner 数ではなくモデル A に収束すること。

Stage 3:Role split(モデル A · 本稿のゴール)

特徴:build / upload 責務分離。DC 間は RUN_ID 付き IPA のみ。match は upload ノードのみ。アップロード出口 IP 固定。

結論:✔ 検収表が安定して埋まる → build runner の横展開(APAC で並列ビルド)または upload 専用機の強化が可能。固定 IP・ノード別契約は Hashvps プランを参照(先に upload 機の ASC IP を固定し、その後 build を拡張)。

Stage 4:Multi upload node(上級)

特徴:upload リージョン複数(US / EU / APAC など)。ASC API Key と IP 戦略をリージョン別。成果物昇格とコンプライアンス監査が独立ライン。

結論:配布システムの領域。「CI 用 Mac をもう 1 台」ではない — 成果物リポジトリ・ポリシー・監査が必要で、本 Runbook の範囲外。

段階 → アクション(意思決定の閉ループ)
段階 今すぐやること
Stage 1単一 Mac を維持。ビルド・アップロード時間帯を最適化
Stage 2増設を止める。モデル A + 検収表の完走
Stage 3build を横展開。upload 専用機と監視を強化
Stage 4別プロジェクト:多リージョン配布とコンプライアンス(Fastlane パッチではない)
アップグレードトリガー(問題が既に起きていると認める)
CI ですでに「TestFlight がたまに載らない + 複数 Mac runner + match が複数ノード」が出ているなら、role split が必須の段階です。runner を増やす段階ではありません。Stage 2 のままなら、上記トリアージ木とモデル B の反パターンで lane を直し、3 台目の購入は後回しにしてください。

最終結論(この節だけで実行可能)

次の 3 条件を同時に満たすなら、本節で判断し、全文の再読は不要です:

  • すでに Mac runner が 2 台以上(または同等のマルチノード CI)
  • Fastlane で TestFlight 不安定 / アップロード失敗match failed、processing 停止、たまにパッケージ無し)
  • match複数マシンで実行された可能性がある

👉 これ以上マシンを足さない。

👉 今日からできる 3 つ:

  1. 停止:upload 以外のノードの match / sync_code_signing(署名権は upload 機のみ)
  2. 強制:DC 間は .ipa + manifest.json のみ(.xcarchive の rsync 禁止)
  3. 統一RUN_ID + GIT_SHA + ipa_sha256。アップロード前に必ず検証

上記 3 つができない場合:まだ Stage 2(モデル B)増設は故障の増幅であり修復ではない。 先に Fastfile / workflow ラベルを直し、検収表を通してから build ノード拡張を議論する。

アップロード機 Fastfile(モデル A · 抜粋)
lane :upload_only do |options|
  verify_run_id!(options) # manifest.json
  match(type: "appstore", readonly: true)
  upload_to_testflight(ipa: options[:ipa_path], api_key_path: "asc_api_key.json")
end
変更規律
lane 分割週は match を rotate しない。証明書変更は独立イベント。双 lane を止め、アップロード機だけで操作する。

よく聞かれること

ビルド機で一切署名しなくて archive できる? プロジェクト設定次第です。当社はビルド機 export でアップロード機が最終 app-store 署名する IPAを渡す(またはビルド機はコンパイル検証のみで、アップロード機で resign)。要点は match が 1 台だけであること。

match の有効期限が近いときは? アップロード機のみ、非 readonly のメンテ窓で rotate。profile が安定するまでビルド機は停止。

出張向け Runbook との違いは? 出張向けは現地 Wi‑Fi と人の操作。本稿は DC ロールと Fastlane 境界。検収表はそのまま流用可。

シリーズ:本稿は ① Runbook:デュアルクラウド Mac + Fastlane 障害対応(TestFlight 未アップロード / match failed / マルチ Mac iOS CI)。続編候補:② Build·Sign·Distribute 設計、③ モデル B 反パターン。選定は TestFlight 専用 Mac

関連記事

役割分担とノードは 香港プラン料金。 upload 専用機の要否は TestFlight 記事から。

Hashvps

Stage 2 のまま? 先に role split

upload 専用の固定 IPv4(ASC 許可リスト向け)。build は APAC で横展開。

プランを見る
期間限定