使用 Xcode Cloud 构建、交付并实现自动化
Build, deliver, and automate with Xcode Cloud
2026年6月10日
一句话判断
Xcode Cloud 这次没搞大新闻,但通过原生支持多 Git 仓库(Additional repositories)和极简的引导流程,彻底让中小团队自建 iOS CI/CD 变成了伪需求。
这场 Session 讲了什么
以前搞 iOS 的持续集成和持续交付(CI/CD),配证书、搞 Mac mini 农场、写 GitHub Actions 脚本能让人掉光头发。Xcode Cloud 出来后好了点,但遇到多仓库依赖和复杂分发时还是有点折腾。今年 Apple 没造新轮子,而是把重心放在了“扫除剩余痛点”上。
全新的引导助手(Onboarding Assistant)让你点几下就能把 iOS 和 macOS App 接入云端。最实用的是新增了额外仓库(Additional repositories)支持。如果你的项目把 UI 组件库或网络层拆分到了独立的 Git 仓库,现在可以直接在 Xcode Cloud 里挂载,不用再写恶心的 ci_post_clone.sh 脚本去手动拉代码了。
这对独立开发者和 50 人以下的中小团队影响最大。你基本可以把维护 Jenkins 或 GitHub Actions 的精力省下来,把买 Mac mini 的钱用来给团队买咖啡。Apple 正在用这种“免运维”的体验,把开发者死死锁在自己的生态里。
值得深挖的点
额外仓库(Additional repositories)的原生支持
现代 iOS 工程早就不是单体仓库(Monorepo)的天下了。很多团队把基础库拆成独立 repo,通过 Swift Package Manager (SPM) 引入。以前 Xcode Cloud 只能拉主仓库,导致 SPM 拉取私有库或者本地 path 依赖时经常失败。开发者只能靠 ci_scripts/ci_post_clone.sh 脚本注入 SSH key 去手动 clone,既丑陋又容易因为权限问题导致构建随机失败。
Apple 这次选择在 UI 层面原生支持挂载额外 repo,而不是去增强脚本的系统权限。这个 trade-off 很聪明:好处是配置完全可视化,仓库访问权限由 Apple 托管,安全且易于审计;坑在于,如果你的依赖关系极其复杂(比如嵌套了多层的私有 SPM),这种 UI 配置可能会显得不够灵活。但无论如何,这直接干掉了 80% 的自定义 clone 脚本,让 ci_scripts 回归了它本该处理简单环境变量的定位。
Webhooks 与自动化工作流的闭环
Xcode Cloud 自身的 Dashboard 对个人开发者够用,但企业级团队需要把构建状态推送到 Slack、飞书,或者触发内部的自动化测试平台。这次 Session 详细展示了 Webhooks 的配置和 payload 结构。
相比于 GitHub Actions 那种万物皆 Action 的庞大生态,Xcode Cloud 保持了极大的克制,只做纯粹的“事件触发器”。这意味着你不需要学习 Apple 特有的 CI 语法,只要你的后端能接收标准 JSON 就行。这种设计极大地降低了和现有 DevOps 工具链(如 Jira, 内部发布系统)集成的成本。你只需要写一个几十行的 Serverless 函数,就能把 Xcode Cloud 的构建结果无缝接入公司的内部系统。
代码片段
1. 瘦身后的 ci_post_clone.sh
场景:有了 Additional repositories 支持后,你的克隆后脚本(post-clone script)再也不需要处理复杂的 SSH 密钥和 git clone 逻辑了,只需专注环境配置。
#!/bin/sh
# 现在的 ci_post_clone.sh 只需要处理简单的环境变量和缓存
# 额外的私有仓库已经在 Xcode Cloud UI 中配置好了,会自动拉取
# 设置 SPM 缓存目录,加速后续构建
export SPM_CACHE_DIR="$CI_WORKSPACE/.spm_cache"
mkdir -p "$SPM_CACHE_DIR"
# 如果是 Release 构建,注入特定的编译宏
if [[ "$CI_WORKFLOW" == "Release" ]]; then
export SWIFT_ACTIVE_COMPILATION_CONDITIONS="RELEASE_BUILD"
fi
echo "环境准备完毕,等待 Xcode Cloud 自动处理依赖..."
坑:别忘了给 ci_post_clone.sh 加上执行权限(chmod +x),这是新手接入 Xcode Cloud 时最常踩的坑,没有执行权限会导致构建直接静默失败。
2. 解析 Webhook Payload 推送飞书/Slack
场景:接收 Xcode Cloud 的 Webhook 事件,提取构建状态和 TestFlight 链接,推送到团队的沟通工具。
// 使用 Vapor 或 Hummingbird 等 Swift 后端框架接收 Webhook
struct XcodeCloudPayload: Decodable {
let buildNumber: String
let workflowName: String
let status: String // 例如 "SUCCEEDED", "FAILED"
let testflightUrl: String?
}
func handleWebhook(_ payload: XcodeCloudPayload) async throws {
// 只关注成功或失败的最终状态,忽略中间状态
guard payload.status == "SUCCEEDED" || payload.status == "FAILED" else { return }
let emoji = payload.status == "SUCCEEDED" ? "✅" : "❌"
let message = """
\(emoji) *Xcode Cloud 构建通知*
工作流: \(payload.workflowName)
版本号: \(payload.buildNumber)
状态: \(payload.status)
TestFlight 链接: \(payload.testflightUrl ?? "暂无")
"""
// 调用飞书或 Slack 的 Incoming Webhook API 发送消息
try await sendMessageToChatApp(message)
}
坑:Xcode Cloud 在构建过程中会触发多次 Webhook(如 Started, Building, Testing, Finished),你的接收端必须做好幂等性处理或状态过滤,否则群里会被消息轰炸。
最佳实践
老项目先别急着删掉现有的 GitHub Actions 或 Jenkins 配置。建议在 Xcode Cloud 里建一个平行的 TestFlight 分发工作流(Workflow),让两个 CI 系统同时跑两周。对比构建速度、缓存命中率和排错成本,确认 Xcode Cloud 的 Additional repositories 能完美兼容你们的私有 SPM 依赖后,再做全面迁移。
新项目无脑选 Xcode Cloud。直接在 Xcode 的 Report Navigator 里使用引导助手(Onboarding Assistant),把 iOS 和 macOS 目标(Target)一起接入。
实战中极其容易踩的一个坑是分支匹配策略。当你配置额外仓库时,Xcode Cloud 默认会尝试拉取与主仓库同名的分支。如果你的主仓库在开发 feature/login,但基础组件库只有 main 分支,构建就会失败。必须在 Xcode Cloud 的 Workflow 设置里,为额外仓库显式指定 Fallback 分支(如 main 或 develop)。
还有什么值得关注
- 临时虚拟机(Ephemeral VMs)的安全承诺:Apple 再次强调源码只在构建时拉取,构建完即销毁,绝不落盘。这对金融或医疗类 App 来说,是直接拿来做安全合规审计的绝佳背书。
- macOS App 的无缝接入:同一个 Workspace 里的 macOS 和 iOS App 现在可以极其顺滑地分别建立 Workflow,开发跨平台 App 的团队不用再跨项目折腾配置了。
- TestFlight 分发直连:现在可以直接在 Xcode 里配置分发 Workflow 并创建 App Store Connect 记录,省去了去网页端点来点去建 App 的繁琐步骤。