GitHub Actions 的并发组默认只保留 1 个正在运行的任务和 1 个等待中的任务;同组再来新任务时,旧的等待任务可能被取消并替换。这个规则说明,看到“排队”并不等于 Mac 台数一定不够。没有适用于所有团队的固定 Mac 数量:先记录目标时段同时运行的 macOS 工作流、排队时长和节点占用,再按可接受等待估算并发槽位;先小批试运行,验证有效后再扩容。(docs.github.com)
这篇文章适合正在判断排队是否值得扩容的小型 iOS 团队、需要在多个仓库之间安排并发的工程团队,以及要用可复核数据规划自管理 Runner 的平台负责人。只需要偶尔运行测试、没有持续排队的个人项目,通常应先测量再行动,而不是按团队人数购置节点。
先判断个人项目是否遇到持续瓶颈
个人项目常见的误判,是一次提交触发多个工作流,恰好撞上完整构建或发布任务,随后便把短暂拥堵当成日常容量不足。若工作流平时很快启动,只在集中提交或发布时等待,增加常驻 Mac Runner 可能只是把闲置时间变长。
先从 Actions 记录一段能代表日常开发和发布节奏的周期。对每个 macOS Job,保存触发时间、开始运行时间、结束时间、等待时长、执行时长、工作流类型,以及当时匹配的 Runner 是否空闲。GitHub 的工作流 Job 接口提供 started_at、completed_at、Runner 标识和 Runner 组等字段,可用于整理这些记录;执行时间也可在工作流运行详情中查看。(docs.github.com)
把“偶发排队”和“持续瓶颈”分开处理:
- 偶发集中提交后短暂等待,之后队列自行消化:保留现有容量,先确认等待是否影响合并或发布。
- 多个代表性时段都出现长等待,且匹配的 Runner 持续忙碌:把增加并发槽位列入试运行方案。
- Runner 显示空闲,任务却没有启动:优先检查标签、组权限、离线状态和工作流依赖,而不是先添节点。GitHub 的 Runner 状态包括空闲、活动和离线;离线节点不能接收任务。(docs.github.com)
用小团队的等待目标估算并发槽位
小团队的 iOS Runner 数量,不应由开发者人数直接推算。真正影响 macOS CI 并发的是工作流触发是否重叠、每类任务占用节点多久,以及团队能接受多长等待。几个人在不同时间提交,可能没有显著并发;人数较少但发布集中、测试任务多,也可能出现明显队列。
可以把容量估算拆成几个变量:
- 目标时段并发:同一时段内已开始运行或正在等待、且确实需要执行的 macOS Job。
- 节点占用时长:从任务开始到释放 Runner 的时间,按单元测试、完整构建、发布任务分别记录。
- 可接受排队目标:团队认为合并验证或发布前,等待多长时间仍可接受。
- 有效槽位数:实际可接收该 Job 的在线 Runner 数量,而非账面上的 Mac 总数。
- 波动因素:缓存命中、依赖下载、测试重试和任务失败造成的占用变化。
一种可复核的估算方式是:按目标时段列出并发 Job 的时间线,观察等待目标内需要同时获得执行机会的任务数量;再将该数量与现有有效槽位对照。若等待超过目标时,经常有任务在排队且所有匹配节点都忙,缺口可作为试运行时增加的槽位数。它是基于自有工作流数据的估算框架,不是 GitHub 对容量或排队时长的承诺。
同时看平均工作流数量和高峰并发,但不要把两者当成同一个配置指标。平均值更适合判断常驻节点是否长期闲置;高峰值帮助判断发布窗口会不会排长队。若高峰只在少数发布时段出现,可以先评估临时容量或错峰发布,而不是把峰值需求全部配置成全天常驻容量。
按工作负载规划多仓库共享池
多个仓库共享 Mac Runner 时,先按任务的执行特点和访问权限划分,而不是只按仓库数量平均分配。单元测试可能触发频繁、占用较短;完整构建通常涉及更多编译步骤;发布任务还可能需要签名凭证或受限访问。三类任务混用同一组节点时,发布任务可能被大量测试挤压;过度隔离则会让某些池闲置、另一些池拥堵。
GitHub Runner 组可用于组织 Runner、限制哪些仓库能使用特定组,并将工作流路由到对应 Runner;runs-on 可以结合组和标签筛选执行节点。标签必须与 Runner 实际环境匹配,否则即使 Mac 在线,也可能不符合工作流的路由条件。规划共享池时,应同时复核组访问策略、工作流选择条件和各组的等待记录。(docs.github.com)
在共享与隔离之间,可按这些条件判断:
- 多个仓库权限相近、构建环境一致、任务占用差异不大:优先试共享组,观察是否改善整体利用。
- 发布凭证、访问范围或环境要求不同:为发布任务单独设置路由和访问控制,不让所有仓库默认获得同一 Runner 权限。
- 某一类标签的 Job 总在排队,但其他组有空闲节点:检查路由是否把负载限制在过窄的池中,再决定调整标签还是增加该池容量。
- 工作流配置了
concurrency:确认它是否有意串行化任务,或在默认规则下取消旧的等待运行;这种排队不一定能靠增加 Mac 节点解决。(docs.github.com)
共享 Runner 也带来运维和安全成本。自管理 Runner 需要维护机器、操作系统和工具链;官方还建议谨慎让公共仓库的分叉代码访问自管理 Runner,因为工作流可能执行不可信代码。多仓库复用可以减少节点闲置,但不能因此跳过仓库访问范围和工作流权限审查。(docs.github.com)
用清单复核数据,再分批试运行
以下清单可用于确定是否扩容,以及扩容后如何验证;每项都应能从工作流记录、Runner 状态或配置中复核。
- [ ] 选取能覆盖普通开发、集中提交和发布活动的代表性观测周期,并记录采样范围与工作流类型。
- [ ] 分别统计排队时间和节点占用时间,避免把“任务运行慢”误判成“Runner 不足”。
- [ ] 对照 Job 标签与 Runner 组,确认任务确实能路由到正在统计的节点池。
- [ ] 检查工作流依赖、并发组和取消策略,确认等待不是由串行规则或队列替换行为造成。
- [ ] 按测试、完整构建和发布拆分负载,再确定共享池、隔离池或专用路由。
- [ ] 先增加有限并发容量,使用与扩容前相同的口径比较排队、Runner 利用和失败情况。
- [ ] 若排队没有改善,先回查标签、权限、离线节点及串行步骤;确认原因后再决定是否继续增加容量。
观察到 Runner 空闲但 Job 仍排队时,不要立即扩容。GitHub 的自管理 Runner 路由依赖工作流指定的组和标签;没有符合条件的在线空闲节点,Job 会继续等待。(docs.github.com)
试运行结果应同时看等待与失败,而不是只看新增节点是否上线。若排队缩短、执行失败没有恶化,新增容量可能解决了瓶颈;若等待未变,检查 Runner 是否被正确选中、是否有并发组限制,或任务是否卡在必须依次执行的依赖上。若使用自管理 Runner,还应纳入系统更新、工具链维护和故障排查工作量;官方提供的自管理 Runner 监控说明包括状态查看和诊断日志,可作为排错入口。(docs.github.com)
容量规划也要把不同成本分开。Mac 节点的使用与维护属于构建资源成本;模型 API 调用量属于另一类支出,不能合并成一个“CI 成本”数字后据此决定 Runner 数量。若考虑远程 Mac,应单独核对实际可用配置、交付方式和租用周期;只有这些信息能与目标工作流需求对应时,比较才有意义。Zutcloud 的Mac mini 租用与服务信息可作为核对租用条件的入口;涉及地域选项时,也应以对应页面实际列出的内容为准,例如香港 Mac mini 租用说明。
先用自己的 Actions 数据判断所需并发,再决定是否要把估算容量映射到远程 Mac 节点。若只是偶尔出现高峰,调整触发时机或接受短暂等待可能更合适;若持续排队且匹配节点长期繁忙,远程 Mac 租用可以作为扩充构建能力的选择。确认实际需求与租用条件后,再查看 Zutcloud 的 Mac mini 租用信息,不要在没有验证排队改善前,把临时峰值直接转成长期节点投入。
FAQ
GitHub Actions 的排队时间怎么换算成 Mac Runner 数量?
先从同一代表性时段统计每个 macOS Job 的开始等待时间、实际占用时长,以及等待期间有多少 Job 同时处于可运行状态。再把等待时长与可接受目标比较,估算还缺多少并发槽位。排队时间本身不能直接换算成固定台数;必须同时确认任务是否匹配可用 Runner,以及是否被工作流依赖或并发组限制。
多个 iOS 仓库共用 macOS CI 时,怎样分配并发?
可以先按工作负载分组,例如快速单元测试、完整构建和签名发布,再用 Runner 组及标签路由到共享池或隔离池。共享池适合任务时间和权限要求接近的仓库;发布任务若有凭证、访问范围或稳定性要求,应单独限制可访问的仓库和工作流。分配后仍需核对各组的排队时间,避免总容量够用、特定标签却长期无空闲节点。
Mac Runner 应按平均工作流数量还是高峰并发配置?
平均值适合评估长期资源利用,不足以保证发布窗口或集中合并时的等待体验。先观察团队真正关心的高峰时段,记录同时需要执行的 macOS Job 数量和持续时间,再以目标等待时间决定常驻容量。若高峰短暂且可接受排队,可把额外容量作为临时扩容;不要仅凭一次峰值把所有需求变成长期闲置节点。
怎么判断 CI 排队是 Runner 不够,还是构建步骤拖慢?
对照 Job 的等待区间、运行区间和 Runner 状态:长时间等待且匹配的节点都在执行,才支持容量不足的判断;节点空闲但任务仍排队,应先查标签、Runner 组权限、离线状态和工作流依赖。若任务已开始但总耗时变长,则拆看依赖安装、缓存恢复、编译、测试和签名步骤。增加节点不会缩短执行中的慢步骤,也无法绕过串行依赖。
为 iOS 并行构建配置专属 Mac 算力
用 Zutcloud 独享 Apple M4 裸金属 Mac,为每个并行构建任务提供稳定的原生 macOS 环境。
从每月 100.9 美元的 16GB 配置起步,也可选择 24GB 高性能方案,按实际并发需求规划预算。 立即订购