构建脚本需要令牌,却担心它出现在日志里?
最快做法:普通配置用工作流环境变量;敏感值标记为 Secret,并按工作流和触发任务限制使用范围。

适合使用 Xcode Cloud 构建或测试、需要注入环境配置的独立开发者;维护多个工作流并想复用配置的小团队;以及通过自定义脚本连接外部服务的发布维护者。

01

配置前先把配置、凭据和文件分开

假设你的构建后脚本要把产物上传到外部服务。你将令牌设成 Secret,但脚本又用 echo "$UPLOAD_TOKEN" 输出调试信息。Secret 设置可以让 Xcode Cloud 在构建日志中将该变量值替换为星号;但这不等于该脚本不再拥有读取凭据的能力,也不意味着所有工作流和触发来源都适合获得这个令牌。Apple 关于自定义构建脚本和 Secret 日志处理的说明

先按用途分类,再决定放在哪里:

内容类型 例子 建议处理方式 主要风险
普通配置 环境名称、非敏感上传目录 配置为工作流环境变量 配错工作流会导致脚本使用错误设置
敏感凭据 上传令牌、访问密钥 标记为 Secret,仅分配给确实需要的工作流 日志脱敏不等于访问权限隔离
凭据文件 含私钥或认证信息的文件 不提交到代码仓库;通过适用于该凭据的安全流程提供 文件可能随代码暴露,也可能被脚本写入日志或产物

自定义变量由你设定;共享变量可以供你选定的多个工作流复用;预定义变量则由 Xcode Cloud 提供,例如当前工作流名称或构建动作。Secret 是变量的安全设置,不是另一种脚本接口。Apple 说明自定义变量可用于构建脚本或测试动作,预定义变量则有各自的可用范围和时机;不要把它们混作同一类配置。Xcode Cloud 工作流参考与环境变量参考

Xcode Cloud 自定义环境变量怎么添加?
在目标工作流的环境设置中创建变量并指定名称和值。若多个工作流需要相同配置,可建立共享变量,但创建后仍要选择要应用的工作流;“共享”不是自动授予全部工作流访问权。Apple 的共享环境变量配置步骤

02

首次设置:按工作流需要决定变量范围

选择 适合情况 你需要确认的事项
工作流变量 只有一个构建或发布工作流需要此值 变量是否配置在实际运行的 workflow 中
共享变量 多个工作流要复用相同配置 是否只勾选了确实需要访问的 workflow
预定义变量 脚本要判断构建上下文,如工作流或动作 该变量是否在当前脚本阶段可用

在 Xcode 中,Apple 文档给出的共享变量管理路径是从报告导航器进入 Cloud,打开项目的环境变量管理,再添加变量并选择工作流。App Store Connect 也提供共享变量管理入口。界面名称或具体路径可能随版本变化,操作前请对照前文链接的 Apple 当前共享变量说明,不要只凭旧截图操作。

同时检查谁能改变量、谁能改工作流。共享变量可限制编辑权限;工作流也可设置编辑限制。Apple 对工作流编辑限制的说明指出,受限工作流仅允许具有 Admin 或 App Manager 角色的团队成员修改。把变量维护和发布流程责任分清楚,避免为了“方便复用”而扩大编辑范围。Apple 的工作流策略与编辑权限说明

03

首次运行:把脚本放到正确阶段

Xcode Cloud 识别的自定义构建脚本有三个阶段。它们不是可以随意互换的入口:选择时要看脚本需要访问的资源,以及任务发生在构建前还是构建后。具体脚本规则见前文 Apple 自定义构建脚本文档。

脚本阶段 适合处理的任务 配置时留意
ci_post_clone.sh 仓库克隆后准备工具或依赖 脚本所需资源要能在该阶段取得
ci_pre_xcodebuild.sh xcodebuild 启动前的准备 缺少必需变量时应停止,而不是用空值继续
ci_post_xcodebuild.sh 构建后上传产物或执行后处理 即使 xcodebuild 失败,该脚本仍会运行;需判断是否应跳过上传

脚本放在仓库的 ci_scripts 目录,使用 Apple 识别的文件名,并提交到仓库。脚本应有 shebang 且具备可执行权限;Apple 说明缺少 shebang 或执行权限时,运行方式可能退回到 zsh,进而导致脚本失败。另一个容易漏掉的边界是:一个自定义脚本创建的文件不会自动提供给其他自定义脚本,Xcode Cloud 也会清理脚本创建的文件;不要把跨阶段持久存储当成默认能力。脚本也不能通过 sudo 获得管理员权限。

读取变量时避免把值写进命令输出。下面的示例使用明显的占位变量名;它只检查变量是否存在,不打印变量内容:

