VPSSpark 部落格
← 返回開發日記

GitHub Actions 正在拖慢 iOS 開發:Xcode CI 的新解法出現了

機房手記 · Cloud Mac CI #9 · 2026.06.12 · 約 12 分鐘閱讀
開發日記:從四十分鐘 Queued,到拆線、上雲 Mac、替 Agent 設護欄

常見搜尋:GitHub Actions iOS 慢 · Xcode CI 排隊 · macOS runner 自託管 · 雲 Mac GitHub Actions

MacBook 開啟程式編輯器與終端機——iOS 團隊在排查 GitHub Actions Xcode CI 建置
週四下午三點的 Slack——「CI 還在 Queued」——很多 iOS 團隊都熟悉這則訊息。

2026 年 5 月 29 日,週四,15:03。一支十二人的 iOS 團隊,有人在 Slack #ios-ci 貼了 Run 連結,配文「本機 Xcode 十二分鐘過了,PR 還在 Queued。」半小時沒人回——這類訊息太常見。48 分鐘後同一人補了一句:「Queued 47m,run 12m。今晚別指望 merge 了。」一位 release engineer 從會議室出來看了一眼手機:「ios-release 那條 Archive 還在排隊,PR 線又被堵死了。」

Slack #ios-ci 頻道實錄:開發者回報 Queued 47 分鐘,release engineer 反映 Archive 堵死 PR 線
圖 5 · Slack #ios-ci 實錄摘錄(倉庫與組織名已打碼,時間與數字保留)

下文截圖來自我們協助排障時客戶提供的材料,已打碼;數字未做修飾。你可對照 GitHub 官方文件中的 Job 執行時間與 queue_wait_seconds 自行複現統計。

這支團隊兩個 App 共倉,CI 全走 GitHub 託管 macOS Runner。2025 年還能忍;到了 2026 年春,回饋迴路被拉長到讓人失去耐心。GitHub Actions 並沒有「壞掉」,但對 iOS 團隊來說,越來越像尖峰必堵的共享接駁車

2832s
queue_wait_seconds
724s
run duration
3.9×
queued / run 比值

那個週四:打開 Job 頁,黃條比綠條長四倍

他們把 Run #18472910356 的 Job 頁截圖傳過來——不是口述,是帶時間軸的實錄。黃條(Queued)47 分 12 秒,綠條(Run)12 分 4 秒,介面底部寫著 queue_wait_seconds: 2832run duration: 724。公式簡單得刺眼:wait time >> run time

GitHub Actions Job 時間軸:Queued 47m12s,Run 12m4s,run 18472910356
圖 1 · Run #18472910356 · ios-pr.yml · macos-latest · 2026-05-29 15:04 CST

當時團隊還在開會討論要不要加 -jobs 並行、要不要換 DerivedData 快取 key——卻沒人拉過最近十條 macOS job 的 queued 與 run 兩欄數。Release 線那邊更憋屈:ios-release.ymlxcodebuild archive、notarization、上傳 TestFlight 和 PR 單測塞在同一條線、同一個 macos-latest 標籤上。Archive 一次二十五到四十分鐘,佔著稀缺併發槽,等 PR 紅燈的快回饋 job 一起被拖進佇列

若你此刻只想先排 Queued,可先讀站內 macOS runner 排隊診斷 Runbook。他們的轉折,是從承認「問題在供給」、並且用數字而不是體感說服會議室之後才開始的。

證據:十條 failed job 抄錄表

5 月 30 日站會前,有人從 Actions 執行列表手動抄了十個 failed macOS job(見下圖)。沒有花俏 BI——就是一張表,兩欄核心數字:queued_srun_s。中位數 queued 2650 秒、run 724 秒;比值最高到 4.5×。那一刻會議室安靜了幾秒:沒人再提「是不是 Xcode 17.4 的鍋」。

十個 failed macOS job 的 queued_s 與 run_s 手抄統計表
圖 3 · 2026-05-22 — 05-29 十個 failed macOS job 手抄表(脫敏)
常被誤判為圖 3 裡的訊號更可能原因
GitHub 故障10/10 條 queued_s > run_smacOS 併發 cap、重任務佔槽
專案變大run_s 穩定在 690–811s編譯並非主因,等待才是
同事亂 push同一 PR 多 run(見圖 2)Agent / bot 迴圈
憑證過期簽章失敗分散在不同 run鑰匙圈冷啟動、並行爭用

圖 2:同一 PR 被觸發了六次

排隊還只是前半場。三月裡團隊接了一個編碼 Agent:CI 紅 → 讀日誌 → 自動 commit → 再觸發 Actions。PR #847 的 Checks 頁截得很清楚——六個 workflow run,其中四個 actor 是 bot,兩個是人。名義上仍是 CI;行為上已是 retry loop。詳見 CI 被迴圈化之後會發生什麼

Pull Request #847 上六個 GitHub Actions workflow 執行記錄
圖 2 · PR #847 · 6 次 ios-pr.yml 觸發(4× bot · 2× 人)· 2026-05-29

團隊裡後來有人開玩笑:「CI 沒死,是我們把它跑成了永動機。」壞的不是自動化,是每一次 bot 修復都在搶公共佇列,且沒有專用 Runner 池。

