← 技術ブログに戻る

Xcode 26 Beta テストコスト急増?
Runner 分離プレイブックで解決

リモート Mac mini 上の Xcode 26 beta CI と self-hosted runner 二系統分離
本番は Xcode 16 固定、beta は専用 Runner——WWDC 後の iOS CI はディスクを分ける。

結論:WWDC 26 後に CI で Xcode 26 beta を試すなら、main の workflow を macos-latest に差し替えて祈るのではなく、リモート Mac 上で Runner を 2 レーンに分離するのが正解です。本番は Xcode 16 安定版に固定し、beta は専用 label と専用 DerivedData ディレクトリで走らせます。

3 つの鉄則:① 本番 job では sudo xcode-select を禁止;② beta と本番の -derivedDataPath は物理的に分離;③ iOS 27 Simulator runtime は beta Runner に一度だけプリインストールし、job ごとのダウンロードをやめる。

本文の範囲:「WWDC 後に CI が遅くなる理由」(WWDC26 iOS CI 遅延の解説)は扱いません。48 時間で実行できる Runbook だけを書きます。

6 月 10 日の記事で触れた通り、WWDC 後の iOS CI の揺れはキャッシュ消去・SDK の肥大化・ホスト Runner の混雑が重なった結果です。1 週間経ち、Slack の質問は実務寄りに変わりました——「beta はどの Mac に入れる?」「1 台で 2 つの Xcode は無理?」「main が赤くなったら誰の責任?」。答えはシンプルです:リモート Mac mini を self-hosted runner にして、beta 検証と App Store リリースを完全に分ける。 self-hosted 未導入なら先に iOS CI 高速化ガイド を。ノード別の月額比較は 6 拠点 Runner TCO を参照してください。

1)よくある誤解:1 台 Mac で混在 ≠ 節約

WWDC 直後に多い判断ミスは、CI 用 Mac が 1 台だけの環境に Xcode 16 と 26 beta を両方入れ、workflow の xcode-select -s で切り替えるパターンです。月額 1 台分に見えて、実際のコストはこう跳ね上がります:

  • 競合:並列 job 実行時、後から走る xcode-select がグローバルパスを書き換え、本番 Archive が beta コンパイラを使う事故が起きる。
  • キャッシュ汚染:~/Library/Developer/Xcode/DerivedData を共有すると Swift module の版が混ざり、ローカル再現不能な「幽霊エラー」が CI だけで赤くなる。
  • ディスク争奪:Xcode 2 セット + Simulator runtime 2 セットで 80GB 超は普通。16GB メモリ機は beta のフルビルド中に swap し、全 job が遅くなる。
判断の一文: main を毎日更新し TestFlight ペースを守るチーム → 本番 Runner と beta Runner は必ず分離。月 1 回リリースで beta は nightly だけ、という小規模チームだけが単機の時間分割を検討できる——それでも DerivedData は分けること。

2)デュアル Runner 構成:label プールと workflow 分流

最小構成は次のとおり——リモート Mac mini M4 を 2 台(または本番 1 台 + beta 用の日割りトライアル機):

RunnerGitHub LabelXcode 版担当 job
本番機 Aself-hosted, macos, ios-prodXcode 16.4(固定)main Archive、TestFlight、リリース tag
Beta 機 Bself-hosted, macos, xcode26-betaXcode 26 betaios-27-* ブランチ、nightly 適応、API 探索

workflow 側は runs-on でハード分流。beta ブランチが ios-prod label を触るのは禁止

