每次提交都触发完整测试,Xcode Cloud 构建太慢,计算时长也持续消耗。

最快解法:本周先把拉取请求检查、完整测试和发布 Archive 拆成不同工作流,再启用 Auto-cancel Builds;如果主要耗时来自反复安装依赖、固定工具链或常驻服务,就采用“Xcode Cloud 轻量验证+远程 Mac 重型构建”的双轨方案。

01

谁应该先按这套方法排查

这篇文章适合每次提交都会触发完整测试、导致反馈明显变慢的独立开发者。

如果团队正在用 Xcode 27 Beta 做兼容测试,同时还要维持稳定发布链路,也应把 Beta 验证与正式 Archive 分开。

当计算时长持续增长,却无法判断问题来自排队、测试、依赖还是上传时,这份 runbook 可以帮助我们先定位,再决定是否迁移环境。

最后更新于 2026 年 9 月 4 日,版本状态与平台能力核对自 Xcode 27 Beta Release Notes 及 App Store Connect 帮助文档。

02

先拆时间线,再判断 Xcode Cloud 是否真的慢

不要只看工作流从“开始”到“完成”的总时长。我们建议把一次构建拆成以下阶段:

  • 排队等待;
  • Git 源码检出;
  • Swift Package、CocoaPods 或其他依赖准备;
  • 自定义脚本与工具安装;
  • Build 或 Analyze;
  • Test,包括模拟器启动和 UI 自动化;
  • Archive、签名与导出;
  • 上传及 App Store Connect 后台处理。

这几个阶段对应的责任不同。排队时间不等于 Mac 计算时间,App Store Connect 的处理时间也不等于 Archive 时间。Apple 的文档明确区分了构建产物上传后仍需在后台处理的阶段;如果上传长期处于 Processing 超过 24 小时,才应按异常流程处理,而不是直接归因于本地打包性能。查看构建上传状态说明

用同一条件建立基线

我们每次排查至少固定三项:

  1. 同一个 Git 提交;
  2. 同一个工作流;
  3. 同一个 Xcode 与 macOS 环境。

然后打开官方构建报告,寻找第一个持续占时的阶段。不要拿一次包含缓存命中的记录,与另一次首次安装依赖的记录直接比较。

还要把三种指标分开记录:

  • 计算时长:真正消耗构建资源的时间;
  • 等待时间:任务排队或等待后台处理的时间;
  • 反馈时间:开发者从提交代码到拿到可用结果的体感时间。

如果排队很短,但依赖准备占据大部分日志,升级计算时长并不能解决根因。如果 Build 很快,Test 和 Archive 却很重,也不应继续优化编译参数。

03

拉取请求:轻检查保留反馈,完整验证后置

拉取请求的目标是尽快发现明显回归,不是完成整个发布流程。

我们建议把默认分支更新或拉取请求触发的工作流限制为:

  • 当前 Scheme 的编译;
  • 一个代表性模拟器;
  • 关键单元测试;
  • 必要的静态检查。

设备矩阵、UI 自动化、完整回归、Archive 和 TestFlight 分发,不应默认跟随每次分支更新运行。Apple 的工作流策略文档也将“每次分支变化运行构建”和“按标签执行多设备测试、归档及 TestFlight 分发”作为不同工作流的典型组织方式。查看 Xcode Cloud 工作流策略

处理连续提交造成的重复消耗

如果开发者在几分钟内连续推送多个修复提交,旧构建通常已经失去验证价值。此时应检查每个启动条件中的 Auto-cancel Builds

Apple 文档给出的示例是:连续产生 5 个构建时,启用自动取消后,前 4 个被取消,最新提交直接进入构建。这个设置适合快速反馈工作流,但不应盲目用于需要保存完整产物的发布工作流。查看 Auto-cancel Builds 规则

检查清单:

  • [ ] 拉取请求工作流是否包含 Archive;
  • [ ] 是否默认运行全部模拟器;
  • [ ] 是否每次提交都执行上传或分发;
  • [ ] 快速反馈工作流是否开启 Auto-cancel Builds;
  • [ ] 发布工作流是否改为标签、手动或发布分支触发;
  • [ ] 取消旧构建后,是否仍保留最新提交的失败日志。
04

模拟器:按风险拆覆盖,不按设备数量堆任务

