2026:遠端 Mac 自建 GitHub Actions 與 GitLab CI Runner
標籤語意、並發上限與機密隔離

約 17 分鐘閱讀 · MACCOME

平臺與行動端負責人在 2026 年把 iOS/macOS 建置搬到遠端 Mac 時,常見起手式是「先註冊 Runner,政策之後再說」。結果標籤模糊、並發塞滿磁碟、簽章脈絡纏在一起。本指南面向在新加坡、東京、首爾、香港、美東、美西之間挑節點的團隊:六類痛點拆解、兩張控制面對照表、可貼上的工作流程片段、六步 Runbook、三項監控指標,並與多專案容量SSH 對照 VNC兩文交叉引用,方便做 CI 評審與 checkout。

為什麼「加更多 Runner」很少能治好佇列與不穩定任務

自建 Runner 會把真實的 macOS 執行面暴露給編排器。GitHub Actions 使用儲存庫與組織層級的 Runner;GitLab 則以專案/群組 Runner 搭配不同執行器類型。若標籤一直停留在泛用層級(macios),工作流程會搶同一臺主機;DerivedData 與磁碟 I/O 熱點疊加,失敗看起來像隨機逾時,而不是清楚的資源壓力。在加主機或跳到 M4 Pro 之前,先把下面六類痛點拆開。

  1. 標籤缺少能力維度:沒有 Xcode 主次版本、簽章需求與模擬器圖形需求時,排程器只能盲派;事故發生後也無法歸因「是哪一類任務越線」。
  2. 並發未寫進文件:任務並行超過磁碟鎖能承受的速度時,全隊變慢;請把每台 Runner 的最大任務數寫進運維文件,不要只靠預設值。
  3. 機密平面等於建置平面:互動式登入與 CI 共用同一 macOS 使用者時,鑰匙圈提示與描述檔會讓流水線變成「有時無人值守、有時要人點允許」。
  4. 沒有快取命名空間:多個儲存庫共用同一 DerivedData 根目錄會造成汙染與高風險清理;一次過於激進的 clean 可能傷及並行中的其他專案。
  5. 區域與製品錯位:協作在新加坡卻把 Runner 放在美西,大型 .xcarchive 或依賴快取跨洋搬運,省下的機器成本會換成頻寬與工程小時。
  6. 租期角色漂移:發布週需要短爆量,但若全年按尖峰費率付費,會同時得到低 Runner 利用率與難看的現金流。

接下來的表格把 Runner 角色與 GitHub/GitLab 差異講清楚;之後再對應 YAML 與落地步驟。

專用建置主機對共享 Runner 池:把角色寫進工單

範圍切分:多專案文章講佇列與租期組合;本文講註冊 Mac,並讓工作流程穩定命中正確環境。架構評審請帶上表 1。

維度共享 Runner 池專用建置主機
典型任務Lint、單元測試、輕量 xcodebuild、無正式環境簽章歸檔、TestFlight 上傳、多模擬器矩陣、嚴格簽章
標籤細粒度:macos-14xcode-16no-signing,可組合專案專用標籤;阻擋其他儲存庫誤用 runs-on
並發保守並行+佇列溢出時切到爆量主機並行綁磁碟觀測;穩定優先於塞滿
機密與帳戶專用 CI 使用者;鑰匙圈或描述檔策略分區固定簽章身分、輪換負責人、審計軌跡
較適合何時耦合低、可接受短暫排隊合規、客戶交付,或需要可重現主機的發布關卡

GitHub Actions 對 GitLab Runner:控制面差異

兩者都能驅動遠端 Mac,但機密注入、Runner 可見度與快取習慣不同。表 2 對齊平臺與工程用語(欄位名請以廠商最新文件為準)。

維度GitHub Actions(自建)GitLab Runner(shell/ssh)
排程儲存庫/組織 Runner + runs-on: [self-hosted, …]tags 對應 + 註冊範圍(專案/群組/實例)
機密Secrets/Variables、Environments;OIDC 短期雲端憑證CI/CD 變數、遮罩變數;留意群組繼承與受保護分支
並發旋鈕矩陣任務需在 Runner 端自行限制行程數concurrent 與每臺 Runner 設定;勿在未隔離下於同一使用者跑多個執行器
常見坑自建 Runner 可能繼承互動登入的環境變數多個 Runner 行程搶 Xcode 授權或埠號
yaml
# GitHub Actions: bind jobs to capabilities, not generic macOS
jobs:
  ios_build:
    runs-on: [self-hosted, macOS, xcode-16, m4-ci]
    concurrency:
      group: ios-${{ github.ref }}
      cancel-in-progress: true
    steps:
      - uses: actions/checkout@v4
      - name: Select Xcode
        run: sudo xcode-select -s /Applications/Xcode_16.app