.github/workflows/ios-prod.yml — 本番 lane
name: iOS Production CI
on:
  push:
    branches: [main, release/*]
jobs:
  archive:
    runs-on: [self-hosted, macos, ios-prod]
    env:
      DEVELOPER_DIR: /Applications/Xcode_16.4.app/Contents/Developer
      DERIVED_DATA: /var/ci/deriveddata/prod
    steps:
      - uses: actions/checkout@v4
      - name: Build & Archive
        run: |
          xcodebuild -scheme MyApp -configuration Release \
            -derivedDataPath "$DERIVED_DATA" \
            -archivePath build/MyApp.xcarchive archive
.github/workflows/ios-beta.yml — beta lane
name: iOS 27 Beta Adapter
on:
  push:
    branches: [ios-27-*, feature/siri-ai-*]
  schedule:
    - cron: '0 2 * * *'   # nightly、merge をブロックしない
jobs:
  beta-build:
    runs-on: [self-hosted, macos, xcode26-beta]
    continue-on-error: true   # beta の赤は main を止めない
    env:
      DEVELOPER_DIR: /Applications/Xcode_26_beta.app/Contents/Developer
      DERIVED_DATA: /var/ci/deriveddata/beta
    steps:
      - uses: actions/checkout@v4
      - run: xcodebuild -scheme MyApp -sdk iphonesimulator build \
          -derivedDataPath "$DERIVED_DATA"

Runner 登録と label 命名は GitHub self-hosted runner ドキュメント を参照。label は契約——誰が label を変えたかで責任が決まります。

3)リモート Mac への Xcode 26 beta インストールと共存

ベアメタルリモート Macなら、2 つの Xcode を /Applications に並べて置き、ディレクトリ名で版を区別できます。beta が安定版を上書きしないように:

  1. Apple Developer Downloads から Xcode 26 beta(.xip)を取得し、SSH でリモート Mac にログインして /Applications/Xcode_26_beta.app に展開。
  2. 本番機は DEVELOPER_DIR 環境変数のみ受け付け、workflow に絶対パスを書く。job 内の sudo xcode-select -switch は禁止
  3. 初回インストール後、xcodebuild -runFirstLaunch とライセンス同意を手動で 1 回実行——これを毎 CI job に入れない。
  4. iOS 27 Simulator runtime は beta 機にプリインストール:Xcode → Settings → Platforms で一括インストール;workflow から -downloadPlatform ステップを削除。

ローカル開発でも複数 Xcode を使うチームは、Xcode ビルドが遅い問題 のハイブリッド運用が参考になります。手元で Swift を書き、重いコンパイルはクラウド M4 に任せる——beta 適応も同じで、16GB ノートに beta のインデックスとフルビルドを載せないこと。

4)DerivedData / Pods / SPM の 3 系統キャッシュ分離

WWDC シーズンにキャッシュが死ぬ根本原因はコンパイラと module 形式の変更であって、「キャッシュが壊れた」わけではありません。分離方針:

表:本番 vs beta Runner のキャッシュパス(固定パス推奨、job 跨ぎで永続)
キャッシュ種別本番パスBeta パス備考
DerivedData/var/ci/deriveddata/prod/var/ci/deriveddata/betaworkflow で -derivedDataPath 固定
CocoaPods/var/ci/cocoapods/prod/var/ci/cocoapods/betaCP_HOME_DIR または --deployment
SPM/var/ci/spm/prod/var/ci/spm/betaclonedSourcePackagesDirPath
ModuleCacheDerivedData 親ディレクトリに従属独立 beta ツリーデフォルト ~/Library 共有禁止

actions/cache は WWDC シーズンには足りないことが多い:Xcode メジャー切替で cache key が全滅し、数 GB の DerivedData をアップロードするネットワーク時間はローカルディスクより損になりがち。self-hosted の価値はディスクが job を跨いで生き残ること——2 回目の beta build で初めて 20 分超から 10 分台に戻ります。Flutter の 3 キャッシュ詳細は Flutter iOS CI、署名と TestFlight は iOS CI 高速化ガイド の Signing 章を参照。

Runner 初期化スクリプト(1 回だけ実行)
sudo mkdir -p /var/ci/{deriveddata,cocoapods,spm}/{prod,beta}
sudo chown -R $(whoami) /var/ci
# ディスク監視:DerivedData 膨張時は lane 単位でクリーン、ディスク全体 rm は避ける
du -sh /var/ci/deriveddata/*

5)典型トラブル:beta クラッシュ、SDK 肥大、キーチェーン混線

現場でよく見る事故と、その予防策:

  • beta の赤が merge を止める:beta workflow に continue-on-error: true を設定し、required status check にしない。beta が不安定なのは想定内で、エンジニアの怠慢ではない。
  • 本番が beta SDK を使う:Archive ログで DTXcodeDEVELOPER_DIR を確認;prod job 冒頭で test "$DEVELOPER_DIR" = "/Applications/Xcode_16.4.app/Contents/Developer" をアサート。
  • キーチェーン / Match 証明書の混線:2 台の Runner はそれぞれ独立 login keychain;Fastlane match の git_url は共有可能だが、証書インポート用 keychain パスワードは機ごとに分離。Apple の Xcode サポートマトリクス も参照。
  • ディスク満杯:beta DerivedData + 2 セット Simulator runtime の増殖は速い;beta 機は 512GB SSD 推奨、beta ツリーで 14 日以上未アクセスの subfolder を週次 cron で削除。
  • 並列 Archive で OOM:M4 16GB で Archive 2 本同時は swap 地獄;本番機 concurrency は 1、beta 機は 1–2 で調整。

6)サンプル:Runner 分離前後の同一リポ P50(SLA ではない)

Swift/UIKit + CocoaPods の中規模プロジェクト、main 本番 job の WWDC 後 1 週目比較——未分離(全員 beta 昇格)vs デュアル Runner(本番は Xcode 16 のまま):

指標未分離(main を beta 化)デュアル Runner 分離
main Archive P50~42 min~11 min(WWDC 前と同等)
beta 適応 job P50(prod と同一台を奪い合い)~22 min(初週フル、2 週目 ~12 min)
main の beta 誤爆失敗率高(コンパイラ/キャッシュ混在)ほぼ 0
必要 Mac 台数1 台(一見お得)M4 2 台、または本番 1 + beta 日割り

数値はリポジトリ依存。自社 workflow で 48 時間 A/B を取ってください。本質は「どれだけ速くなるか」ではなく、main が beta の代金を払わないことです。

7)48 時間ロールアウトチェックリスト

  1. Day 0 午前:本番 Xcode 版をロックし、prod workflow に DEVELOPER_DIR を固定;main への「Xcode 26 昇格」CI 変更のマージを禁止。
  2. Day 0 午後:リモート Mac mini(または 48h 日割り)を xcode26-beta Runner として登録;Xcode 26 beta + iOS 27 runtime をインストール。
  3. Day 1:/var/ci/... キャッシュディレクトリを作成;beta workflow の初回フルビルドを通す;prod job への影響がないことを確認。
  4. Day 2:beta workflow を nightly + ios-27-* ブランチトリガーに変更;GitHub branch protection から beta check の required を外す。
  5. 受け入れ:main Archive を 3 連続 < 15 min(プロジェクト次第);beta job 失敗で Slack @channel しない。

2 台目の月額が妥当か迷うなら、日割り beta 機で iOS 27 適応 spike を終えてから本契約を判断——TCO テンプレは MacBook Pro vs クラウド Mac 判断。ツールチェーンが macOS 独占な理由は Xcode ツールチェーン独占の解説 を参照。

8)よくある質問(15 件)

1. 1 台のリモート Mac に 2 つの Xcode は入る? 入ります。別 .app 名で共存;CI では DEVELOPER_DIR を指定し、グローバル xcode-select に頼らない。

2. beta Runner は 24GB 必須? 単一 scheme の中規模なら 16GB M4 で足りることが多い;複数 target 並列 Archive は 24GB 推奨。

3. 本番機でたまに beta job を回せる? 非推奨。時間分割でも DerivedData は最低限分離;できれば物理分離。

4. ホスト macos-latest が beta Runner の代わりになる? ならない。ephemeral ディスクは毎回コールドスタート、WWDC シーズンの bootstrap だけ 15 分超、永続キャッシュなし。

5. actions/cache で足りる? メジャー版切替で key 無効;大 DerivedData の up/down はローカルディスクに劣る。

6. beta 不安定で CI が真っ赤? 想定内;beta lane は optional にし、main merge をブロックしない。

7. prod が beta コンパイラを使っていない確認方法? Archive ログの DTXcode、または job 冒頭で DEVELOPER_DIR をアサート。

8. Simulator runtime を毎 job ダウンロード? しない。beta 機に 1 回プリインストール、workflow から download 削除。

9. 2 台の Runner は別リージョンでも OK? OK。本番はチームに近いノード;beta は prod と同区画の方が ops が楽。

10. OpenClaw で beta Runner を管理できる? webhook トリガーは可能;Gateway 詳細は割愛。CI 登録は OpenClaw CI Runner FAQ

11. 日割り beta 機で足りる? 適応 spike なら十分;nightly を長期運用なら月額の方が安い。

12. DerivedData はどのサイズでクリーン? lane 単位 40GB 超なら scheme 別クリーン;本番 lane は慎重に、beta を優先削除。

13. Swift 6 並行チェックが厳しくなったら? beta lane だけ strict フラグを有効化、prod は現状維持で段階移行。

14. WWDC 記事との関係は? あちらは「なぜ遅いか」、こちらは「Runner をどう分けるか」。

15. 48h 以内に 2 台必須? main が beta に触れないなら prod 1 台で可;beta 適応は日割り機が来てから lane を開く。

Beta は試せ、本番は絶対に安定させろ

WWDC 後いちばんコスパが良い構成は、月額本番 Runner 1 台 + オンデマンド beta 機 です。本番 Mac mini M4 を 7×24 で TestFlight ペースを守り、beta は日割りで iOS 27 適応を試し、結果を見て本契約を判断。Nuvcloud のベアメタルはディスク独占、DerivedData が job を跨いで生存;M4 16GB で大半の iOS Archive は十分、24GB は複数 scheme 並列向け。低消費電力・ファンレスで、無人 CI に向きます。

WWDC 後にXcode 26 beta CI を組みたいが、main を実験場にしたくないなら、 Nuvcloud クラウド Mac mini M4 が最も安い分離の起点です—— プランを今すぐ確認 、48 時間で beta / 本番 Runner を切り分けましょう。

LIMITED 料金を見る