“测试更多设备”不等于“每次提交都测试所有设备”。

我们会把模拟器任务分成四层:

  1. 健康检查:确认项目能够编译并在一个代表性设备启动;
  2. 兼容测试:覆盖屏幕尺寸、系统版本或关键能力差异;
  3. UI 自动化:验证登录、购买、同步等高风险流程;
  4. 发布前回归:在候选版本上运行完整矩阵。

拉取请求阶段通常只需要第一层,加上少量关键单元测试。第二层和第三层可以按固定计划运行,第四层绑定发布候选版本。

删减矩阵前,不要凭感觉判断“应该没问题”。至少保留:

  • 测试结果包;
  • UI 失败截图;
  • 失败设备与系统版本;
  • 实际发现的缺陷记录;
  • 删减前后的失败类型对比。

Xcode Cloud 完成构建后会保存构建日志、导出产物和测试结果包;官方文档还说明,这些构建信息与产物通常可从完成后保留 30 天,正式发布工作流应主动下载归档。查看构建产物说明

05

依赖与脚本:减少每个 Action 的重复准备

Xcode Cloud 使用临时、隔离的构建环境。环境中并不会自动包含项目需要的全部第三方工具,因此 CocoaPods、额外命令行工具和自定义脚本很容易成为隐藏耗时来源。查看依赖准备规则

我们建议按日志逐项确认:

  • 源码检出是否包含过大的二进制目录;
  • Swift Package 是否每次重新解析;
  • Podfile.lock 是否提交到仓库;
  • CocoaPods 是否在每个 Action 重复安装;
  • Homebrew 工具是否按条件安装;
  • 自定义脚本是否在 Build、Test、Archive 中重复执行;
  • 私有仓库认证是否因环境变量缺失而反复失败重试。

对于 CocoaPods,Apple 建议确保 PodfilePodfile.lock 都在仓库中,并根据仓库体积、依赖更新频率和 Git 管理方式决定是否提交 Pods 目录。

让脚本只在需要时运行

Xcode Cloud 支持 ci_post_clone.shci_pre_xcodebuild.shci_post_xcodebuild.sh 等脚本类型。脚本应只完成当前阶段必要的动作,而不是把所有准备工作塞进每次构建。查看自定义脚本规则

可以利用预置环境变量判断当前工作流、触发来源和 xcodebuild 动作。例如,只有 Archive 工作流才执行上传脚本,只有夜间回归才安装额外测试工具。环境变量参考中提供了 CI_WORKFLOWCI_XCODEBUILD_ACTION 等变量,可用于减少无关脚本执行。查看环境变量参考

脚本验收清单:

  • [ ] 首行包含明确的 shebang;
  • [ ] 使用 set -e 处理失败;
  • [ ] 非必要命令不会在每个 Action 执行;
  • [ ] 私密变量开启脱敏;
  • [ ] 依赖版本由锁定文件控制;
  • [ ] 失败时返回非零退出码;
  • [ ] 脱敏日志足以确认失败发生在哪一步。
06

FAQ:计算时长不足前,先解决工作流结构

见本文中部的常见问题答案。这里最重要的判断是:计算时长不足,只说明当前使用量超过了可用额度,不代表增加额度后,反馈链路就一定会变快。

如果一个拉取请求同时执行编译、全设备测试、Archive 和上传,那么升级套餐只是允许这套结构继续消耗资源。正确顺序应是:

  1. 删除重复触发;
  2. 拆分轻量与重型任务;
  3. 修复依赖与脚本重复执行;
  4. 重新观察同一项目的使用量;
  5. 最后才评估是否需要更多额度。
07

Archive 与 TestFlight:把发布链路从日常验证中隔离

Archive 不是普通 Build 的放大版。它还涉及签名、导出、上传以及 App Store Connect 后台处理。

App Store Connect 要求先建立 App 记录,再上传构建;上传完成后,构建仍需经过 Apple 系统处理,之后才会出现在可测试或提交的列表中。查看上传与处理流程

因此,正式发布工作流更适合绑定:

  • Git 标签;
  • 明确的发布分支;
  • 手动触发;
  • 发布候选版本。

每次候选版本都应保留独立日志和产物。不要让开发分支上的快速检查与生产发布共享同一个复杂工作流,否则一次 UI 测试失败可能连带阻塞整个发布链路。

