2026-04-20 レンタル Apple Silicon クラウド Mac 上の Ruby Bundler と CocoaPods 再現可能 CI
SSH で Mac mini M4 や Mac Studio を借りて iOS CI を回すチームは、依然として多くの CocoaPods リポジトリを抱えています。失敗の本質は「Pods が悪い」ではなく、再現性のない Ruby ツールチェーンです。あるジョブはシステムの pod、別のジョブは火曜に上がった Homebrew、さらに別は gem install cocoapods が ~/.gem に残したもの、という具合です。この 2026-04-20 ランブックは、レンタル Apple Silicon ホストで Bundler 管理の CocoaPods を HK / JP / KR / SG / US に揃え、キャッシュをジョブ単位のワークスペースに合わせ、マルチテナント機の NVMe を予測可能にします。併読として SwiftPM と CocoaPods の比較、CLT とフル Xcode、並列 xcodebuild を参照し、依存解決とコンパイルの前提を一致させてください。
ヘッドレスビルダーで Bundler が依然重要な理由
CocoaPods は Ruby 製です。呼び出す pod の安定性は背後の gem 集合に依存します。Bundler は Gemfile.lock でそれを固定し、十数プロダクトが 1 つのクラウド Mac フリートを共有するときに不可欠です。Bundler がないと「自分のブランチは緑」は、しばしば「最後にログインした人がグローバル CocoaPods を上げた」ことを意味します。
- 再現性 — 同じ
Gemfile.lockでリージョン横断の挙動が揃う。 - 監査性 — セキュリティがリリース間の gem 差分を追える。
- 隔離 —
bundle install --path vendor/bundleで gem を共有ホームではなくワークスペースへ。
Ruby ツールチェーンのマトリクス(3.1 / 3.2 / 3.3)
Apple Silicon の macOS イメージには新しめのシステム Ruby が載ることが多く、rbenv や asdf を重ねるチームもいます。フリートごとに 1 つ の方針を選び、インフラリポジトリにコード化してください。ビルドメタデータには ruby -v と xcodebuild -version を併記します。
| 方式 | 利点 | リスク |
|---|---|---|
| システム Ruby + Bundler | 新規 SSH ホストでの立ち上げが速い | OS アップデートで Ruby が上がる可能性。plist や CI 環境で固定 |
| ユーザー単位 rbenv | パッチレベルまで厳密 | launchd ジョブは rbenv shim を明示的に読み込む必要 |
| asdf + .tool-versions | Ruby と Node などを 1 ファイルで管理 | 初回インストール時間が長い |
Gemfile とロックファイルの規律
Gemfile と Gemfile.lock の両方をコミットします。cocoapods は検証済みマイナーに固定し、プラグイン(例: cocoapods-acknowledgements)も明示します。CI では次を推奨します。
bundle config set --local deployment 'true'
bundle config set --local path 'vendor/bundle'
bundle install --jobs 4 --retry 3
pod install の前に bundle check を走らせ、Gemfile を変えたのに Gemfile.lock を更新し忘れた場合に早期失敗させます。
bundle exec pod install(--deployment を付けるタイミング)
常に bundle exec pod install を使います(Bundler にロックファイルを厳格適用させるなら bundle exec pod install --deployment)。本番パイプラインで素の pod を叩くのは金曜夜の非決定性を招きます。CI キャッシュには決定的な CP_HOME_DIR を渡すか、公式推奨のキャッシュ環境変数をジョブディレクトリ配下にスコープします。
~/Library/Caches/CocoaPods に書くと部分ダウンロードが起き得ます。$CI_JOB_ID やクローンパス単位で隔離してください。
キャッシュ、Pods/、ワークスペース配置
Pods/ と *.xcworkspace の生成は、そのビルドのクローン配下に閉じます。短命ワークスペースでは Gemfile.lock + Podfile.lock のチェックサムが一致するときだけ vendor/bundle と specs キャッシュを跨ぎで保持し、ズレたら積極的に無効化します。古い specs キャッシュはネットワーク問題に見える曖昧な解決エラーを招きます。
NVMe とマルチテナント衛生
CocoaPods のダウンロードは 1 回で 数百 MB に達することがあり、複数 Podfile を持つモノレポでは倍増します。512 GB 共有ホストでは シミュレータとアーカイブ掃除 のディスク指針とセットで運用してください。pod ステップで 70% を超えることが常態なら、レーン分割か 料金ページ から 1 TB / 2 TB ノードへ移行し、パイプライン途中の無限プルーニングに頼らないでください。
リージョナルビルダー:CDN と遅延
シンガポール や 東京 から specs CDN へは通常高速ですが、企業プロキシや TLS 検査でリトライが増えます。bundle install にリトライを設定し、ミラーやキャッシュプロキシが必要ならリージョンごとに例外を文書化し、香港 と 米東 の挙動を揃えます。
関連ランブック
SwiftPM へレーンを移すなら、キャッシュサイズとロック意味を SwiftPM の解決とキャッシュ と比較してください。Pods 解決後の署名は既存の自動/手動署名記事に戻ります。Bundler はプロビジョニングプロファイルの代替ではありません。
FAQ:クラウド Mac の Bundler + CocoaPods
| 質問 | 実務的な答え |
|---|---|
| Homebrew の CocoaPods は? | CI では避け、Bundler 管理の gem にし、更新はコードレビュー経由にします。 |
| Bundler 2 と 1 は? | メジャーを統一します。開発機と CI の不一致は「ローカルでは動く」典型原因です。 |
| CI で Pods/ をコミット? | チーム方針です。完全にコミットするか毎回生成するか、中途半端は避けます。 |
まとめ:CocoaPods を別のコンパイラツールチェーンのように扱い、版を固定し、キャッシュをスコープし、共有 SSH ビルダーでは常に bundle exec を通してください。