维护 OpenClaw 分叉或插件 的团队,在 2026 年往往同时面对两条线:上游 OpenClaw CI 里的 macos-node、macos-swift 与 checks-node-compat-node22 需要真 macOS;而 GitHub 托管 macOS 分钟费与队列又推高成本。本文专注在远程独享 Mac 上自建 GitHub Actions Runner,用 macOS 标签池 承接 OpenClaw 原生 lane,并用只读 Webhook + Lobster 多步工作流做失败 triage——不写 Gateway 18789 安装、不做六地节点横评(节点与 TCO 见 Runner 节点与 TCO 文)。套餐见 定价方案,美东/美西公开结账见 美东结账、美西结账,Runner 运维见 帮助中心。
一、托管 macOS Runner vs 远程 Mac 自建:OpenClaw CI 场景下的决策表
根据 OpenClaw CI 文档,macos-node 在变更触及 macOS 相关源码时运行 TypeScript 测试;macos-swift 负责 Swift lint/构建/测试;手动 workflow_dispatch 会绕过智能 scope、拉起完整图(含 Node 22 兼容 lane)。官方仓库默认走 Blacksmith macos-latest 族 Runner,fork 维护者若无法稳定占用上游队列,就需要自己的 macOS 标签池。
GitHub 托管 macOS 按分钟计费,适合低频 PR;自建则在远程 M4 上换「固定席位 + 持久 node_modules / DerivedData」,更适合日更 main、插件契约分片、以及要对齐上游 pnpm check 本地等价命令的团队。对比六地节点与日租—月租算例请读 六地 Runner TCO 文,本篇只回答「如何对接 OpenClaw lane」。常驻 Agent/Gateway 部署分工见 OpenClaw 远程 Mac 实操文(一句:Gateway 管对话与工具面,CI Runner 管编译与测试)。
| 路径 | OpenClaw CI 适配 | 主要代价 |
|---|---|---|
GitHub 托管 macos-latest |
零运维跑上游 workflow;fork 难保证与官方同队列/缓存。 | 分钟费;macos-swift 冷启动慢;高峰排队。 |
| 远程 Mac 自建 Runner | 用 label 映射 macos-node / macos-swift;可固定 Node 22、pnpm store。 |
需维护 Runner 升级、磁盘与并发互斥。 |
| 仅 Linux 托管 + 跳过 macOS lane | 适合纯文档/Node 改动;不能替代 Swift/macOS 测试。 | 合并前仍需手动或定时跑 macOS 全量。 |
workflow_dispatch 全量 CI,或 fork 上 macos-node 经常排队超过 15 分钟,优先规划至少一台带 openclaw-macos-node 标签的自建机,而不是继续叠托管分钟。插件维护者还可把「托管分钟费 + 人工盯失败」与「一台 M4 月租」做 90 天对比,通常在全量 dispatch 场景下更容易回本。二、环境清单:Xcode CLT、Node 22 与 CI 用户隔离
OpenClaw 上游在 Linux 上跑大部分 Node shard,但 macos-node 与 checks-node-compat-node22 明确要求 Node 22(见 CI 文档中的 compat lane 与本地 pnpm check 等价命令)。在自建 Runner 上建议:
- Xcode Command Line Tools 与目标 Xcode 小版本与团队冻结策略一致;Swift lane 需完整 Xcode,而非仅 CLT。
- Node 22.x 用
fnm/mise固定,并在~/.zprofile对 CI 用户生效;workflow 内仍建议actions/setup-node双保险。 - pnpm 版本与上游
packageManager字段对齐;缓存目录放在 CI 用户家目录,避免与个人开发混用。 - 专用 Unix 用户(如
runner)安装actions-runner,不要用日常 Apple ID 或含聊天/浏览器密钥的同一用户跑 job。 - 资源上限:用
ulimit、Activity Monitor 或memory_pressure观察;24GB 机型再考虑并行第二 job。
xcode-select -p指向预期 Xcode;xcodebuild -version与文档一致。node -v为 v22.x;pnpm -v与仓库锁文件匹配。- CI 用户可无密码执行 Runner 服务(
launchd),SSH 断开仍存活。 - 磁盘剩余 > 25%(Swift DerivedData + pnpm store 增长快)。
- 仓库 Secrets 仅注入必要 PAT,推理/Webhook 密钥与签名证书分库分 Secret。
Apple 平台 API 与签名行为以 Apple Developer Documentation 为准;Node 版本政策见 nodejs.org。
三、Runner 注册与 macOS 标签池(HowTo)
按 GitHub 官方文档 在远程 Mac 注册 Runner。对 OpenClaw fork,推荐把上游 job 的 runs-on 映射到自建标签,而不是复用模糊的 self-hosted。
# 在 ~/actions-runner 目录 ./config.sh --url https://github.com/YOUR_ORG/YOUR_FORK \ --token YOUR_REGISTRATION_TOKEN \ --labels self-hosted,macOS,ARM64,openclaw-macos-node,openclaw-m4-16 \ --name nuv-openclaw-macos-node-01 sudo ./svc.sh install sudo ./svc.sh start
标签池建议(按 lane 拆分):
openclaw-macos-node— 对应上游macos-node(TypeScript/Vitest macOS 路径)。openclaw-macos-swift— 对应macos-swift;CPU/内存占用更高,勿与 node lane 默认并行在同一台 16GB 机。openclaw-node22— 可选,用于手动 dispatch 的 Node 22 compat 或本地pnpm check冒烟。openclaw-m4-16/openclaw-m4-24— 硬件档位,便于 workflow 里做矩阵或容量规划。
jobs:
macos-node:
runs-on: [self-hosted, macOS, openclaw-macos-node]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
- run: pnpm test --filter macos-relevant
签名、notarization 等副作用步骤请加 concurrency: { group: codesign-macos, cancel-in-progress: false },避免两把钥匙串同时解锁。更多 SSH/Runner 守护说明见 帮助中心。
四、对接 OpenClaw CI / dispatch 与只读 Webhook
上游 CI 在 push/PR 时由 preflight 决定 lane;你可在 fork 中保留该逻辑,仅把 macOS job 的 runs-on 改到自建池。需要全量验证时,用官方支持的手动 dispatch(文档示例):
gh workflow run ci.yml --ref main gh workflow run ci.yml --ref main -f target_ref=your-branch -f include_android=true
只读 Webhook 推理层(推荐分阶段):在 CI 失败 triage 场景,宜先订阅只读事件(如 workflow_run.completed、check_run.completed、workflow_job.completed),把 payload 元数据(仓库、分支、结论、URL)送入网关或轻量接收端,不要在第一阶段申请 Contents 写权限或自动 merge。验签通过后,由 Agent 拉取公开日志链接或已授权的 Actions API 只读范围做摘要;确认稳定后再扩权(评论 PR、打 label 等)。
| 阶段 | Webhook / 权限 | 用途 |
|---|---|---|
| Phase 0 | 只读 + workflow_run / check_run |
失败通知、排队监控、Lobster triage 输入。 |
| Phase 1 | 增加 Actions 日志只读 PAT | 拉取 job 日志片段、关联 macos-node 失败 shard。 |
| Phase 2 | 受控写(issue comment、label) | 自动打 ci-failure、@值班;需审批策略。 |
五、M4 16GB / 24GB 并发简表(单机标签池)
以下为OpenClaw macOS lane 的务实并发建议(非 SLA;与工程体积、插件数量强相关)。需要多地域或并联席位扩容时,参考 TCO 文中的节点与并联策略,本篇不展开六地横评。
| 档位 | 建议并行 | 适合绑定的 label | 风险点 |
|---|---|---|---|
| M4 16GB | 1× macos-node 或 1× 轻量 Swift;避免双 job 同时跑。 |
openclaw-macos-node + openclaw-m4-16 |
内存压力导致 Vitest OOM;DerivedData 与 pnpm store 争磁盘。 |
| M4 24GB | 1× macos-node + 1× 非峰值 Swift 检查;或 2× node 分片错开。 |
openclaw-m4-24;Swift 仍建议独立 Runner 名。 |
并行 Swift 编译仍可能触发内存警告;应用 concurrency 分组。 |
| 双机并联 | 一台固定 node,一台固定 swift;用 label 路由,不用同一 Runner 混跑。 | openclaw-macos-swift 独占 |
两台机缓存不共享;需各自预热依赖。 |
Nuvcloud 提供多节点 M4 裸金属、内存与 SSD 扩容选项,适合把上述标签池做成固定 CI 席位;具体可用区与价格以 定价页 与结账页为准,本文不承诺可用性或排队 SLA。
六、Lobster 工作流:CI 失败日志 triage 可复现片段
Lobster 把多步工具链收成一次确定性调用,带审批点与 resumeToken,适合「CI 红了 → 拉日志 → 分类 → 人类确认 → 发摘要」而非让 LLM 逐步乱调工具。先在 Agent 配置里 alsoAllow: ["lobster"],再下发 pipeline。
{
"action": "run",
"pipeline": "exec --json --shell 'gh run list --workflow ci.yml --limit 5 --json databaseId,conclusion,headBranch' | exec --stdin json --shell 'gh run view $ID --log-failed' | exec --stdin json --shell 'node scripts/ci-triage-summarize.mjs' | approve --preview-from-stdin --limit 3 --prompt '将摘要发到值班频道?'",
"timeoutMs": 120000,
"maxStdoutBytes": 512000
}
对应 .lobster 工作流文件可把步骤拆为 collect → classify → approval → notify(见 Lobster 文档 workflow files 一节)。当 status 为 needs_approval 时,用 resume 继续:
{
"action": "resume",
"token": "<resumeToken>",
"approve": true
}
可复现 triage 习惯:把每次失败的 run_id、触发的 label(如 openclaw-macos-node)、首段 stderr 哈希写入团队 wiki;Lobster 输出 JSON 进 issue 评论前,务必人工看一眼是否含 Secrets 片段。若 pipeline 超时,按文档提高 timeoutMs 或拆分「拉日志」与「LLM 总结」两步。建议为每个失败 run 保留 7 天只读归档,便于对比 flaky 与真实回归。
七、常见问题(FAQ)
Q1:Runner 显示 Offline 怎么办?
检查 launchd 服务是否运行、注册 token 是否过期、磁盘是否满。在 GitHub → Settings → Actions → Runners 移除后重新 config.sh;详见 自建 Runner 文档。
Q2:macos-node 报 Node 版本不对?
对齐 Node 22:Runner 上 node -v、workflow setup-node、以及 checks-node-compat-node22 三者一致;清理旧的 ~/.npm 全局缓存。
Q3:Swift / SDK 找不到?
确认完整 Xcode 已安装且 sudo xcodebuild -license accept;macos-swift job 不要跑在仅 CLT 的机器上。
Q4:只读 Webhook 一直 403?
核对 secret、HTTPS 证书、反代路径;GitHub App 权限是否包含对应事件;网关是否把 PR 正文误当 shell 指令执行(应只解析元数据)。
Q5:与 openclaw doctor 怎么区分?doctor 是安装/网关健康检查;CI 红在 Actions job 日志。用 Lobster + gh run view 排 CI,不要用 onboard 文档替代 workflow 排障。
Q6:能否只跑 Linux、跳过 macOS?
可以合并纯 Node 改动,但合并 Swift/ macOS 相关 PR 前必须至少手动 workflow_dispatch 一次全量,否则与上游 preflight 意图冲突。
Q7:fork 与上游共用 Runner 安全吗?
不建议。上游 PR 与 fork 应分 Runner 组、分 Secrets;防供应链脚本读取 fork 外的签名材料。
Q8:Lobster 返回 invalid JSON?
确保 pipeline 每步 stdout 仅为 JSON;增大 maxStdoutBytes;检查是否把人类可读日志直接 pipe 进下一步而未用 --json 包装。
Q9:托管与自建能否混用?
可以:例如 PR 用托管、main 的 macos-swift 用自建;用 if: 或不同 workflow 文件区分。
更多文章见 技术博客 索引。
在云端 Mac mini 上,OpenClaw CI 更稳、更易扩容
把 macos-node / macos-swift 放到远程独享 M4 上,本质是买下可预测算力与标签池弹性:Nuvcloud 裸金属 Mac mini 提供原生 Unix、适合 7×24 Runner 的低功耗稳定性,并可按需升级 24GB、扩容 SSD 或并联第二台专跑 Swift lane——与只读 Webhook + Lobster triage 组合时,DevOps 不必再盯托管队列。
若你正在为 OpenClaw fork 规划 CI 池,从一台带 openclaw-macos-node 标签的 M4 开始最省事——查看套餐与节点,再按本篇清单注册 Runner 与 Webhook。