摧毀 Apple Silicon CI 吞吐的最快方式,就是把快取命名成Git 分支。分支鍵會在靜默變更了 Package.resolved、Podfile.lock 或 Gemfile.lock 的提交之間重複使用圖,帶來「隨機」紅建置,甚至更糟的幽靈綠。到了 2026 年,請把相依快取當成依內容定址的儲存:對 lockfile 求雜湊、固定工具鏈建置號,並發布政策讓每位工程師理解——快取未命中是健康的訊號。
維運脈絡:磁碟與產物保留、工作樹與乾淨克隆,以及 Runner 親和性。若在香港、日本、韓國、新加坡或美國需要更隔離的 Mac mini M4 主機,請比對 定價,並參閱 說明 中的 SSH/VNC 存取模式。
為何 lockfile 雜湊勝過分支標籤
分支標籤暗示「這條開發線上的所有東西共享狀態」。相依圖並不沿分支走——它們遵循精確的解析結果。一次合併可能在未觸碰應用程式原始碼的情況下抬升遞移相依版本,使二進位失效而分支名不變。對 lockfile 雜湊讓快取命中成為證明義務:若雜湊一致,你就有證據顯示解析器輸出在模工具鏈意義下相同。
- 可重現性:稽核人員可把綠建置與特定 lockfile 摘要關聯。
- 並行 PR:同名分支上的兩個 PR(fork 工作流程)不再悄悄衝突。
- 磁碟經濟:在雜湊上做 LRU 比「刪掉整個分支資料夾」更能封頂成長。
矩陣 A:依生態的鍵控配方
| 生態 | 鎖定輸入 | 建議路徑後綴 |
|---|---|---|
| SwiftPM + Xcode | Package.resolved + Xcode build |
spm/<sha256(resolved)>/xc<build> |
| CocoaPods | Podfile.lock + Ruby 版本檔 |
pods/<sha256(lock)>/ruby<ver> |
| Bundler | Gemfile.lock |
bundle/<sha256(lock)> |
| npm / pnpm | package-lock.json 或 pnpm-lock.yaml |
js/<sha256(lock)>/node<major> |
矩陣 B:共享快取仍不安全的訊號
即便 lockfile 雜湊完美,若在還原階段執行 post-install 指令稿,仍無法救場。除非對指令稿執行做沙箱並對還原產物校驗,否則把這些作業視為冷路徑。
| 訊號 | 政策 | 緩解 |
|---|---|---|
post_install 鉤子改寫 Pods |
不要在作業間共享還原 | 每次建置都跑鉤子;僅快取下載 blob |
| 未校驗的二進位 Pod | 視為不可信輸入 | 在儲庫中以帶內容雜湊的 vendor 固化 |
| Fork PR 建置 | 獨立快取命名空間 | 絕不重複使用內部單體儲庫快取路徑 |
經得起稽核的數值預設
- 雜湊演算法:對正規化 lockfile 位元組做 SHA-256(在 CI 中統一剝離 CR/LF 差異)。
- LRU 寬度:每台主機每個生態保留最近 12 個雜湊。
- 最長保留:無論 LRU,14 天無命中即驅逐。
- 告警:當快取卷超過專用 CI 磁碟的 70% 時發頁。
安全提示:快取屬於供應鏈的一環。若遭竄改的 lockfile 可能毒化共享 tarball 快取,優先選擇暫時下載並校驗,而非盲目重複使用。
八步上線
- 盤點哪些儲庫缺少已提交的 lockfile——在補齊前禁止快取。
- 輸出摘要作為每次建置的 CI 產物以便事後關聯。
- 掛載快取到快速 APFS 卷而非網路共享,用於 SPM 解析。
- 接入指標:快取命中率、還原秒數、驅逐次數。
- 文件化 CONTRIBUTING.md 中的冷快取預期。
- 明確測試 fork 工作流程——依信任層級劃分快取命名空間。
- 與簽出政策配對(見工作樹指南)避免雙重共享。
- 擴展硬體——當驅逐引發抖動時,NodeMac 可依區域增加專用 M4 節點而無需採購週期。
常見問題
為何分支命名快取會導致幽靈綠?
它們在 lockfile 變更間重複使用二進位。對 lockfile 求雜湊,使快取命中意味解析器輸出一致。
SPM 快取應與 DerivedData 共用鍵嗎?
否——關注點分離。SPM 鍵屬於解析;DerivedData 屬於編譯索引,應包含作業或工具鏈維度。
多久修剪一次?
在上限內做 LRU,並配合最長保留驅逐;始終綁定磁碟告警。