在跨區 Mac mini M4 並聯叢集跑 Xcode 時,瓶頸常常不是單核編譯,而是「Parallel Testing 開著、destination 愈切愈細、Simulator 同時開太多」,最後與 Derived Data、截圖暫存一起把 1TB/2TB 磁碟預算燒穿。

本文給 iOS/macOS CI 負責人一份可貼進 runbook 的決策表:先用參數表對齊 -parallel-testing-enabled、單次工作階段的 destination 數量Simulator 並發,再把建置鎖Derived Data 路徑磁碟清理閾值寫進同一張驗收清單。排程與檔案扇出可銜接站內 Nomad 親和與建置鎖矩陣watchman/磁碟節流矩陣;製品同步則對齊 rsync 決策矩陣

xcodebuild test 參數表(起點):下列為「單節點」建議區間,跨區時請再乘以網路延遲與 CoreSimulator 同步成本;1TB 機型應取表格下半保守列。

CI 情境 -parallel-testing-enabled destination 數量(單次 invocation) Simulator 並發(同機同時 boot)
主線/PR 煙測 YES 1(單一 platform=iOS Simulator 目的地) 1–2
夜間多裝置 shard YES 2–4(依 scheme 切片;避免同一 Derived 樹競寫) 2–3(受 RAM 與磁碟 IO 約束)
1TB 節點保守模式 YES 或 NO(若套件極大可先關閉換穩定) 1 1(並以佇列串接)
並發預算怎麼估:每個 Simulator 實例除了資料層,還會在測試過程寫入 xcresult、截圖與暫存;parallel-testing-enabled YES 會讓 XCTest 工作進程與模擬器成對放大。請以「同機同時 boot 上限」為硬欄杆,再回推允許的 destination 數。

建置鎖

並行測試不取代「誰能寫入正式產物樹」的規則。對 Archive、簽章目錄或共享製品根目錄,仍應以 flock(或排程器單寫入者/max_parallel=1 擇一為權威)包住提升步驟;鎖檔放在本機 SSD,避免在網路卷宗上長持鎖。若 CI 同時觸發 xcodebuild test 與 promote,請把測試工作目錄與 promote 目錄分樹,否則測試過程的暫存檔會與產物鎖競態。

LOCK_FILE="/var/tmp/xcode-promote.lock"
flock -n "$LOCK_FILE" bash -c '
  xcodebuild -scheme Release -configuration Release archive ...
  rsync -a --delete "$ARCHIVE_EXPORT/" "/Volumes/Artifacts/promote/"
' || { echo "promote busy"; exit 17; }

與 Nomad/自研佇列並用時,請參考站內 Nomad 文將「鎖粒度」與「排程並行」對齊,避免雙軌互卡。

Derived Data 路徑

建議以環境變數或 -derivedDataPath 將 Derived Data 導到本機快速卷,並依 $CI_PIPELINE_ID/分支名建立子目錄,讓並行 job 彼此隔離。若團隊把 Derived Data 放在共享卷,務必保證「一 job 一路徑」,不要多寫者共用同一樹;涉及 SQLite/快取資料庫時,請另行評估 WAL 與鎖語意(可參考站內「共享卷 SQLite WAL」矩陣文題)。

  • 預設路徑:可預測但易與互動式本機建置混用;CI 專用節點仍建議顯式指定。
  • 每分支子目錄:利於並行與事後刪除;注意磁碟配額與輪替週期。
  • 唯讀快取+本機增量:適合超大 monorepo;實作複雜度較高,需驗證符號連結與 framework 搜尋路徑。

磁碟清理閾值(1TB/2TB 驗收)

下列為「卷宗已用容量」驗收閾值,請接到監控與自動化清理;觸發時應同步降低 Simulator 並發與 destination 數,而不是只清檔不改參數。

使用率區間 1TB 節點 2TB 節點 建議動作(含測試負載)
< 70% 維持參數表預設;每週排程清過期 xcresult 可保留較多 Simulator 快取;仍監控 APFS 快照。 綠燈:僅趨勢紀錄。
70%–80% 黃燈:收斂 destination 與並發;評估升 2TB 或拆測試節點。 黃燈:刪除過期 Derived 子目錄、舊 CoreSimulator 裝置資料。 降低夜間 shard 寬度;暫停非關鍵截圖/錄影留存。
> 90% 紅燈:視為硬停——停止新測試 dispatch,先清 Derived、Simulator 殘留與大型暫存,再恢復。 佇列背壓直至監控回綠。
70%
啟動例行清理與容量趨勢圖;校對清理腳本 dry-run。
80%
收斂 Parallel Testing 與 Simulator 並發;通知排程/值班。
90%
硬停線:清 Derived/CoreSimulator/暫存後再放行佇列。

若你正在把測試從單機搬到多台 Mac mini M4,請把「參數表+三閾值」寫進合併前驗收:同一節點上線腳本應能回報目前卷宗使用率、當前 Simulator 並發上限與 Derived 根路徑,避免跨區複製設定時漂移。

購買引導:需要獨佔 Mac mini M4 並搭配 1TB/2TB 儲存以支撐 Parallel Testing 與 Simulator 預算時,請至站內公開頁 購買(免登入瀏覽)方案/價格完成選型;下單前建議先依本文閾值對照你預期的 destination 數與並發上限。

本文為工程實務建議。 Xcode 與 XCTest 行為隨版本演進;請以 Apple 官方文件與你鎖定的 Xcode 版本為準。對生產路徑執行大量刪除前務必 dry-run 並保留稽核紀錄。
免登入即可瀏覽方案

為 Xcode 並行測試補齊 Mac mini M4 節點

依區域與 1TB/2TB 儲存 tier 對齊 Simulator 與 Derived Data 預算;無需登入即可在公開頁比對方案並下單。

前往購買(免登入瀏覽) 比對方案與儲存