#!/bin/sh
set -eu

: "${UPLOAD_TOKEN:?UPLOAD_TOKEN is required}"

# 在此调用上传工具;不要 echo、打印或拼接输出令牌。

如果要在构建前安装第三方工具,先考虑临时构建环境这一条件:需要的工具可能必须在每次构建时准备。Apple 的技术说明明确指出,Xcode Cloud 为每次构建创建干净的临时环境,因此依赖额外辅助工具时要将安装过程纳入构建流程,而不是依赖上一次任务留下的状态。Apple TN3129:Xcode Cloud 临时构建环境与辅助工具

04

权限与日志检查:不要把脱敏当作授权

怎样避免 Xcode Cloud Secret 出现在构建日志?
创建或编辑变量时,将其标记为 Secret(在 Xcode 的界面中也可能显示为保留值脱敏的选项)。Apple 说明这会在构建日志中隐藏变量值。但脚本日志仍可能包含请求、子命令输出或用于认证的信息,因此不要主动输出令牌,也不要把“日志已脱敏”理解成“只有获准的任务能读取凭据”。Apple 关于脚本日志内容的说明

发布前逐项检查触发来源。分支变更、拉取请求、手动启动或定时任务可能对应不同工作目的;检查每个会运行脚本的 workflow 是否真的需要外部服务凭据。尤其不要仅因为变量标记为 Secret,就认定所有触发场景都适合执行上传或发布脚本。Xcode Cloud 支持按分支、拉取请求、标签或计划配置启动条件,具体范围应以当前工作流设置为准;工作流和启动条件的细节可参考前文 Apple 工作流参考。

多个工作流需要同一配置时怎么处理?
创建共享变量,再选择需要它的工作流。你仍应逐个核对分配范围:测试、拉取请求验证和正式发布工作流承担的任务不同,不要让只负责验证代码的工作流无必要地访问发布凭据。

05

首次验收:用占位值走完真实流程

先别拿正式令牌做第一次验证。按以下步骤验收配置:

  • 为测试工作流创建无权限或不可用于真实操作的占位值,确认变量名与脚本读取名一致。
  • 手动触发一次测试构建,确认目标 workflow 确实拿到了所需变量。
  • 检查脚本是否只输出“变量已配置”等状态信息,不输出变量值、认证请求头或含凭据的命令行。
  • 检查构建报告与脚本日志,确认 Secret 值按预期隐藏;同时排查脚本是否把凭据复制到文件、产物或错误信息中。
  • 暂时移除测试变量再运行一次,确认脚本以非零退出状态失败,并给出不包含秘密值的错误提示。
  • 对 ci_post_xcodebuild.sh 单独检查失败分支:由于它会在 xcodebuild 失败后仍运行,上传逻辑应根据构建结果决定是否继续。

脚本读取不到变量时,先排查什么?
先检查变量是否配置在当前运行的 workflow,名称是否完全一致,以及脚本是否在预期阶段读取它。然后再核对是否误把预定义变量当作自定义变量,或在 xcodebuild 运行前读取了只在动作之后才有的结果变量。例如,Apple 的变量参考说明 CI_XCODEBUILD_EXIT_CODE 在对应的 xcodebuild 命令运行后才可用;它不适合用于构建前判断结果。

06

后续维护:看环境需求是否超出工作流边界

继续使用 Xcode Cloud,适合构建环境可由工作流设置、脚本可在每次任务中准备依赖、并且不要求保留主机状态的情况。调整脚本,适合变量范围、阶段选择或失败处理尚未理顺的情况。若你需要持久工作区、交互式排查,或对主机状态有额外控制要求,再评估独立的远程 Mac 构建环境;不要只因某个脚本首次失败,就认定必须迁移。

你的实际需求 优先考虑 主要取舍
可重复的构建与测试,依赖能在任务中准备 继续使用 Xcode Cloud 临时环境不应被当作持久工作区
需要修正变量范围、脚本阶段或日志行为 先调整现有 workflow 需要重新运行构建验证变更
需要交互式排查或保留自定义主机状态 评估远程 Mac 需要另行评估访问方式、权限管理和持续维护责任

如果你正从“凭据为何读不到”排查到“构建环境是否需要长期保留”,可先查看 KVMNODE 的 Mac 方案页面,核对实际提供的访问和租赁信息,再判断是否符合你的构建流程。KVMNODE 的远程 Mac 可作为 Xcode Cloud 之外的环境选项;若当前任务只需短暂、可重复的云端构建,则没有必要仅为变量配置问题迁移。你也可以从 KVMNODE 中文页面了解现有服务信息,具体条件以页面为准。