2026年企業 iOS/macOS CI 選型:GitLab Runner(macOS)與 GitHub Actions 自託管 Runner 對比——獨佔遠端 Mac 節點上的併發、SSH 帳戶隔離、快取掛載與運維 FAQ 決策矩陣
當 CI 必須跑在實體 macOS、且一臺遠端 Mac 原則上「獨佔」給團隊使用時,GitLab Runner 與 GitHub Actions 自託管 Runner 的本質差異不在 UI,而在併發語意、程序身分、工作目錄與快取掛載策略。本文用運維可執行的表格收斂決策。
一、前言:為什麼「獨佔遠端 Mac」會放大差異
雲端託管 Runner 把多租戶隔離藏在供應商側;自託管 macOS 節點則把隔離問題交還給你。當節點獨佔時,常見痛點是:同一臺機器能否安全地跑多個建置、SSH 登入身分與 CI 程序是否一致、Derived Data/SPM/CocoaPods 快取要掛在哪裡才不會互相踩檔。若你正在評估 GitHub 生態與 GitLab 一體化流水線何者更順,可先參考我們對 Xcode Cloud 與自建 GitHub Actions 的決策矩陣,再回到本文的 Runner 層級比較。
- 併發:Job 是否假設「整機可用」,還是需要細粒度資源標籤與佇列
- 身分:SSH 互動除錯帳戶 vs. launchd/服務帳戶執行 CI 的 Keychain/權限落差
- 快取:本機 SSD 掛載點、網路儲存、以及「可清除性」與建置可重現性的權衡
二、併發模型與排程語意(獨佔節點版)
以下假設單一 Mac mini/Mac Studio 作為團隊節點;實務上仍建議用標籤或 Runner 名稱區分用途(例如 ios-release 與 ios-pr)。
| 維度 | GitLab Runner(shell/custom) | GitHub Actions 自託管 Runner |
|---|---|---|
| 預設併發想像 | 以 Executor 與 concurrent 設定為中心,易與專案/群組 Runner 池對齊 |
單一 Runner 程序可承接多 Job;實務上常以「一機一 Runner+標籤」降低狀態干擾 |
| 佇列與優先級 | 與 GitLab CI 圖、環境、resource_group 等原生欄位結合度高 | 依儲存庫/組織配額與矩陣策略調度;跨 Repo 排隊行為需自行觀測 |
| 多 Job 同機風險 | shell executor 下共享同一使用者環境時,檔案鎖與模擬器埠衝突機率高 | 類似:若未做目錄隔離,xcodebuild 與模擬器資源仍會互搶 |
若你的目標是「單機高併發」,請優先設計工作目錄隔離+模擬器裝置配對,而不是先爭論要用哪套平台;雲端 Mac 架構設計也可一併參考 遠端 Mac mini 上的 iOS CI 實踐。
三、SSH 帳戶隔離與「誰在跑 CI」
遠端除錯幾乎都走 SSH,但 CI 常見以 launchd、服務帳戶或互動使用者登入後啟動的 Agent 執行;兩者若混用,會出現「手動跑過、CI 却找不到憑證」的經典問題。
| 議題 | 建議作法 | 驗收訊號 |
|---|---|---|
| Keychain/簽名 | 固定「CI 專用」macOS 使用者,憑證與 Provisioning Profile 只匯入該登入鑰匙圈 | 同一提交在 SSH 批次與本機互動下,codesign 結果一致 |
| SSH 除錯 | 需要時以同 CI 使用者身分開互動 Session,避免用管理員帳戶「幫忙試一次」造成漂移 | Runbook 能寫出「誰的環境變數/PATH」 |
| 檔案權限 | 建置目錄與快取目錄統一屬主;清理 Job 用同一使用者刪除 | 不會出現 root 擁有而 Runner 無法覆寫的殘留 |
四、快取掛載:Derived Data、SPM、Pods 怎麼放
快取能顯著縮短 iOS/macOS 建置時間,但錯誤掛載會讓「偶發失敗」難以重現。下表以獨佔節點常見路徑為例(實際路徑請對齊 Xcode 版本與專案設定)。
| 快取類型 | 建議掛載/保留策略 | 風險提示 |
|---|---|---|
| Derived Data | 集中於單一路徑並由清理政策控管;重大 Xcode 升級後安排離峰刪除重建 | 跨分支共用時,索引與模組快取可能與 Swift 版本不相容 |
| SPM | 快取套件原始碼與建置產物目錄,並鎖定 Package.resolved | 解析結果未鎖定時,CI 與本機會「看似同一提交、不同依賴」 |
| CocoaPods | Pods 目錄與快取目錄分離;偏好可重現的 lockfile 流程 | 多 Job 並行時避免共用同一 Pods 建置暫存目錄 |
五、運維 FAQ 決策矩陣
將常見問題收斂成「現象 → 假設 → 動作」,方便寫進 on-call 備忘錄。
| 情境/FAQ | 較適合的思考路徑 | 第一步動作 |
|---|---|---|
| 程式碼在 GitHub,但想統一用 GitLab CI | 評估鏡像、API 整合與雙平台維護成本;Runner 本身可執行任意腳本 | 先畫出觸發鏈與秘鑰邊界,再決定是否值得「跨平台編排」 |
| 已重度使用 GitHub 生態(Actions、Code Scanning) | 自託管 Runner 降低供應商排隊;與 OIDC、環境保護規則一併設計 | 用最小矩陣驗證 Runner 服務帳戶與權杖生命週期 |
| 需要嚴格資源群組(同一 App 不可並行發版) | GitLab resource_group 類需求在 YAML 層較直觀;GitHub 需組合環境、佇列或外部鎖 |
把「互斥資源」列成名稱清單並測試競態 |
| Runner 升級與 macOS 升級誰先誰後 | 兩邊都必須滿足相容矩陣;先對齊 Xcode/SDK,再升 Runner 二進位 | 在維護視窗跑試建置並保留上一版 Runner 安裝包以利回滾 |
六、落地檢核表(獨佔節點)
- • 併發上限:以實測 CPU/磁碟 I/O/模擬器數量決定,而不是預設開滿
- • 身分一致:SSH、launchd 與互動登入的預設環境變數對齊方式寫進文件
- • 快取 SLO:定義「可接受的全量重建頻率」與「清理警報」
- • 可觀測性:至少記錄 JobId、提交、Xcode 版本、Runner 版本與建置目錄路徑
兩套工具都能把 macOS CI 跑穩;差別在於你的組織是「以 Git 平台為中心」還是「以流水線與權限模型為中心」。把獨佔節點的併發、SSH 身分與快取掛載先講清楚,選型爭議自然會縮小。
在 Mac mini 上,CI 腳本與簽名流程更一致
本文討論的 shell/自託管流程,在 macOS 上最能發揮「原生工具鏈+長時間待機仍省電」的優勢:Apple Silicon 的統一記憶體讓大型 Xcode 專案與模擬器並存時較不易卡在記憶體頻寬瓶頸,macOS 的權限模型也讓 Keychain、Hardened Runtime 與 notary 相關操作維持在同一套系統語意內。相較於在異質環境來回切換,把獨佔節點放在實體 Mac mini 上,通常能顯著降低「本機可以、CI 不行」的漂移成本。
Mac mini M4 在待機功耗與噪音控制上適合機房或辦公區長期開機;若你希望把 2026 年的 iOS/macOS 流水線跑在穩定、可預期的硬體上,現在正是檢視節點規格與租賃方案的合適時機——前往首頁了解方案,把 Runner 選型與機器資源一次對齊。