2026 Mac クラウド CI:SPM と Package.resolved のロック方針、いつ -disableAutomaticPackageResolution を強制すべきか(FAQ)
共有ビルダーで「ノートでは通るが CI がランダムに欠ける」状態は Xcode より SwiftPM の自動書換やロック未投入が原因であることが大半です。この記事は 2026 年に Mac クラウドを VPS 同様に扱う担当者へ、四類の痛み、三段決定表、並列係数早見表、五步 Runbook、三 KPI、FAQ、そしてサイト内の出口・キュー・冷温記事への導線をまとめたものです。
目次
1. 痛みの分類:ロック欠如、無人環境でのグラフ書換え、共有キャッシュ汚染、出口誤認
共有 Mac ビルダーでは自動解決がリンク段 flaky を増やします。
- lockfile 未ポリシー:推移依存がコミットされず二度目の CI が汚染で落ちる。
- 自動解決が残った Archive:main と PR で別グラフになり bisect が壊れる。
- キャッシュ根を共有した:半成品モジュールで linker が曖昧化。ビルドキューとディスク余裕 でスロット契約。
- SPM が遅いと compile のせいにした:TLS/DNS で resolve のみ不安定。出口ガイド でログ単体化。
missing package product/checksum は resolve、resolve 後の linker は IO/キューとして束ねます。
2. workspace・xcodebuild・共有ノードの三段表
Xcode が実際に読む Package.resolved の場所だけを門禁してください。
| 構成 | Package.resolved コミット | -disableAutomaticPackageResolution | 独立 resolve Job |
|---|---|---|---|
| 単一リポ Archive(既定) | 必須(PR+保護 main) | archive/test すべて | 推奨:resolve プローブを前段に分離 |
| 同一ノードで複数 scheme 並列 | ブランチ単位で必須/暗黙共有禁止 | 必須+スロット別 -derivedDataPath |
resolve と compile の IO 峰を分ける |
| SwiftPM CLI | 必須/swift package resolve --force-resolved-versions |
xcodebuild フラグは非該当 | 私設 Git なら SSH ウォームを別 job で |
| 実験ブランチで依存だけ上げる | マージ前にロック差分を明示 | 隔離キャッシュ上のみ一時解除可 | Unix ユーザとルートを分離 |
3. 並列 resolve 係数の早見
| 変数/フラグ | 開始レンジ(8〜12 並列スロット想定) | 絞る・止める条件 |
|---|---|---|
SWIFT_PACKAGE_MANAGER_PARALLEL_FETCH_LIMIT |
8〜12(CPU と帯域で再調整) | 空き容量 < 15% やキューアラート点灯時 |
XCODE_PACKAGE_RESOLVE_PARALLELISM=YES |
resolve プローブだけ | Archive と同ボリューム同時満載時 |
-scmProvider system |
企業 Git+ssh-agent 統合時 | known_hosts 自動化前は認証地獄 |
-disableAutomaticPackageResolution |
ロック運用下の compile/archive/test | ロック再生成の隔離 job 以外では付与 |
XCODE_PACKAGE_RESOLVE_PARALLELISM や並列係数は resolve 側へ閉じ、Archive 峰と離します。
4. 五步 Runbook とシェル例
- lockfile をバージョン管理ポリシーへ格上げ:マニフェストに手を入れた PR は必ず
Package.resolvedの説明を添える。 - resolve プローブをコンパイルより前に置く:
xcodebuild -resolvePackageDependenciesを同じ scheme/宛先で走らせ、ログを成果物化する。 - パスをスロット契約で固定:
DERIVED_DATA_PATHと-derivedDataPathを一致させ、archive では-disableAutomaticPackageResolutionを常設。私設パッケージなら-scmProvider system。 - 夜間スモーク:重い依存で出口を一度通す。
- 同一コミット三回:resolve/link の再現性を比較。
#!/bin/zsh
set -euo pipefail
export DERIVED_DATA_PATH="/Volumes/ci/slot${JOB_SLOT:-0}/DerivedData"
xcodebuild -resolvePackageDependencies -scheme App -derivedDataPath "$DERIVED_DATA_PATH" -destination 'generic/platform=iOS'
xcodebuild -scheme App -derivedDataPath "$DERIVED_DATA_PATH" \
-disableAutomaticPackageResolution -scmProvider system \
-destination 'generic/platform=iOS' archive
set -euo pipefail
export DERIVED_DATA_PATH="/Volumes/ci/slot${JOB_SLOT:-0}/DerivedData"
xcodebuild -resolvePackageDependencies -scheme App -derivedDataPath "$DERIVED_DATA_PATH" -destination 'generic/platform=iOS'
xcodebuild -scheme App -derivedDataPath "$DERIVED_DATA_PATH" \
-disableAutomaticPackageResolution -scmProvider system \
-destination 'generic/platform=iOS' archive
5. 三つの KPI(resolve/ロック/失敗分類)
- resolve が E2E の約 20% 超え(大規模でコード変更なし)→ 出口優先。
- ロック不変成功が週 2 件超え→ 自動解決の抜け穴。
- ログ分類の一貫性:checksum は resolve/link は IO。
6. ディスク親和と出口との接続
resolve 成功後にだけ linker が悪化するなら NVMe 争奪を疑い、冷温・アフィニティ と出口ガイドへ戻ります。
7. FAQ
ロック消失? CI で検知。多リポ user 共有? NG。Linux only? iOS は macOS が真実。
8. 結び:VPSMAC ベースラインへの橋渡し
共有キャッシュだけに頼るとロックの真実性が崩れやすく、不透明なキャッシュ運用だけでは出口と門禁が練りづらいままです。低並列で resolve/archive を分けられる VPSMAC の Apple Silicon は Runbook 化の下地になります。