Linear CI 優化:解決 AI 驅動開發的瓶頸

AI 驅動的程式碼代理大幅提升了程式碼交付速度,但驗證流程卻未能跟上步伐。在 Linear,這種差異使持續整合(CI)成為主要瓶頸,增加了基礎設施成本,並延遲了開發者與代理的反饋時間。透過實施多層次的優化策略,Linear 將合併請求的等待時間從超過 6 分鐘縮短至僅略超過 5 分鐘,即使今年以來測試套件的規模幾乎增加了四倍。

基礎設施與工具鏈升級

升級底層硬體與編譯器工具鏈可在不改變 CI 流程邏輯的情況下立即獲得性能提升。

  • 第三方執行器: 將工作負載從 GitHub Actions 移至具有更快 CPU、更高性能儲存與優秀快取基礎設施的第三方執行器,使各工作平均提速 34%,部分工作(如 tsc(TypeScript 編譯器))更提升了 52%。
  • 原生編譯: 改用 tsgo,一個原生 TypeScript 編譯器,將 tsc 檢查的每周中位數時間減少 73%,有效消除了類型檢查的瓶頸。
  • 基於 AST 的靜態檢查: Linear 將自訂的 lint 规則重寫為使用抽象語法樹(AST)進行靜態分析,而非依賴 TypeScript 類型資訊。這使得 ESLint 可以在不依賴完整類型圖的情況下運作,將 API lint 時間減少 68%,全倉儲 lint 時間減少 55%。
  • Oxlint 整合: 改用 Oxlint 進一步降低了 linting 所耗的執行器分鐘數,因其在處理基於語法的規則時效率更高。

優化門檻工作

位於關鍵路徑上的工作——那些必須在其他任何工作開始前完成的工作——對總 CI 時間有不成比例的影響。

高效的變更檢測

Linear 優化了最初根據 PR 差異決定執行哪些測試的工作:

  • 限制取得深度: 透過限制變更檢測工作的取得深度,最慢的門檻時間從 94 秒降至 20 秒。
  • 移除工作樹: 不需要完整工作樹的工作完全移除了檢查出動作,執行時間從 27 秒降至 7 秒。
  • 稀疏檢查: 對提交推送與合併佇列事件,使用具有有限歷史記錄的稀疏、無 blob 檢查,額外節省了 11 秒。

這些變更使變更檢測工作的中位執行時間從 26 秒降至 8 秒。

強韌性與路徑最小化

為應對第三方執行器與 GitHub 之間的網路不穩定,Linear 將 actions/checkout 替換為自訂的組合動作,該動作實現了帶退避的重試機制,並設定了 GIT_HTTP_LOW_SPEED_LIMIT 與 GIT_HTTP_LOW_SPEED_TIME 以防止掛起。此外,他們將非必要任務(如寫入快取標記)移出關鍵合併路徑,使每個 API 合併請求節省了 42 秒。

減少重複的設定開銷

設定成本——啟動執行器、安裝套件與配置依賴——在短暫執行的工作中,往往比實際測試耗時更長。

  • 自訂 CI 映像: Linear 將共享依賴(例如 Postgres 客戶端)移入基礎 CI 映像。這消除了每個分片 7-8 秒的 apt 安裝時間,並防止了原生建構標頭下載時偶發的掛起。
  • 過濾依賴安裝: 在其 pnpm 多倉儲中,API 測試工作流程改為僅安裝 API 套件及其依賴,而非整個工作區。這使 pnpm install 時間從 44-73 秒降至 16-18 秒。
  • 重建 vs. 快取: 測試顯示,透過過濾安裝重建 node_modules(7.5 秒)比從快取還原(28 秒)更快,因此 Linear 放棄了 node_modules 快取。
  • 資料庫結構快照: 改為在每次執行時載入生成的資料庫結構快照與啟動檔,而非重播完整的資料庫遷移歷史,將資料庫設定時間從 12 秒縮短至 1-2 秒。
  • 工作批次處理: 將七個獨立的短時間檢查合併為兩個可並行執行的工作。這降低了設定開銷的頻率,每月節省約 87,000 個執行器分鐘(佔總 CI 使用量的 11.8%)。

提升測試執行效率

在設定成本最小化後,Linear 開始積極平行化 API 套件,這是工作流程中最大且最頻繁的部分。

工作負載平衡

由於 Vitest 按檔案分配工作而非測試執行時間,少數大型檔案可能成為分片的瓶頸。Linear 將這些大型檔案拆分為更小、更專注的檔案,並將分片數量從四個增加至八個。這使最慢分片的執行時間從 5.25 分鐘降至 4.33 分鐘。

模組狀態快取

透過引入一個可選的 Vitest 專案並設置 isolate: false,Linear 允許安全的測試檔案在每個工作進程內共享模組註冊表。這避免了每個檔案都需重複重建實體、GraphQL 與裝飾器圖。這是單一最大的改進,使最慢分片的執行時間從約 300-379 秒降至 195 秒,並將每次執行的總 API 分片執行器時間從 32.8 分鐘減少至 22 分鐘。

社群觀點與反駁意見

雖然 Linear 的技術方法聚焦於基礎設施與流程效率,但社群討論也突顯了更廣泛的系統性挑戰:

  • AI 測試的價值: 一些貢獻者質疑測試套件擴大四倍是否帶來相應的價值提升,認為 LLM 可能產生大量範本或無意義的測試。
  • 左移驗證: 有人建議將 linting 與單元測試移入代理的本地循環(透過 Hooks 或技能),使 CI 僅處理資源密集型任務,並接收已預先驗證的候選者。
  • 替代工具: 多位開發者提倡使用 Bazel 或 Grog 等建構系統,這些系統透過激進的快取與依賴圖,可在大型專案中實現 10 秒級的建構時間。
  • 移動的瓶頸: 工程師中普遍存在一種共識:加快 CI 只是將瓶頸進一步推至人工程式碼審查、部署與回滾流程。

"加快 CI 只是將瓶頸移到審查與部署。代理讓佇列更嘈雜——它們並未創造它。"

Sources

相關