完成拆分后,用一次真实 Archive 验证:

  • [ ] 签名证书和 Provisioning Profile 是否正常;
  • [ ] 导出的产物是否可下载;
  • [ ] 上传是否成功;
  • [ ] App Store Connect 是否完成处理;
  • [ ] 失败后能否从对应阶段重新执行;
  • [ ] 产物是否已经下载到团队自己的存储位置。
08

三种环境分工:继续优化、双轨运行,还是迁移重型任务

以下决策条件比“Xcode Cloud 好不好”更有用:

继续优化 Xcode Cloud

若同时满足以下条件,继续优化:

  • [ ] 任务能够在临时环境稳定复现;
  • [ ] 依赖准备时间可控;
  • [ ] 测试能够按风险拆分;
  • [ ] 不需要常驻后台服务;
  • [ ] 失败时通过日志足以定位问题;
  • [ ] Archive 不是每次提交都执行。

采用 Xcode Cloud+远程 Mac 双轨

若出现以下情况,优先双轨:

  • 轻量 Build 和单元测试适合临时环境;
  • 多设备回归会明显拖慢反馈;
  • 正式 Archive 需要固定工具链;
  • 依赖安装或缓存恢复占据主要日志;
  • 团队既要保留云端验证,又需要随时进入主机排障。

把重型任务迁移到远程 Mac

若主要任务依赖以下条件,考虑将其迁移到常驻远程 Mac:

  • 固定的 Xcode 27 Beta 版本;
  • 持久化依赖和 DerivedData;
  • 长时间运行的后台服务;
  • 频繁的 Release Archive;
  • 需要 SSH、VNC 或终端即时排障;
  • 需要保存完整构建环境,而不是每次重新准备。

Xcode 27 Beta 截至 2026 年 9 月 4 日仍应按 Beta 工具链管理。Apple 的发布说明显示,Xcode 27 Beta 只能安装并运行在 Apple silicon Mac 上,并要求 macOS Tahoe 26.4 或更高版本;具体兼容性和已知问题应以当日 Release Notes 为准。查看 Xcode 27 Beta 发布说明

如果需要一台固定版本的 Apple silicon Mac 做负载验收,可以先参考 Xcode 27 远程 Mac 配置与负载验收。若团队还没有确定地区,也可以根据开发者所在位置查看 Mac mini M4 租赁方案,再用真实项目完成一次完整 Archive,而不是只比较纸面规格。

工作负载 Xcode Cloud 更适合 远程 Mac 更适合 推荐触发方式
拉取请求编译 ✅ 临时环境、快速反馈 ⚠️ 仅在需要即时排障时 每次拉取请求
关键单元测试 ✅ 易于拆分 ⚠️ 适合作为补充验证 每次提交或合并前
多模拟器兼容测试 ✅ 适合定时执行 ✅ 适合需要固定设备状态时 定时或发布前
UI 自动化回归 ✅ 可集中运行 ✅ 适合保留测试环境与日志 夜间或候选版本
Release Archive ⚠️ 可用,但需等待临时环境 ✅ 固定工具链、便于排障 标签、手动或发布分支
常驻服务与重型脚本 ❌ 不适合长期保持状态 ✅ 适合持续运行与 SSH 管理 手动、定时或流水线触发
09

当前方案与远程 Mac:停止迁移的条件

如果当前方案是单一 Xcode Cloud 工作流,真实缺点通常有三类:每次临时环境都要重新准备依赖,重型测试会阻塞轻量反馈,Archive 与后台处理时间也难以和普通 Build 分开观察。

如果当前方案还要求维护者频繁等待完整矩阵、重复安装工具,或在失败时只能依赖构建日志,那么继续增加计算时长并不是最直接的工程解法。更稳妥的方式是保留 Xcode Cloud 的轻量检查,再把固定 Xcode 版本、持久依赖和重型发布任务放到远程 Mac。

这类任务可以先通过 iOS 打包服务器的工作流拆分方法梳理,再决定是否租赁 MESHLAUNCH 的 Mac 环境。若只需要临时算力、版本兼容测试或一次真实 Archive 验收,租赁通常比专门购买一台长期闲置的 Mac 更灵活;但如果需要持续运行多年、依赖物理接口或承担稳定的全天候重负载,自购设备仍可能更合适。