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 取捨、命令列工具與完整 Xcode,以及 並行 xcodebuild 工作,讓相依解析與編譯步驟維持同一套假設。
為何在無頭建置機上仍需要 Bundler
CocoaPods 本質是 Ruby 程式。你呼叫的 pod 執行檔,穩定性取決於背後的 gem 組合。Bundler 透過 Gemfile.lock 把這組版本釘死——這正是十幾支產品團隊共用一套雲端 Mac 機隊時最需要的保障。沒有 Bundler,「我這條分支綠了」往往等同於「誰最後登入就把全域 CocoaPods 升了一階」。
- 可重現 — 同一份
Gemfile.lock在各區域得到一致的解析行為。 - 可稽核 — 安全團隊可以比對兩次釋出之間的 gem 版本差異。
- 可隔離 —
bundle install --path vendor/bundle把 gem 放在工作區,而不是共享 home。
Ruby 工具鏈矩陣(3.1 / 3.2 / 3.3)
Apple Silicon 上的 macOS 映像常附較新的系統 Ruby;也有團隊疊加 rbenv 或 asdf。請為整個機隊選擇 唯一 政策,並在基礎設施儲存庫裡寫成設定。把精確的 ruby -v 與 xcodebuild -version 一併寫進建置中繼資料。
| 作法 | 優點 | 風險 |
|---|---|---|
| 系統 Ruby + Bundler | 全新 SSH 主機啟動快 | 系統升級可能抬升 Ruby;以 plist 或 CI 環境變數釘選 |
| 每使用者 rbenv | 補丁級版本精確 | launchd 工作必須明確載入 rbenv shim |
| asdf + .tool-versions | 單一檔案同時管理 Ruby、Node 等 | 首次安裝時間較長 |
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,或使用 CocoaPods 官方建議、且範圍限定在工作目錄下的快取環境變數。
~/Library/Caches/CocoaPods 且不做命名空間隔離,可能出現半成品下載——請依 $CI_JOB_ID 或依儲存庫複製路徑隔離快取。
快取、Pods/ 與工作區版面
把 Pods/ 與 *.xcworkspace 的產生限制在該次建置對應的複製路徑內。在短命工作區上,僅當校驗和與 Gemfile.lock + Podfile.lock 一致時,才在多次執行之間快取 vendor/bundle 與 CocoaPods specs 快取;一旦不一致就要積極失效——過期的 specs 快取會引發看似網路問題的模糊解析錯誤。
NVMe 與多租戶衛生
CocoaPods 下載可能單次就增加 數百 MB;含多個 Podfile 的 monorepo 會成倍放大。在 512 GB 共享主機上,請把解析階段與 模擬器與封存清理 的磁碟指引結合使用。若 pod 步驟期間磁碟經常超過 70%,請拆分 lane 或透過 定價頁 升級到 1 TB / 2 TB 節點,而不是在管線中段無止境地臨時清理。
區域建置機:CDN 與延遲
從 新加坡 或 東京 存取 specs CDN 通常很快,但企業代理或 TLS 檢查會增加重試。為 bundle install 設定重試參數;若安全團隊要求鏡像或快取代理,請依區域記錄例外,讓 香港 與 美東 行為一致。
相關手冊
若你把 lane 遷向 SwiftPM,請用 SwiftPM 解析與快取 比較快取體量與鎖語意。Pods 解析完成後的簽章流程,請回到你們既有的自動/手動簽章文章——Bundler 不會取代描述檔。
常見問題:雲端 Mac 上的 Bundler + CocoaPods
| 問題 | 實務答案 |
|---|---|
| 能否用 Homebrew 安裝 CocoaPods? | CI 不建議——請用 Bundler 管理 gem,讓升級走程式碼審查,而不是意外的套件版本跳動。 |
| Bundler 2 與 1 怎麼辦? | 統一主版本;開發筆電與 CI 不一致是常見的「本機能跑」來源。 |
| CI 要不要提交 Pods/? | 團隊政策——要么全提交達成封閉建置,要么每次都產生;不要半提交。 |
結論:把 CocoaPods 當成另一種編譯工具鏈——固定版本、限定快取範圍,並在共享 SSH 建置機上始終透過 bundle exec 呼叫。