2026年 グローバルチームの XCTest 分片とマルチリージョン物理 Mac:ビルド成果物は「単一リージョン産出」か「分片の近傍実行」か?Artifact 越境コストと Runner ルーティング閾値の意思決定マトリクス(コピペ可能パラメータ+FAQ)
越境チームが XCTest を並列化するとき、ビルド成果物を 1 ゾーンに集約して配るか、シャードごとに近傍でビルドしてテストするかで、転送コスト・再現性・キュー待ちのトレードオフが変わります。本稿では 3 枚の意思決定マトリクス、7 ステップの Runbook、コピペ用パラメータと FAQ で設計レビューにそのまま持ち込める形に整理しました。
1. 痛みの分解:なぜ「Artifact だけ」では決められないか
XCTest 分片は Runner 台数とネットワーク経路の両方に敏感です。プライベートレジストリや依存ミラーと同区の物理 Mac に寄せる議論は、iOS/macOS パイプラインのレジストリ配置記事とセットで読むと、取得フェーズとテストフェーズの責務分離が明確になります。
- 越境転送と尾部遅延:.xcarchive/圧縮 .xcresult を毎シャード・毎コミットで引き回すと、オブジェクトストアの出口と TLS 往復が支配的になり、分片の wall-clock が伸びます。
- ビルドハッシュの一貫性:単一産出は再現性が高い一方、リージョン別ビルドは Xcode/SDK の微差でテストスキップやフラップの原因になり得ます。どちらを正とするかを事前に宣言します。
- Runner キューとコスト:物理 Mac プールを増やすほど待ち時間は減りますが、ライセンスと電力の総額は上がります。3 年 TCO で見ると、購入かマルチリージョンのレンタルかのマトリクス記事と同じ軸で「転送コスト vs 追加ノード」比較がしやすくなります。
2. 成果物戦略マトリクス:単一リージョン産出 vs 分片近傍ビルド
「1 回ビルドして配る」か「シャードごとに近傍でビルドして即テスト」かを、チーム規模ではなく転送バイト×頻度×一貫性要件で切ります。
| シナリオ | 単一リージョン産出+配布が有利 | 分片近傍ビルド+テストが有利 |
|---|---|---|
| 成果物サイズ(圧縮後 P95) | おおよそ 1.8GB 未満で同一リージョン内シャードに収まる | おおよそ 3.2GB 超または大洋横断が支配的 |
| 1 日あたりの配布回数 | メインブランチ中心でおおよそ 12 回未満 | PR 毎・シャード毎でおおよそ 28 回超の越境転送 |
| 再現性ポリシー | 「単一の署名済みバイナリ」を唯一の正とする | リージョン別に SDK 差を許容しテストのみ揃える |
3. Runner ルーティング閾値マトリクス
ラベル設計は「地域」「Xcode バージョン」「シャード番号」の順で固定し、メトリクスが閾値を超えたらだけプールを増やします。
| 指標 | 観察ウィンドウ | 追加の Runner プール/経路変更を検討する目安 |
|---|---|---|
| ジョブキュー待ち | 直近 2 週間の中央値 | おおよそ 4 分を超えるプールが 1 つでもある |
| Artifact 取得+展開(セットアップ) | P95 | テスト実行より長く、P95 がおおよそ 7 分超 |
| RTT(Runner→オブジェクトストア) | 平日日中の P95 | おおよそ 95ms 超かつ越境転送単価が月次予算のおおよそ 6% 超 |
4. Artifact サイズ×頻度と越境コスト感
金額はクラウド課金と社内ネットの実測に置き換えてください。ここでは「どのセルで CFO が介入するか」の目安を揃えます。
| 圧縮後サイズ帯 | 日次シャード配布の目安 | 推奨アクション |
|---|---|---|
| 〜 900MB | 〜 18 シャード/日まで | 単一産出+同一大陸の読み取り専用バケット |
| 900MB 〜 1.8GB | おおよそ 8 〜 12 シャード/日 | デルタ同期または差分レイヤー(テスト対象モジュールのみ) |
| 1.8GB 超 | PR 毎フル配布 | リージョン別ビルド、またはテストを UI/Unit 単位でさらに分片 |
5. 7 ステップ Runbook
- 計測を先に固定する:セットアップ(取得・展開)とテスト本体の wall-clock を分け、ログに「shard id」「region」「artifact bytes」を必ず出す。
- 単一産出の仮説を置く:同一コミットから 1 ビルドし、オブジェクトストアのチェックサムを Runner への入力として渡す。
- 越境が支配的なら分割:P95 転送がテスト実行のおおよそ 40% を超えたら、モジュール分割またはリージョン別ビルドに切り替える。
- Runner ラベルを 3 層で統一:region / xcode-version / shard-index。data-residency が必要なら第 4 層を追加。
- Simulator とランタイムをプール単位で固定:フラップより待ちのほうが安いため、バージョンのばらまきを禁止。
- キューが閾値を超えたら経路を疑う:まずオブジェクトストアの出口と TLS を直し、その後でスケールアウト。
- 四半期レビュー:転送単価・ノード単価・人件費(オンデマンド待ち)を 1 枚のシートに載せ、マトリクスを更新する。
6. コピペ可能パラメータ(xcodebuild/環境変数)
実プロジェクトのスキーム名・デスティネーションは置き換えてください。分片は「テスト一覧を事前に分割」する方式が追跡しやすいです。
# 例:シャード 2 / 5 のユニットテストのみ(プレースホルダー)
export SHARD_INDEX=2
export SHARD_TOTAL=5
export TEST_TARGET="MyAppTests"
xcodebuild test \
-scheme "MyApp" \
-destination 'platform=iOS Simulator,name=iPhone 16,OS=18.2' \
-only-testing:"${TEST_TARGET}/MyAppTestsClassOne" \
-only-testing:"${TEST_TARGET}/MyAppTestsClassTwo" \
-resultBundlePath "build/Shard-${SHARD_INDEX}.xcresult" \
-parallel-testing-enabled YES \
-parallel-testing-worker-count 4
Runner 側メタデータ(例)
CI_RUNNER_REGION=ap-northeast-1 · XCODE_VERSION=16.2 · ARTIFACT_URI=s3://bucket/path/commit.sha.tar.zst
7. 引用用の閾値・数値(設計書・SLO にそのまま)
- 圧縮後 Artifact の週次 P95 が おおよそ 1.8GB 未満なら単一産出+同一大陸配布を既定にしやすい。
- 越境転送が 1 日おおよそ 28 回/シャードを超えると、転送コストが追加 Mac ノードより上振れしやすい。
- セットアップ P95 が おおよそ 7 分超でテストより長い場合は、ネットワーク経路か成果物分割を先に直す。
8. Mac mini で CI を安定させる理由
XCTest の分片は「同じ Xcode/Simulator バージョンで揃える」ほど結果が安定します。Apple Silicon の Mac mini は、ユニファイドメモリと低発熱で長時間のテスト実行に向き、待機電力がおおよそ 4W 程度と小さく、複数台をリージョン別コロケーションで置いても運用負荷が跳ねにくいのが実務上のメリットです。
macOS は Xcode・シミュレータ・コード署名検証まで一貫したスタックで動き、Gatekeeper や SIP も含めて攻撃面を抑えやすいため、無人 Runner を増やすほど「環境ドリフト」に悩まされにくくなります。
グローバルに XCTest を回すなら、まず各リージョンで同世代の Mac mini を揃え、転送とキューのどちらを先に潰すかを本稿のマトリクスで決めたうえで、必要な台数を足すのが最短です。今すぐ手元のパイプラインに載せ替えたい場合は、ZoneMac のサービス概要から構成を確認できます。
9. まとめ
単一リージョン産出は再現性と運用の単純さ、分片近傍ビルドは転送の削減と尾部遅延の圧縮というトレードオフです。数値(サイズ帯・頻度・キュー・RTT)をログに出せば、本稿のマトリクスに沿って意思決定を再開できます。
設計レビューでは「成果物の正」がどこにあるか、および Runner ラベルとメトリクス閾値をセットで貼ると、越境チームでも合意が取りやすくなります。
10. FAQ
単一リージョン産出の Artifact を各シャードへ配るのはいつ合理的ですか?
圧縮後サイズの週次 P95 がおおよそ 1.8GB 未満で、同一大陸内の Runner に収まり、越境転送が支配的でないときです。P95 がおおよそ 3.2GB を超えるなら、分割転送かリージョン別ビルドを検討してください。
Runner ラベルはどの粒度で切ればよいですか?
region・xcode-version・shard-index の 3 層を基本とし、法域要件があるテスト資産には data-residency を追加します。キュー中央値がおおよそ 4 分を超えたプールから優先的に水平展開します。
xcodebuild test の分片は環境変数だけで足りますか?
足りません。テスト一覧の分割ポリシー(クラス/ファイル/ターゲット)と、Runner に固定する Xcode/Simulator のバージョンをセットで定義してください。本文のコピペ断片をテンプレート化し、リポジトリにスクリプトとして残すのが安全です。
Mac mini M4クラウドサービスのご案内
開発者向けに最適化された高性能ビルド環境を、クラウド上でご利用いただけます。