若把每台云 Mac 都当作「又一个 Runner」,迟早会出现生产签名证书出现在 fork PR 任务里、或制品从未在接近上架环境的硬件上编译等问题。本文为 2026 年平台工程团队说明:谁需要拆分池、三种隔离模型对比矩阵、密钥如何按环境路由,以及在 NodeMac 独占 Mac mini M4 上可执行的九步落地清单(基于 SSH 运维)。
若您已在运行 自托管 GitHub Actions macOS Runner,环境拆分是接入第二条产品线或外部贡献者之前的必经成熟度关卡。
混合池为何会同时制造安全与发布风险
Apple 工具链鼓励长期状态:描述文件、Xcode 缓存、派生数据与公证凭证对开发很方便,但若同一系统用户既跑 fork 工作流又跑上架上传,攻击面与审计成本会同步放大。
- PR 脚本的爆炸半径:恶意或粗心的
run:步骤可读取 Runner 家目录;若磁盘上曾存放 App Store Connect API 密钥,即存在被读取风险。 - 发布质量不确定:预发机安装测试版 Xcode 或调整 Rosetta 后,下一单生产任务可能继承这些变更,除非采用不可变镜像或分主机。
- 审计疲劳:合规常问「哪些机器接触过客户数据或签名材料」;单池只能回答「全部」,问卷更长、发版更慢。
经验法则:凡可由外部贡献者 pull_request 触发的工作流,其标签不得与持有生产证书的工作流共用 Runner——与分支保护无关。
决策矩阵:Mac CI 分层应隔离到什么程度?
| 池模型 | 典型每月运维工时 | 爆炸半径 | 适用场景 |
|---|---|---|---|
| 单一共享池 | 低于 8 工程师小时 | 最高 | 仅内部仓库、无 fork 构建、无上架上传 |
| 逻辑拆分(标签+环境) | 12~20 工程师小时 | 中等 | 贡献者可信、GitHub Environment 规则严、密钥按环境隔离 |
| 物理拆分(每层专用 Mac) | 24~40 工程师小时 | 最低 | 强监管行业、公共开源、或移动与 AI Agent 工作负载并行 |
密钥、签名与可审计的晋升路径
隔离不仅是机器,更是凭证如何流动。生产 Runner 应仅通过带必填审核人的 GitHub Environment 注入密钥;预发 Runner 使用另一命名空间——即便两环境位于同一云区域。
- 为每个密钥标注层级:罗列 App Store Connect 密钥、企业分发描述文件与第三方 SaaS Token;凡能触达对外制品的,只能出现在带
prod标签的主机。 - 使用晋升式工作流:预发产出未签名或 ad-hoc 制品,再通过
workflow_dispatch或受保护分支触发仅跑在runs-on: [self-hosted, macOS, prod]的流水线。 - 事故后 24 小时内轮换:若误将 fork PR 跑到错误标签,值班手册应包含清空钥匙串与作废 API 密钥。
- 磁盘快照策略分离:预发机可配置每周自动清理;生产机仅在维护窗内做受控升级。
- 记录机器标识:将序列号或 NodeMac 实例 ID 与 Runner 名称一并存档,便于审计追溯。
标签速查:让调度器无法「误接单」
| 标签前缀 | 预期任务 | 禁止触发 |
|---|---|---|
| mac-ci-dev | 功能分支、实验 Xcode | Tag、release/* 保护路径 |
| mac-ci-stg | 主干集成、TestFlight 内测 | 未经人工批准的 fork PR |
| mac-ci-prod | 商店上传、公证、企业 IPA | 外部协作者的 pull_request |
在 NodeMac 云 Mac 上部署拆分池的九个步骤
下列步骤假设您已通过 SSH/VNC 使用 NodeMac 在香港、东京、首尔、新加坡或美国租用的独占 Mac mini M4。连接与账号说明见 帮助中心。
- 至少租用两台 Mac mini——一台预发、一台生产;若 AI Agent 与 Xcode 签名必须硬隔离,再增一台沙箱层。
- 拆分 OS 用户(如
runner-stg与runner-prod),避免家目录泄漏跨层。 - 注册不同 GitHub Runner 名称,每机仅挂本层标签;勿在同一 OS 用户上混挂两套标签族。
- 刻意对齐 Xcode 版本策略:生产锁定单一构建;预发最多落后 一个 次版本以便提前暴露编译回归。
- 为生产配置 GitHub Environment 保护规则,含首次贡献者必填审核人。
- 仅对预发自动化磁盘清理:可用 cron 在剩余空间低于 120 GB 时清理 DerivedData;生产应告警而非静默删缓存。
- 导出遥测:将 Runner 日志送入可观测平台;当生产机任务耗时超过滚动中位数的 2 倍 时告警。
- 每季度演习:模拟 fork PR 申请生产标签,确认在工作流图层面即被拒绝。
- 文档化回滚:保留上一份
.xip,目标在 45 分钟 内完成重装演练。
常见问题
是否必须为预发和生产各买一台物理 Mac?
不一定,但必须拆分 Runner 身份、标签与密钥作用域,确保生产任务不会被同时执行未信任 PR 工作流的机器接取。每层使用独立 Mac mini M4 是最强隔离,也更符合监管问卷的答法。
生产 Mac 上应允许多少并发任务?
涉及签名与制品上传的发布构建建议每台先只跑 1 个并发。预发池在磁盘 IO、Swift 包图规模与多模拟器 UI 测试允许时,可在每台 M4 上跑 2~4 个较轻任务。
如何最快发现环境串线?
当工作流使用生产标签却来自 pull_request 事件时告警,并监控预发机是否误存 App Store Connect 密钥或描述文件;接入新移动团队时可配合 VNC 抽查。
需要地理分布式池时,可在 港、日、韩、新、美 节点各布预发机以贴近开发者网络路径,同时把生产放在更靠近公证链路的区域。通过 套餐页面 按层配机,避免单机过载。
Mac mini M4 使分层 CI 在成本上可行:Apple Silicon 在并行 Xcode 任务下仍保持较高能效,闲置功耗足够低,专用生产 Runner 长期在线也不显得浪费。NodeMac 提供独占物理 Mac mini而非超售虚拟机,并同时支持 SSH 与 VNC,便于交互排查签名失败。节点覆盖香港、日本、韩国、新加坡与美国,预发可贴近工程师,生产可贴近公证与上架流程,无需一次性资本开支。按月租用 可在扩展整队机器前先把拆分池模型跑通并量化 TCO。