# GitLab CI: tags map to the runner on the remote Mac
ios_build:
  tags: [macos, xcode16, m4-ci]
  script:
    - xcodebuild -version
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
info

說明:請在內部 Runbook 註冊標籤名稱時一併記錄 Xcode 路徑、是否允許簽章、最大並行任務數—避免複製過期的工作流程。

六步:從遠端 Mac 到可驗收的自建流水線

區域前置作業請參考多地區指南;接入方式請參考SSH 對照 VNC

  1. 凍結 Runner 能力矩陣:每臺 Mac 列出 Xcode 版本、正式環境簽章政策、最大並行任務數、磁碟層級與告警門檻。
  2. 建立 CI 使用者與目錄:非互動式服務帳戶;依專案或儲存庫命名空間切分 DerivedData/快取根目錄。
  3. 註冊 Runner 與標籤:在 GitHub/GitLab 完成註冊後,逐一把標籤與矩陣對齊;禁止未記錄的「暫時」標籤。
  4. 設定機密與輪換:儲存庫/環境機密採最小權限;憑證與描述檔分發受控;記錄輪換與回滾負責人。
  5. 跑兩週觀測:佇列深度、任務 P95、每週磁碟增量、失敗分類;沒有資料就不要買第二臺 Runner。
  6. 寫驗收與下線:爆量主機 Runner 註銷、金鑰撤銷、快取清理必須可執行;基線變更要走變更單。

三個應出現在儀表板上的指標

下列欄位名可直接貼進 Grafana、Datadog 或週報。

  1. 佇列深度與逾時率:若逾時集中在某一組標籤,先收斂並發或切分磁碟路徑,再考慮加 CPU。
  2. DerivedData/快取根目錄每週成長(GB):把每週 GB 放在租賃發票旁邊,判斷 1TB/2TB 是否貼近真實建置形狀。
  3. 跨區製品分鐘數:主路徑應與消費端同區;跨洋大檔上傳是典型隱性成本—請在評審附錄預留工程小時。

專用主機穩定兩週後,再評估第二臺節點或 M4 Pro 以支撐重型矩陣。

運維補遺:當 xcodebuild 與 Swift 套件解析同時吃滿網路與磁碟時,P95 常被索引與快取寫入拉長—不僅是編譯器吞吐。請把佇列長度與磁碟 await 一併追,並留意記憶體壓縮是否觸發,不要只看 CPU。將 Runner 在線時數對齊租賃發票,財務才能理解為何需要專用主機;否則共享池爭論會一直缺乏證據。

為什麼臨時筆電與巢狀虛擬機難以支撐可審計的 iOS CI

巢狀虛擬化會放大 Metal、簽章與 USB 流程的摩擦;個人筆電會睡眠、依自己的時程更新,打斷無人值守任務。正式環境的 Apple Silicon 需要裸金屬專用、可選區域、可組合租期,並把 Runner 標籤與並發寫進運維基線。

僅靠分散桌面很難長期支撐閘道、AI Agent 執行層或多儲存庫 CI:權限提示與突襲式系統與軟體更新會把自動化變成隨機失敗。MACCOME 於多地區提供 Mac mini M4/M4 Pro 裸金屬與彈性租期—可作為自建 Runner 的基線執行層,並搭配可驗收的爆量容量。讀完地區、SSH/VNC 與多專案文章後,請在價格頁對齊方案並下單相符區域。

建議先在主要製品所在區域用短租試點,再把基線從月租延伸到季租;極短尖峰用日租或週租吸收,避免把現金鎖在錯誤檔位。

常見問題

先加 Runner 還是先收斂標籤?

先凍結標籤語意與每台 Runner 並行上限,再觀察佇列與磁碟。請開啟租賃價格,並搭配多地區選型

GitHub 與 GitLab 機密要對齊哪一個原則?

長效機密不要進 git,並以獨立 macOS 使用者隔離簽章。接入模式請讀SSH 對照 VNC(CI)幫助中心

多專案並發還要讀什麼?

請續讀多專案容量與租期組合,把 Runner 角色與里程碑對齊。