Extend your Xcode Cloud workflows
Developer Tools 进阶 20m

扩展你的 Xcode Cloud 工作流

Extend your Xcode Cloud workflows

2024年6月10日

在 Apple 官方观看视频

一句话判断

Xcode Cloud 新增了手动触发工作流、自定义别名(Custom Aliases)和 ci_scripts 自定义脚本三大能力,让你的 CI 从”代码推送就跑”进化到”按需触发、版本统一、环境可控”。

这场 Session 讲了什么

Xcode Cloud 是 Apple 内置于 Xcode 和 App Store Connect 的持续集成和交付服务。所有 Apple Developer Program 会员每月有 25 小时的免费构建时间。这场 Session 聚焦在如何扩展和规模化你的工作流。

工作流由四个要素组成:Environment(环境变量和 Xcode/macOS 版本)、Start Conditions(触发条件)、Build Actions(构建、测试、分析、归档)、Post Actions(Slack 通知、TestFlight 分发等)。

今年新增了三个关键能力。手动触发条件让你可以创建只在需要时才运行的工作流,比如专门跑集成测试。自定义别名让你定义团队共享的 Xcode/macOS 版本别名,更新一处所有使用该别名的工作流都跟着变。自定义脚本(ci_scripts)让你在构建流程的关键节点注入自定义逻辑,比如在测试前检查依赖服务是否在线。

Session 用一个实际场景串联了这三个功能:团队在现有主分支工作流之外,新建了一个手动触发的集成测试工作流,用自定义别名确保两个工作流使用相同的工具链版本,用 ci_scripts 在测试前验证测试服务器状态。

值得深挖的点

自定义别名解决团队版本同步问题

在团队协作中,Xcode Cloud 的工作流版本管理是个实际痛点。你有多个工作流——主分支构建、PR 测试、集成测试——它们需要跑在同一个 Xcode 和 macOS 版本上。以前每次版本升级都得逐个修改每个工作流,容易遗漏。

Custom Aliases 解决了这个问题。你在 App Store Connect 中定义一个别名,比如叫 “Team Preference”,指向 Xcode 15.3。然后所有工作流都引用这个别名。下次需要升级工具链时,只需更新别名的指向,所有工作流自动跟随。

Xcode Cloud 已经提供了一些内置别名如 “latest release”,自定义别名是同一概念的团队级别扩展。你可以在 App Store Connect 的 Manage Custom Aliases 界面创建和管理,也可以直接从工作流编辑器的版本选择器下拉菜单中快速创建。别名的适用范围是 App 级别的,同一个 App 下所有工作流共享。

ci_scripts 的执行时机与环境变量

自定义脚本放在仓库根目录的 ci_scripts 文件夹中,文件名决定了执行时机。ci_post_clone.sh 在仓库克隆后执行,ci_pre_xcodebuild.sh 在 xcodebuild 运行前执行,ci_post_xcodebuild.sh 在 xcodebuild 运行后执行。

脚本可以访问工作流中定义的所有环境变量,以及 Xcode Cloud 提供的内置环境变量。内置变量包括 CI_WORKFLOW(工作流名称)、CI_BRANCH(分支名)、CI_COMMIT(提交哈希)等完整集合。

一个实用模式是在 ci_pre_xcodebuild.sh 中检查外部依赖服务的健康状态。如果服务不可用,脚本可以跳过测试步骤而不是让它失败。这避免了因外部服务问题导致的构建失败通知疲劳。

代码片段

创建手动触发工作流

# 在 App Store Connect > Manage Workflows 中:
# 1. 复制现有工作流
# 2. 移除原有的 Branch/PR/Tag 触发条件
# 3. 添加 Manual Start Condition
# 4. 可以选择关联特定分支或保持 "any branch"

# 工作流配置示例:
# 名称: Integration Tests
# 触发条件: Manual (手动)
# 关联分支: Any
# Build Action: Test > IntegrationTests test plan
# Post Actions: 无(手动触发的测试不需要自动分发)

使用 Custom Aliases 统一工具链版本

# 在 App Store Connect > Manage Custom Aliases 中:
# 创建 Xcode 别名:
#   名称: Team Preference
#   指向: Xcode 15.3
#
# 创建 macOS 别名:
#   名称: Team Preference
#   指向: macOS Sonoma 14.4

# 在工作流中引用:
# Environment > Xcode version > Team Preference
# Environment > macOS version > Team Preference

# 更新别名后,所有引用该别名的工作流自动切换版本

ci_scripts 检查测试服务器状态

#!/bin/bash
# 文件: ci_scripts/ci_pre_xcodebuild.sh
# 在测试运行前检查依赖服务是否在线

set -euo pipefail

# Xcode Cloud 提供的环境变量
echo "Running workflow: $CI_WORKFLOW"
echo "On branch: $CI_BRANCH"

# 检查测试服务器是否在线
TEST_SERVER="https://test-api.example.com/health"
HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$TEST_SERVER")

if [ "$HTTP_STATUS" != "200" ]; then
    echo "警告: 测试服务器不可用 (HTTP $HTTP_STATUS)"
    echo "跳过集成测试..."
    # 可以设置环境变量让测试代码感知
    echo "SKIP_INTEGRATION_TESTS=1" >> "$CI_ENVIRONMENT_FILE"
else
    echo "测试服务器在线,继续执行测试"
fi

坑点:ci_scripts 必须有可执行权限(chmod +x)。如果你忘记给脚本加执行权限,Xcode Cloud 会跳过它而不报错,这可能让你困惑为什么脚本没有执行。另外 $CI_ENVIRONMENT_FILE 是 Xcode Cloud 提供的特殊路径,写入这个文件的环境变量可以在后续构建步骤中使用。

最佳实践

如果你的项目刚接触 Xcode Cloud,从最简单的工作流开始:代码推送到 main 分支时构建并运行单元测试,成功后分发到 TestFlight。等团队熟悉后再引入手动触发的工作流来处理集成测试等特殊场景。始终使用自定义别名管理工具链版本——这个习惯从第一天就该建立,比事后补要轻松得多。ci_scripts 的典型用法包括:检查依赖服务状态、安装额外工具、根据分支名决定构建配置。保持脚本简单,复杂逻辑留在应用代码里。

还有什么值得关注

  • Apple Developer Program 每月 25 小时免费构建时间,合理规划工作流可以充分利用
  • 自定义脚本的环境变量完整参考文档在 Xcode Cloud 文档的 “Environment variable reference” 页面
  • Xcode 16 中 Swift Package 的解析不再阻塞构建启动,包解析和构建可以并行进行
WWDC 2024