轉折點:一台雲 Mac,和 5 月 31 日拆線的那個晚上

抄錄表之後,團隊先把日誌按 job 類型拆開:大約七成 PR 校驗與整合編譯,兩成 Simulator 單測,一成 Archive 與上傳——和 另一支團隊每天五百次 iOS CI 的實測構成 驚人相似。有人提議買八台 Mac mini;有人提議遷 Xcode Cloud。最終落地兩件事:

5 月 31 日,租一台 Apple Silicon 雲 Mac,註冊自託管 Runner(標籤 self-hosted, macOS, cloud-mac)。對照實驗很樸素:同一 commit 在託管 macos-latest 與雲 Mac 上各 build 五十次——queued 方差從「有時 40 分鐘有時 5 分鐘」收成「基本是個位數秒」。

當晚拆線。 把 Archive、export、上傳從 ios-pr.yml 挪到 ios-release.yml,PR 線只保留 build 加單測。暖機 cron 也加上了:每天凌晨在雲 Mac 上跑一次 xcodebuild build,DerivedData 留在磁碟上,比每次從 actions/cache 冷拉更穩。

圖 6 · 同一團隊 wall time 中位數(PR build,兩週各 50 次)

託管 macOS · queued
38 min
託管 macOS · run
12 min
雲 Mac 自託管 · queued
41 s
雲 Mac 自託管 · run
9 min

資料來源:客戶對照實驗日誌(2026-05-31 — 06-08),與圖 1、圖 4 單次 run 可交叉驗證。

6 月 9 日:圖 4 那張終於「像話」的 Job 頁

拆線兩週後的週一早晨,Slack 裡有人貼了 Run #18510488201 的截圖:queued 41 秒,run 9 分 17 秒,runner 已是 self-hosted, cloud-mac。頻道裡沒人按讚,有人回了一個表情——在 iOS 團隊裡,那就是最高的褒獎。

GitHub Actions 自託管 Runner:Queued 41s,Run 9m17s,cloud-mac
圖 4 · Run #18510488201 · self-hosted, cloud-mac · 2026-06-09 09:11 CST

給 Agent 設護欄:四條寫進 Wiki 的規則

拆線解決 Archive 堵 PR;bot 迴圈還要另治。團隊給 bot 單獨分支和低優先級 Runner 池,人 review 後再合併。四條硬規則寫進了 Wiki:

  • PR workflow 禁止 Archive / 上傳商店
  • macOS job 必須設 concurrency,避免同一分支疊跑
  • 自託管 Runner 必須標籤化,禁止與實驗 workflow 混池
  • Agent 自動 push 必須走獨立分支,禁止直推保護分支
你可以複製的 30 分鐘自檢
打開最近 10 個 macOS job,抄 queue_wait_seconds 與 run duration(如圖 3);統計單 PR workflow 次數(如圖 2);確認 Archive 是否還在 PR workflow 裡。若中位數 queued > run,先談 Runner 供給,別先調編譯參數。

新解法是什麼:不是拋棄 GitHub,是換供給方式

這支團隊的經歷,濃縮成 2026 年 iOS 團隊最常落地的四件事:雲 Mac 自託管 Runner 池PR / Release 拆線暖機與磁碟快取Agent 護欄。Xcode Cloud 能替代嗎?適合 Apple 生態閉環;與 GitHub PR 檢查、混合 Android 線組合時,多數團隊仍保留 Actions,只把 Archive 遷到專用 macOS 算力。

若你的團隊像……常見落地建議
1–3 人,週發版託管 macOS + 強快取;Release 手動 Archive
5–15 人,日合併1–2 台雲 Mac 自託管 + PR/Release 拆線
15+ 人,多 AppRunner 池按 App 分標籤 + 暖機 cron
重度 Agent 修復獨立 bot 池 + 禁止 Archive 進 PR workflow

Apple 官方 xcodebuild 文件 強調 scheme 與 destination 一致;CI 若環境每次冷啟動,「本機能過」會失去意義。客戶原話大概是:比每天對著 47 分鐘黃條,憑證輪換和 Xcode 大版本升級反而更好忍受。

從第一台雲 Mac 自託管 Runner 說起

若你的 Job 頁也像圖 1——黃條壓過綠條——下一步最划算的投資通常是一台專屬 Apple Silicon 雲 Mac:註冊為 GitHub 自託管 Runner,讓 PR 編譯從「排隊抽獎」變成圖 4 那樣可預期的九分鐘。

先跑兩週對照實驗:同一分支在託管 macOS 與雲 Mac 自託管各 build 五十次,抄一張像圖 3 的表。資料會告訴你,究竟是 Xcode 慢,還是供給在拖慢 iOS 開發。

從一台可預期的雲 Mac 開始,把 Archive 請回 Release 線。 查看 VPSSpark 雲 Mac 方案, 註冊你的第一台 iOS 自託管 Runner。

限時特惠

iOS CI 總排隊?用雲 Mac 做自託管 Runner

GitHub Actions · 專用 Apple Silicon · PR/Release 拆線

返回首頁
限時優惠 點擊查看方案