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 的同事从会议室出来看了一眼手机:「ios-release 那条 Archive 还在排队,PR 线又被堵死了。」

Slack #ios-ci 频道实录:开发者汇报 Queued 47 分钟,Release 同事反馈 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 后再 merge。四条硬规则写进了 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 人,日 merge1–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 拆线

返回首页
限时优惠 点击查看套餐