结论:先让目标 iOS 项目在远程 Mac 上稳定复现,再接入 Bazel iOS 远程缓存,并用第二台 Mac 的日志证明跨机命中。适合维护 Bazel iOS 构建规则、需要团队共享构建结果的开发者与 DevOps 工程师;如果远程 Mac 上的构建基线尚未跑通,先不要把失败归因于缓存。
维护 iOS Bazel 构建规则的开发者,可按本文建立从本机基线到远程 Mac 验收的实施顺序。
构建工程师与 DevOps 工程师,可据此检查缓存读写身份、CI 接入和签名交付边界。
00第 1 步:先留下一份可复现的本机构建基线
接缓存前,先在目标项目的开发 Mac 上完成一次 Bazel 构建与测试,并确认预期产物确实生成。记录构建命令、目标、日志和产物校验结果;否则,后续即使另一台机器构建失败,也无法判断是原有规则、Apple 工具链还是缓存配置造成的。
把实际锁定值写入验收记录,不要依据网上某份配置猜版本。Bazel、rules_apple、rules_swift 与 Xcode 的兼容关系,应按项目锁定文件和对应版本的官方说明逐项核对;rules_apple 官方仓库也提示,规则需要随 Bazel 版本变化而更新。可从 rules_apple 官方仓库 核对支持范围,并在项目对应版本的规则说明中确认 Apple 工具链的要求。
| 基线项 | 记录内容 | 复测时要对照什么 |
|---|---|---|
| 规则与构建器 | Bazel、rules_apple、rules_swift 的锁定版本 |
锁定文件及规则兼容说明 |
| Apple 工具链 | 实际选中的 Xcode、SDK、命令行工具 | 远程 Mac 上的选择结果与版本输出 |
| 构建入口 | 目标、命令、关键 .bazelrc 配置 |
两台 Mac 是否执行相同目标与参数 |
| 验收证据 | 构建日志、测试结果、产物校验 | 失败信息和产物是否可重复核对 |
接入远程缓存的稳妥顺序是什么?先得到可重复的本机构建,再把缓存端点和读取、写入策略放入团队可审查的 Bazel 配置;最后在另一台 Mac 上跑相同目标。仅仅让构建命令返回成功,不足以证明缓存已经接入。
01第 2 步:在远程 Mac 上对齐 Xcode 与 SDK
连上远程 Mac 后,先确认系统实际选用的开发者目录,而不是只看机器上是否装有 Xcode。可以记录 xcode-select -p、xcodebuild -version 和项目所需的 SDK 信息,再将输出与基线逐项比较。Apple 说明,xcodebuild 等命令行工具随 Xcode 提供,使用前需安装 Xcode 并将其设为当前开发者目录;因此,单独安装 Command Line Tools 并不能替代所有 Xcode 构建要求。Apple 的 Xcode 命令行工具参考和安装命令行工具的说明可用于核对这些边界。
xcode-select -p
xcodebuild -version
如果项目通过 Bazel 管理 Apple 工具链,还要检查 DEVELOPER_DIR 与 Xcode 版本是否被一致地传给 Bazel。rules_apple 的工具链说明建议让工具链能感知 DEVELOPER_DIR 的变化;否则,更换 Xcode 后构建环境或缓存共享行为可能与预期不一致。具体做法仍应按项目锁定的规则版本复核。
远程 Mac 独立执行同一构建目标和测试,只有基线复现后才进入下一步。若此处失败,先根据日志排查 Xcode 路径、SDK、Bazel 参数、环境变量及依赖解析;不要用缓存命中与否解释一个尚未通过的远程构建。
02第 3 步:接入缓存端点并限定写入身份
Bazel 远程缓存用于保存和复用构建 action 的结果;连接后,构建会尝试读取已有结果,未命中的 action 仍可在本机执行并按权限上传结果。这不等于把 action 派发到另一台机器运行。可先在项目的 .bazelrc 或 CI 注入配置中设置缓存地址:
build --remote_cache=https://<cache-endpoint>
这只是配置入口示例,端点、认证方式和协议须由实际缓存后端确定。Bazel 官方文档列出远程缓存的数据类型、接入方式与读写选择,并提醒缓存可能包含构建产物,应按敏感数据保护;HTTP Basic Authentication 也应通过 HTTPS 传输。Bazel 远程缓存文档说明了这些行为。
权限不要默认设成“所有开发者都能写”。一种容易审查的起点是:开发者与非发布 CI 身份只读,经过审核的构建任务才写入;例如,Bazel 提供 --remote_upload_local_results=false 关闭本地构建结果上传。对不适合共享的目标,可以按规则支持的方式加上 no-remote-cache 标签。具体标记能力及配置要以项目使用的 Bazel 版本为准。
| 访问身份 | 读取缓存 | 写入缓存 | 验收证据 |
|---|---|---|---|
| 开发者或只读 CI 任务 | 按任务需要开放 | 默认关闭 | 配置中可见只读策略,日志无写入凭据 |
| 受控构建任务 | 按任务需要开放 | 审批后开放 | 身份范围、凭据注入方式和写入结果可核查 |
| 不应共享的目标 | 按项目策略决定 | 默认排除 | 目标标记及其规则支持情况已复核 |
凭据放在 CI 的秘密管理机制或受限配置中,不要写进代码库、打印到构建日志,或拼接在可能被记录的命令行里。上线前检查缓存端点访问范围、日志脱敏、任务身份和失效方式。Bazel 官方文档也明确提示:写入缓存的权限应受到控制,凭据可能赋予对缓存数据的读写能力。
缓存复用与远程执行分别改变了什么?缓存命中表示 Bazel 从缓存复用了符合 action key 的结果;远程执行表示构建 action 被调度到远端执行环境运行。启用 --remote_cache 本身不会把本机未命中的 action 变成远程 action。Bazel 的远程执行概览将远程执行描述为把构建和测试 action 分发到多台机器;这是与缓存复用不同的能力。
03第 4 步:用第二台 Mac 验证是否真正跨机命中
第一台 Mac 用基线中的目标完成构建,并确认其写入策略允许上传;随后第二台 Mac 检出相同代码,按相同工具链、目标和参数执行同一构建。两边都保存构建输出与日志,以 Bazel 对 action 的报告为证据,而不是根据耗时变短或构建成功推断缓存有效。
Bazel 的远程缓存排查文档建议检查构建输出中的 action 结果信息,并留意读取或写入缓存时的警告;目标、参数或认证不一致时,也可能造成预期外的未命中。Bazel 缓存命中排查文档提供了相应的排查思路。
跨 Mac 缓存结果不符合预期时,先检查哪些配置?按以下顺序对照:目标与命令行参数、Bazel 配置、Xcode 与 SDK、DEVELOPER_DIR 等环境变量、缓存端点、网络连通性、读取和写入身份。发现差异后只改一个变量,再执行同一测试;这样才能把修复结果与具体原因关联起来。不要将 Bazel 输出中的通用动作信息或构建成功,误当作跨机器缓存命中证明。
04第 5 步:把缓存验收与签名、打包分开
iOS 构建链路里,缓存命中、远程执行、Mac 本地执行、应用打包与代码签名是不同验收对象。Bazel 负责的 action 是否从缓存取回,要看构建日志;action 是否在远端运行,要看远程执行策略与结果;.app 或 .ipa 是否生成,则需检查项目期望的打包产物;签名还要单独验证证书、配置文件、entitlements 和最终产物。
签名与打包环节应如何安排?先按项目的 Apple 规则与远程执行环境要求确认哪些 action 可执行、工具链如何提供,再对签名资产采取独立的权限控制。发布签名通常更适合放在受控的 Mac 发布任务中:凭据不进入一般缓存写入任务,最终交付前检查产物与签名结果。Apple 的应用分发签名流程也把构建归档与分发签名导出列为需要核查的环节;项目针对 iOS 的实际流程还须遵循其对应规则和 Apple 文档,不能仅凭缓存命中放行。
05第 6 步:接入 CI,按证据决定扩大还是回退
让 CI 使用与开发者可核对的 Bazel 配置,但将 CI 身份按任务拆分:普通验证任务按策略读取缓存,受控任务才具备写入权限。随后用真实项目完成构建、测试、产物检查与签名验收,并保留缓存不可用时的日志及回退路径。缓存后端暂时不可用时,团队应事先决定是允许本机继续构建、让任务失败,还是切换到另一条经过验证的执行路径;不要等到发布任务中断后再临时改权限。
上线决策条件:
- ✅ 若远程 Mac 能复现基线、第二台 Mac 的日志证明命中、CI 身份与凭据权限通过审查,先在受控任务中试运行,再依据相同证据扩大范围。
- ⚠️ 若构建成功但没有跨机命中证据,保持当前构建方式,回查工具链、参数、网络和权限后重测;不要宣称已有性能收益。
- ❌ 若远程 Mac 无法复现基线、日志出现缓存读取或写入错误,或签名资产暴露在不受控任务中,先暂停缓存写入并修复配置;发布任务继续走已验证的独立签名流程。
上线记录至少包含:两台 Mac 的工具链与构建参数、缓存端点及权限策略、可核对的命中日志、CI 任务身份、构建测试结果、最终产物与签名检查结果。没有这些记录,就无法区分“缓存配置可用”“构建碰巧成功”和“发布结果符合预期”。
如果当前方案是让每台开发 Mac 各自保留构建结果、再靠人工核对 Xcode 配置,团队会承担环境漂移、缓存难以复用和凭据分散管理的成本;若改成通用 Linux 节点执行,又不能直接代替远程 Mac 上的 Apple 工具链与签名验收。对暂时没有合适 Mac、但需要持续运行 Apple 工具链任务的团队,租赁远程 Mac 可作为按需配置执行节点的方案;它并不会自动解决 Bazel 缓存配置,仍需按本文流程自行验证环境与权限。需要评估时,可先了解 NUKCLOUD 的远程 Mac 服务入口,再根据真实项目的运行周期判断是否需要长期在线节点,并查看远程 Mac 套餐选项。