Skip to content

OpenClaw CI 在每次推送到 main 和每个拉取请求时运行,通过 preflight 作业智能分类 diff,只有相关区域发生变化时才触发昂贵的 lanes。手动 dispatch 会绕过作用域检测并运行完整作业图,用于发布候选验证。如果你发现某条作业没跑,先检查 changelog 是否只触发了文档或作用域外的代码变更。

OpenClaw CI 流水线配置与问题排查

CI 在每次推送到 main 分支以及每个 Pull Request 时运行。preflight 作业分类 diff,并在只有不相关区域发生变更时跳过昂贵的 lanes。手动 workflow_dispatch 会绕过智能作用域,展开完整作业图用于发布候选和广泛验证。Android lanes 始终通过 include_android 选择加入。仅发布的插件覆盖在单独的 Plugin Prerelease 工作流中运行,且仅通过 Full Release Validation 或显式手动调度触发。

Pipeline 总览

Job用途运行时机
preflight检测文档变更、变更作用域、变更扩展,构建 CI manifest始终运行(非 draft 推送和 PR)
security-fast私钥检测、zizmor 工作流审计、生产 lockfile 审计始终运行(非 draft 推送和 PR)
check-dependencies生产 Knip 依赖-only pass 加未使用文件 allowlist 守卫Node 相关变更
build-artifacts构建 dist/、Control UI、内置 CLI 冒烟检查、可复用产物Node 相关变更
checks-fast-coreLinux 快速正确性通道:bundled、protocol、CI-routing 检查Node 相关变更
checks-fast-contracts-plugins-*两个分片插件契约检查Node 相关变更
checks-fast-contracts-channels-*两个分片渠道契约检查Node 相关变更
checks-node-core-*核心 Node 测试分片(排除渠道、bundled、契约、扩展 lanes)Node 相关变更
check-*分片主本地门控等价:生产类型、lint、守卫、测试类型、严格冒烟Node 相关变更
check-additional-*架构、分片边界/提示偏移、扩展守卫、包边界、运行时拓扑Node 相关变更
checks-node-compat-node22Node 22 兼容性构建和冒烟 lane手动 CI 调度(发布时)
check-docs文档格式、lint、死链检查文档变更
skills-pythonPython 技能的 Ruff + pytestPython 技能相关变更
checks-windowsWindows 特定进程/路径测试加共享运行时 import spec 回归Windows 相关变更
macos-nodemacOS TypeScript 测试 lane(使用共享构建产物)macOS 相关变更
macos-swiftmacOS 应用的 Swift lint、构建、测试macOS 相关变更
androidAndroid 两个 flavors 的单元测试加一个 debug APK 构建Android 相关变更
test-performance-agent每日 Codex 慢测试优化(可信活动后)Main CI 成功或手动调度
openclaw-performance每日/按需 Kova 运行时性能报告(mock-provider、deep-profile、GPT 5.5 live lanes)调度和手动调度

Fail-fast 顺序

  1. preflight 决定哪些 lanes 存在。docs-scopechanged-scope 逻辑是该作业内部的步骤,不是独立作业。
  2. security-fastcheck-*check-additional-*check-docsskills-python 快速失败,不等待更重的产物和平台矩阵作业。
  3. build-artifacts 与快速 Linux lanes 重叠,以便下游消费者在共享构建就绪后立即启动。
  4. 更重的平台和运行时 lanes 随后展开:checks-fast-corechecks-fast-contracts-plugins-*checks-fast-contracts-channels-*checks-node-core-*checks-windowsmacos-nodemacos-swiftandroid

GitHub 在同一个 PR 或 main ref 上有新推送时,可能会将更早的作业标记为 cancelled。只要最新运行的同一个 ref 没有失败,就视为 CI 噪音。矩阵作业使用 fail-fast: falsebuild-artifacts 直接报告嵌入的渠道、core-support-boundary、gateway-watch 失败,而非排队小型验证作业。CI 并发键已版本化(CI-v7-*),防止旧排队组中的僵尸作业无限期阻塞新的 main 运行。手动完整套件运行使用 CI-manual-v1-*,不会取消进行中的运行。

ci-timings-summary 作业为每个非 draft CI 运行上传紧凑的 ci-timings-summary 产物。它记录当前运行的 wall time、queue time、最慢作业和失败作业,因此 CI 健康检查无需反复抓取完整的 Actions 负载。

作用域与路由

作用域逻辑位于 scripts/ci-changed-scope.mjs,由 src/scripts/ci-changed-scope.test.ts 的单元测试覆盖。手动调度跳过 changed-scope 检测,使 preflight manifest 表现得像每个作用域区域都发生了变更。

  • CI 工作流编辑会验证 Node CI 图和工作流 lint,但不会单独触发 Windows、Android 或 macOS 原生构建;这些平台 lanes 仍作用域到平台源代码变更。
  • main 推送上的文档由独立的 Docs 工作流检查,该工作流使用与 CI 相同的 ClawHub docs mirror,因此混合代码+文档推送不会同时排队 CI 的 check-docs 分片。Pull Request 和手动 CI 在文档变更时仍从 CI 运行 check-docs
  • 仅 CI 路由编辑、选定的低成本核心测试夹具编辑、狭窄的插件契约辅助/测试路由编辑使用快速的 Node-only manifest 路径:preflight、security 和一个 checks-fast-core 任务。当变更仅限于该快速任务直接锻炼的路由或辅助表面时,该路径跳过构建产物、Node 22 兼容性、渠道契约、完整核心分片、bundled-plugin 分片和额外守卫矩阵。
  • Windows Node 检查作用域到 Windows 特定的进程/路径包装器、npm/pnpm/UI runner 辅助工具、包管理器配置、以及执行该 lane 的 CI 工作流表面;无关的源代码、插件、install-smoke 和仅测试变更停留在 Linux Node lanes 上。

最慢的 Node 测试家族被拆分或平衡,以便每个作业保持较小而不过度预留 runner:插件契约和渠道契约各作为两个加权的 Blacksmith 支持的分片运行,标准 GitHub runner 回退;核心单元快速/支持 lanes 分开运行;核心运行时基础设施在状态、进程/配置、共享和三个 cron 域分片之间拆分;自动回复作为平衡 worker 运行(回复子树拆分为 agent-runner、dispatch 和 commands/state-routing 分片);智能体网关/服务器配置在聊天/认证/模型/http-plugin/运行时/启动 lanes 间拆分,而不是等待构建产物。广泛的浏览器、QA、媒体和杂项插件测试使用专门的 Vitest 配置,而不是共享的插件 catch-all。包含模式分片使用 CI 分片名称记录定时条目,因此 .artifacts/vitest-shard-timings.json 可以区分整个配置和过滤后的分片。check-additional-* 将包边界编译/金丝雀工作放在一起,并将运行时拓扑架构与 gateway watch 覆盖分离;边界守卫列表被条带化为一个提示密集型分片和一个组合分片用于剩余守卫条带,每个分片并发运行选定的独立守卫,并打印每次检查的定时。昂贵的 Codex happy-path 提示快照漂移检查作为自己的额外作业运行,仅用于手动 CI 和提示影响变更;因此正常的无关 Node 变更不会等待冷提示快照生成,并且边界分片保持平衡,同时提示漂移仍然固定在其导致的 PR 上;相同的标志在 built-artifact 核心支持边界分片中跳过提示快照 Vitest 生成。Gateway watch、渠道测试和核心支持边界分片在 build-artifacts 内部并发运行,前提是 dist/dist-runtime/ 已经构建完毕。

Android CI 同时运行 testPlayDebugUnitTesttestThirdPartyDebugUnitTest,然后构建 Play debug APK。第三方 flavor 没有单独的 source set 或 manifest;其单元测试 lane 仍然使用 SMS/call-log BuildConfig 标志编译该 flavor,同时避免在每个 Android 相关推送上重复 debug APK 打包作业。

check-dependencies 分片运行 pnpm deadcode:dependencies(一个生产 Knip 依赖-only pass,固定到最新 Knip 版本,对 dlx 安装禁用 pnpm 的最低发行年龄)和 pnpm deadcode:unused-files,后者将 Knip 的生产未使用文件发现与 scripts/deadcode-unused-files.allowlist.mjs 进行比较。未使用文件守卫在 PR 添加新的未审查未使用文件或留下陈旧的 allowlist 条目时失败,同时保留 Knip 无法静态解析的有意动态插件、生成、构建、实时测试和包桥接表面。

ClawSweeper 活动转发

.github/workflows/clawsweeper-dispatch.yml 是 OpenClaw 仓库活动到 ClawSweeper 的目标端桥接。它不检出或执行不受信任的拉取请求代码。该工作流从 CLAWSWEEPER_APP_PRIVATE_KEY 创建 GitHub App 令牌,然后将紧凑的 repository_dispatch 负载分派到 openclaw/clawsweeper

该工作流有四个 lane:

  • clawsweeper_item 用于精确的 issue 和拉取请求审查请求;
  • clawsweeper_comment 用于 issue 评论中的显式 ClawSweeper 命令;
  • clawsweeper_commit_review 用于 main 推送上的提交级审查请求;
  • github_activity 用于 ClawSweeper 智能体可能检查的通用 GitHub 活动。

github_activity lane 仅转发规范化的元数据:事件类型、动作、actor、仓库、条目编号、URL、标题、状态以及评论或审查的简短摘录(如果有)。它有意避免转发完整的 webhook 主体。接收工作流在 openclaw/clawsweeper 中是 .github/workflows/github-activity.yml,它将规范化的事件发布到 OpenClaw Gateway hook 供 ClawSweeper 智能体使用。

通用活动是观察,不是默认投递。ClawSweeper 智能体在其提示中接收 Discord 目标,并且仅当事件令人惊讶、可操作、有风险或操作上有用时才应发布到 #clawsweeper。常规的打开、编辑、机器人闲聊、重复的 webhook 噪音和正常的审查流量应导致 NO_REPLY

在整个路径中,将 GitHub 标题、评论、正文、审查文本、分支名称和提交消息视为不受信任的数据。它们是用于摘要和分类的输入,不是工作流或智能体运行时的指令。

手动调度

手动 CI 调度运行与正常 CI 相同的作业图,但强制所有非 Android 作用域的 lane 开启:Linux Node 分片、bundled-plugin 分片、插件和渠道契约分片、Node 22 兼容性、check-*check-additional-*、构建产物冒烟检查、文档检查、Python 技能、Windows、macOS 和 Control UI i18n。独立的手动 CI 调度仅当 include_android=true 时运行 Android;完整发布伞启用 Android 通过传递 include_android=true。插件预发布静态检查、仅发布 agentic-plugins 分片、完整扩展批处理扫描和插件预发布 Docker lanes 从 CI 中排除。Docker 预发布套件仅当 Full Release Validation 调度单独的 Plugin Prerelease 工作流并启用 release-validation gate 时运行。

手动运行使用唯一的并发组,因此发布候选完整套件不会被同一 ref 上的另一个推送或 PR 运行取消。可选的 target_ref 输入允许受信任的调用者针对分支、标签或完整 commit SHA 运行该图,同时使用选定调度 ref 的工作流文件。

bash
gh workflow run ci.yml --ref release/YYYY.M.D
gh workflow run ci.yml --ref main -f target_ref=<branch-or-sha> -f include_android=true
gh workflow run full-release-validation.yml --ref main -f ref=<branch-or-sha>

运行器

RunnerJobs
ubuntu-24.04preflight、文档检查、Python 技能、workflow-sanity、labeler、auto-response;install-smoke preflight 也使用 GitHub 托管的 Ubuntu
blacksmith-4vcpu-ubuntu-2404CodeQL Critical Qualitysecurity-fast、低权重扩展分片、checks-fast-core、插件/渠道契约分片、checks-node-compat-node22check-guardscheck-prod-typescheck-test-types
blacksmith-8vcpu-ubuntu-2404Linux Node 测试分片、bundled plugin 测试分片、check-additional-* 分片、android
blacksmith-16vcpu-ubuntu-2404build-artifactscheck-lint;install-smoke Docker 构建使用 32 vCPU
blacksmith-16vcpu-windows-2025checks-windows
blacksmith-6vcpu-macos-latestmacos-nodeopenclaw/openclaw 上;fork 回落到 macos-latest
blacksmith-12vcpu-macos-latestmacos-swiftopenclaw/openclaw 上;fork 回落到 macos-latest

规范仓库 CI 保持 Blacksmith 作为默认 runner 路径。在 preflight 期间,scripts/ci-runner-labels.mjs 检查最近排队的和进行中的 Actions 运行中是否有排队的 Blacksmith 作业。如果某个特定的 Blacksmith label 已经存在排队作业,将使用该确切标签的下游作业会回落到匹配的 GitHub 托管 runner(ubuntu-24.04windows-2025macos-latest)仅用于该次运行。同一 OS 家族中的其他 Blacksmith 大小保持在其主要标签上。如果 API 探测失败,则不应用回退。

本地等价命令

bash
pnpm changed:lanes                            # 检查本地 changed-lane 分类器(origin/main...HEAD)
pnpm check:changed                            # 智能本地检查门控:按边界 lane 变更类型检查/lint/守卫
pnpm check                                    # 快速本地门控:生产 tsgo + 分片 lint + 并行快速守卫
pnpm check:test-types
pnpm check:timed                              # 带阶段时间记录的相同门控
pnpm build:strict-smoke
pnpm check:architecture
pnpm test:gateway:watch-regression
pnpm test                                     # vitest 测试
pnpm test:changed                             # 便宜智能变更 Vitest 目标
pnpm test:channels
pnpm test:contracts:channels
pnpm check:docs                               # 文档格式 + lint + 死链
pnpm build                                    # 当 CI artifact/smoke 检查重要时构建 dist
pnpm ci:timings                               # 总结最新的 origin/main 推送 CI 运行
pnpm ci:timings:recent                        # 比较最近成功的 main CI 运行
node scripts/ci-run-timings.mjs <run-id>      # 总结 wall time、queue time、最慢作业
node scripts/ci-run-timings.mjs --latest-main # 忽略 issue/comment 噪音,选择 origin/main 推送 CI
node scripts/ci-run-timings.mjs --recent 10   # 比较最近成功的 main CI 运行
pnpm test:perf:groups --full-suite --allow-failures --output .artifacts/test-perf/baseline-before.json
pnpm test:perf:groups:compare .artifacts/test-perf/baseline-before.json .artifacts/test-perf/after-agent.json
pnpm perf:kova:summary --report .artifacts/kova/reports/mock-provider/report.json --output .artifacts/kova/summary.md

OpenClaw Performance

OpenClaw Performance 是产品/运行时性能工作流。它在 main 上每天运行,也可以手动调度:

bash
gh workflow run openclaw-performance.yml --ref main -f profile=diagnostic -f repeat=3
gh workflow run openclaw-performance.yml --ref main -f profile=smoke -f repeat=1 -f deep_profile=true -f live_openai_candidate=true
gh workflow run openclaw-performance.yml --ref main -f target_ref=v2026.5.2 -f profile=diagnostic -f repeat=3

手动调度通常对 workflow ref 进行基准测试。设置 target_ref 以使用当前工作流实现对发布标签或其他分支进行基准测试。已发布的报告路径和最新指针以被测试的 ref 为键,每个 index.md 记录被测试的 ref/SHA、工作流 ref/SHA、Kova ref、profile、lane auth 模式、模型、重复次数和场景过滤器。

该工作流从固定版本安装 OCM,从 openclaw/Kova 安装 Kova(固定到 kova_ref 输入),然后运行三个 lane:

  • mock-provider:Kova 诊断场景,针对本地构建运行时,使用确定性的假 OpenAI 兼容认证。
  • mock-deep-profile:CPU/堆/跟踪分析,用于启动、网关和智能体回合热点。
  • live-openai-candidate:真正的 OpenAI openai/gpt-5.5 智能体回合,当 OPENAI_API_KEY 不可用时跳过。

mock-provider lane 还在 Kova pass 之后运行 OpenClaw 原生源探针:网关启动时序和内存(默认、hook 和 50 插件启动情况);重复的 mock-OpenAI channel-chat-baseline hello 循环;以及针对已启动网关的 CLI 启动命令。源探针 Markdown 摘要位于报告包中的 source/index.md,旁边有原始 JSON。

每个 lane 上传 GitHub 产物。当配置了 CLAWGRIT_REPORTS_TOKEN 时,工作流还将 report.jsonreport.md、bundle、index.md 和源探针产物提交到 openclaw/clawgrit-reports 下的 openclaw-performance/&lt;tested-ref&gt;/&lt;run-id&gt;-&lt;attempt&gt;/&lt;lane&gt;/。当前被测试 ref 的指针写入 openclaw-performance/&lt;tested-ref&gt;/latest-&lt;lane&gt;.json

Full Release Validation

Full Release Validation 是手动伞工作流,用于“在发布前运行所有内容”。它接受分支、标签或完整 commit SHA,使用该目标调度手动的 CI 工作流,调度 Plugin Prerelease 用于仅发布的插件/包/静态/Docker 验证,并调度 OpenClaw Release Checks 用于安装冒烟、包验收、跨 OS 包检查、QA Lab 对等、Matrix 和 Telegram lane。稳定/默认运行将详尽的 live/E2E 和 Docker 发布路径覆盖保留在 run_release_soak=true 后面;release_profile=full 强制这种浸泡覆盖,使广泛的咨询验证保持广泛。使用 rerun_group=allrelease_profile=full 时,它还会针对发布检查中的 release-package-under-test 产物运行 NPM Telegram Beta E2E。发布后,传递 release_package_spec 以跨发布检查、Package Acceptance、Docker、跨 OS 和 Telegram 重用已发布的 npm 包,无需重新构建。仅当 Telegram 必须证明不同的包时,才使用 npm_telegram_package_spec。Codex 插件实时包 lane 默认使用相同的选定状态:已发布的 release_package_spec=openclaw@&lt;tag&gt; 派生 codex_plugin_spec=npm:@openclaw/codex@&lt;tag&gt;,而 SHA/产物运行从选定 ref 打包 extensions/codex。显式设置 codex_plugin_spec 用于自定义插件源,如 npm:npm-pack:git: spec。

参见 Full release validation 了解阶段矩阵、确切的工作流作业名称、profile 差异、产物和聚焦的 re-run 句柄。

OpenClaw Release Publish 是手动变更发布工作流。在发布标签存在且 OpenClaw npm preflight 成功后,从 release/YYYY.M.Dmain 调度它。它验证 pnpm plugins:sync:check,调度 Plugin NPM Release 用于所有可发布插件包,调度 Plugin ClawHub Release 用于相同的发布 SHA,然后才调度 OpenClaw NPM Release 并保存 preflight_run_id

bash
gh workflow run openclaw-release-publish.yml \
  --ref release/YYYY.M.D \
  -f tag=vYYYY.M.D-beta.N \
  -f preflight_run_id=<successful-openclaw-npm-preflight-run-id> \
  -f npm_dist_tag=beta

对于快速分支上的固定提交验证,使用辅助工具代替 gh workflow run ... --ref main -f ref=&lt;sha&gt;

bash
pnpm ci:full-release --sha <full-sha>

GitHub 工作流调度 ref 必须是分支或标签,而不是原始 commit SHA。辅助工具在目标 SHA 处推送一个临时分支 release-ci/&lt;sha&gt;-...,从该固定 ref 调度 Full Release Validation,验证每个子工作流的 headSha 与目标匹配,并在运行完成后删除临时分支。伞验证器在任何子工作流以不同的 SHA 运行时也会失败。

release_profile 控制传递给发布检查的 live/provider 广度。手动发布工作流默认 stable;仅当你有意想要广泛的咨询提供商/媒体矩阵时使用 fullrun_release_soak 控制稳定/默认发布检查是否运行详尽的 live/E2E 和 Docker 发布路径浸泡;full 强制浸泡开启。

  • minimum 保留最快的 OpenAI/核心发布关键 lane。
  • stable 添加稳定的提供商/后端集合。
  • full 运行广泛的咨询提供商/媒体矩阵。

伞记录已调度的子运行 ID,最终 Verify full validation 作业重新检查当前子运行结论,并为每个子运行附加最慢作业表。如果子工作流被重新运行并变为绿色,仅重新运行父验证器作业以刷新伞结果和时序摘要。

对于恢复,Full Release ValidationOpenClaw Release Checks 都接受 rerun_group。对发布候选使用 all,对仅正常完整 CI 子项使用 ci,对仅插件预发布子项使用 plugin-prerelease,对每个发布子项使用 release-checks,或在伞上使用更窄的组:install-smokecross-oslive-e2epackageqaqa-parityqa-livenpm-telegram。这将使失败的发布 box 重新运行在聚焦修复后保持有限。对于一条失败的跨 OS lane,组合 rerun_group=cross-oscross_os_suite_filter,例如 windows/packaged-upgrade;长的跨 OS 命令发出心跳行,packaged-upgrade 摘要包括每个阶段的时序。QA 发布检查 lane 是咨询性的,除了标准运行时工具覆盖门控,该门控在所需的 OpenClaw 动态工具从标准层级摘要中漂移或消失时阻止。

OpenClaw Release Checks 使用受信任的工作流 ref 将选定的 ref 解析一次为 release-package-under-test tarball,然后将该产物传递给跨 OS 检查和 Package Acceptance,以及当浸泡覆盖运行时传递给 live/E2E 发布路径 Docker 工作流。这使包字节在整个发布 box 中保持一致,并避免在多个子作业中重新打包相同的候选。对于 Codex npm-plugin 实时 lane,发布检查要么传递从 release_package_spec 派生的匹配已发布插件 spec,要么传递操作员提供的 codex_plugin_spec,要么将输入留空以便 Docker 脚本打包选定 checkouts 的 Codex 插件。

ref=mainrerun_group=all 的重复 Full Release Validation 运行会取代较旧的伞。当父级被取消时,父级监视器会取消它已经调度的任何子工作流,因此较新的主验证不会坐在陈旧的两小时发布检查运行后面。发布分支/标签验证和聚焦的 re-run 组保持 cancel-in-progress: false

Live 和 E2E 分片

发布 live/E2E 子项目保持广泛的本地 pnpm test:live 覆盖,但通过 scripts/test-live-shard.mjs 作为命名分片运行,而不是一个串行作业:

  • native-live-src-agents
  • native-live-src-gateway-core
  • provider-filtered native-live-src-gateway-profiles 作业
  • native-live-src-gateway-backends
  • native-live-test
  • native-live-extensions-a-k
  • native-live-extensions-l-n
  • native-live-extensions-openai
  • native-live-extensions-o-z-other
  • native-live-extensions-xai
  • 拆分媒体音频/视频分片和 provider-filtered 音乐分片

这保持了相同的文件覆盖,同时使慢的 live provider 失败更容易重新运行和诊断。聚合的 native-live-extensions-o-znative-live-extensions-medianative-live-extensions-media-music 分片名称对于手动一次性重新运行仍然有效。

原生 live 媒体分片在 ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04 中运行,由 Live Media Runner Image 工作流构建。该镜像预安装了 ffmpegffprobe;媒体作业仅在 setup 之前验证二进制文件。将 Docker 支持的 live 测试套件保持在正常的 Blacksmith runner 上——容器作业不是启动嵌套 Docker 测试的正确位置。

Docker 支持的 live 模型/后端分片每次选定提交使用一个单独的共享 ghcr.io/openclaw/openclaw-live-test:&lt;sha&gt; 镜像。live 发布工作流构建并推送该镜像一次,然后 Docker live 模型、provider-sharded 网关、CLI 后端、ACP 绑定和 Codex harness 分片使用 OPENCLAW_SKIP_DOCKER_BUILD=1 运行。网关 Docker 分片带有显式脚本级 timeout 上限,低于工作流作业超时,因此卡住的容器或清理路径会快速失败,而不是消耗整个发布检查预算。如果这些分片独立地重新构建完整的源 Docker 目标,则发布运行配置错误,将浪费 wall clock 在重复的镜像构建上。

Package Acceptance

当问题是“这个可安装的 OpenClaw 包作为产品工作吗?”时,使用 Package Acceptance。它与正常 CI 不同:正常 CI 验证源树,而包验收验证单个 tarball 通过用户在安装或更新后使用的相同 Docker E2E harness。

作业

  1. resolve_package 检出 workflow_ref,解析一个包候选,写入 .artifacts/docker-e2e-package/openclaw-current.tgz.artifacts/docker-e2e-package/package-candidate.json,将两者作为 package-under-test 产物上传,并在 GitHub step summary 中打印源、工作流 ref、包 ref、版本、SHA-256 和 profile。
  2. docker_acceptance 调用 openclaw-live-and-e2e-checks-reusable.yml,参数 ref=workflow_refpackage_artifact_name=package-under-test。可重用工作流下载该产物,验证 tarball 清单,在需要时准备 package-digest Docker 镜像,并针对该包运行选定的 Docker lane,而不是打包工作流 checkouts。当 profile 选择多个定向的 docker_lanes 时,可重用工作流一次准备好包和共享镜像,然后作为并行的定向 Docker 作业扇出这些 lane,附带唯一的产物。
  3. package_telegram 可选地调用 NPM Telegram Beta E2E。当 telegram_mode 不是 none 时运行,并且当 Package Acceptance 解析了一个时安装相同的 package-under-test 产物;独立的 Telegram 调度仍然可以安装已发布的 npm spec。
  4. summary 如果包解析、Docker 验收或可选的 Telegram lane 失败,则整个工作流失败。

候选源

  • source=npm 仅接受 openclaw@betaopenclaw@latest 或确切的 OpenClaw 发布版本如 openclaw@2026.4.27-beta.2。用于已发布的预发布/稳定验收。
  • source=ref 打包一个受信任的 package_ref 分支、标签或完整 commit SHA。解析器获取 OpenClaw 分支/标签,验证选定的 commit 可以从仓库分支历史或发布标签到达,在分离的工作树中安装依赖,并使用 scripts/package-openclaw-for-docker.mjs 打包。
  • source=url 下载一个 HTTPS .tgzpackage_sha256 是必需的。
  • source=artifactartifact_run_idartifact_name 下载一个 .tgzpackage_sha256 是可选的,但应为外部共享的产物提供。

保持 workflow_refpackage_ref 分离。workflow_ref 是运行测试的受信任工作流/harness 代码。package_ref 是当 source=ref 时被打包的源 commit。这使得当前测试 harness 可以验证旧的受信任源 commit,而无需运行旧的工作流逻辑。

套件 profile

  • smokenpm-onboard-channel-agentgateway-networkconfig-reload
  • packagenpm-onboard-channel-agentdoctor-switchupdate-channel-switchskill-installupdate-corrupt-pluginupgrade-survivorpublished-upgrade-survivorupdate-restart-authplugins-offlineplugin-update
  • productpackage 加上 mcp-channelscron-mcp-cleanupopenai-web-search-minimalopenwebui
  • full — 完整的 Docker 发布路径块与 OpenWebUI
  • custom — 确切的 docker_lanes;当 suite_profile=custom 时需要。

package profile 使用离线插件覆盖,因此已发布包的验证不依赖于实时的 ClawHub 可用性。可选的 Telegram lane 在 NPM Telegram Beta E2E 中重用 package-under-test 产物,已发布的 npm spec 路径保留给独立的调度。

对于专用的更新和插件测试策略,包括本地命令、Docker lanes、Package Acceptance 输入、发布默认值和失败分类,请参见 Testing updates and plugins

发布检查以 source=artifact、准备好的发布包产物、suite_profile=customdocker_lanes='doctor-switch update-channel-switch skill-install update-corrupt-plugin upgrade-survivor published-upgrade-survivor update-restart-auth plugins-offline plugin-update'telegram_mode=mock-openai 调用 Package Acceptance。这使包迁移、更新、实时 ClawHub 技能安装、陈旧的插件依赖清理、配置的插件安装修复、离线插件、插件更新和 Telegram 验证保持在同一个已解析的包 tarball 上。在发布 beta 后,在 Full Release Validation 或 OpenClaw Release Checks 上设置 release_package_spec,以针对已发布的 npm 包运行相同的矩阵而无需重建;仅当 Package Acceptance 需要与发布验证其余部分不同的包时,设置 package_acceptance_package_spec。跨 OS 发布检查仍然覆盖 OS 特定的 onboarding、安装程序和平台行为;包/更新产品验证应从 Package Acceptance 开始。published-upgrade-survivor Docker lane 在阻塞发布路径中每次运行验证一个已发布的包基线。在 Package Acceptance 中,解析的 package-under-test tarball 始终是候选,而 published_upgrade_survivor_baseline 选择回退的已发布基线,默认为 openclaw@latest;失败的 lane 重新运行命令保留该基线。Full Release Validation 使用 run_release_soak=truerelease_profile=full 设置 published_upgrade_survivor_baselines='last-stable-4 2026.4.23 2026.5.2 2026.4.15'published_upgrade_survivor_scenarios=reported-issues,以扩展到四个最新的稳定 npm 发布版本加上固定的插件兼容性边界发布版本和问题形状的夹具,用于 Feishu 配置、保留的 bootstrap/persona 文件、配置的 OpenClaw 插件安装、波浪线日志路径和陈旧的遗留插件依赖根。多基线已发布升级幸存者选择按基线分片到单独的定向 Docker runner 作业中。单独的 Update Migration 工作流使用 update-migration Docker lane,带有 all-since-2026.4.23plugin-deps-cleanup,当问题是详尽的已发布更新清理,而不是正常 Full Release CI 广度时。本地聚合运行可以通过 OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPECS 传递确切的包 spec,通过 OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPECopenclaw@2026.4.15 保留单个 lane,或通过 OPENCLAW_UPGRADE_SURVIVOR_SCENARIOS 设置场景矩阵。已发布的 lane 使用烘焙的 openclaw config set 命令配方配置基线,在 summary.json 中记录配方步骤,并在 Gateway 启动后探测 /healthz/readyz 和 RPC 状态。Windows 打包和安装程序全新 lanes 还验证已安装的包可以从原始的绝对 Windows 路径导入浏览器控制覆盖。OpenAI 跨 OS 智能体回合冒烟默认使用 OPENCLAW_CROSS_OS_OPENAI_MODEL 当设置时,否则是 openai/gpt-5.5,因此安装和网关验证保持在 GPT-5 测试模型上,同时避免 GPT-4.x 默认。

遗留兼容性窗口

Package Acceptance 对已发布的包有有界的遗留兼容性窗口。到 2026.4.25 的包,包括 2026.4.25-beta.*,可以使用兼容路径:

  • 已知的私有 QA 条目在 dist/postinstall-inventory.json 中可能指向 tarball 中遗漏的文件;
  • doctor-switch 当包没有暴露 gateway install --wrapper 标志时,可能会跳过 gateway install --wrapper 持久性子案例;
  • update-channel-switch 可能会修剪来自 tarball 派生的假 git 夹具的缺失 pnpm patchedDependencies,并且可能会记录缺失的持久化 update.channel
  • 插件冒烟可能会读取旧式安装记录位置或接受缺失的市场安装记录持久化;
  • plugin-update 可能允许配置元数据迁移,同时仍要求安装记录和不重新安装行为保持不变。

已发布的 2026.4.26 包也可能对已经发布的本地构建元数据戳文件发出警告。之后的包必须满足现代契约;相同的条件将失败而不是警告或跳过。

示例

bash
# 验证当前 beta 包,使用产品级覆盖。
gh workflow run package-acceptance.yml \
  --ref main \
  -f workflow_ref=main \
  -f source=npm \
  -f package_spec=openclaw@beta \
  -f suite_profile=product \
  -f telegram_mode=mock-openai

# 打包并验证发布分支,使用当前 harness。
gh workflow run package-acceptance.yml \
  --ref main \
  -f workflow_ref=main \
  -f source=ref \
  -f package_ref=release/YYYY.M.D \
  -f suite_profile=package \
  -f telegram_mode=mock-openai

# 验证 tarball URL。SHA-256 对 source=url 是强制的。
gh workflow run package-acceptance.yml \
  --ref main \
  -f workflow_ref=main \
  -f source=url \
  -f package_url=https://example.com/openclaw-current.tgz \
  -f package_sha256=<64-char-sha256> \
  -f suite_profile=smoke

# 重用另一个 Actions 运行上传的 tarball。
gh workflow run package-acceptance.yml \
  --ref main \
  -f workflow_ref=main \
  -f source=artifact \
  -f artifact_run_id=<run-id> \
  -f artifact_name=package-under-test \
  -f suite_profile=custom \
  -f docker_lanes='install-e2e plugin-update'

当调试失败的包验收运行时,从 resolve_package 摘要开始,确认包源、版本和 SHA-256。然后检查 docker_acceptance 子运行及其 Docker 产物:.artifacts/docker-tests/**/summary.jsonfailures.json、lane 日志、阶段时序和重新运行命令。优先重新运行失败的包 profile 或确切的 Docker lanes,而不是重新运行完整的发布验证。

Install Smoke

单独的 Install Smoke 工作流通过其自己的 preflight 作业重用相同的作用域脚本。它将冒烟覆盖拆分为 run_fast_install_smokerun_full_install_smoke

  • 快速路径:针对触及 Docker/包表面、bundled plugin 包/清单变更或核心插件/渠道/网关/Plugin SDK 表面的拉取请求运行(Docker 冒烟作业会锻炼这些)。仅源 bundled plugin 变更、仅测试编辑和仅文档编辑不会保留 Docker worker。快速路径构建根 Dockerfile 镜像一次,检查 CLI,运行 agents delete shared-workspace CLI 冒烟,运行容器 gateway-network e2e,验证 bundled extension 构建参数,并在 240 秒聚合命令超时下运行有界的 bundled-plugin Docker profile(每个场景的 Docker 运行单独上限)。
  • 完整路径:将 QR 包安装和安装程序 Docker/更新覆盖保留给 nightly 调度运行、手动调度、workflow-call 发布检查以及真正触及安装程序/包/Docker 表面的拉取请求。在完整模式下,install-smoke 准备或重用目标 SHA GHCR 根 Dockerfile 冒烟镜像,然后运行 QR 包安装、根 Dockerfile/gateway 冒烟、安装程序/更新冒烟和快速 bundled-plugin Docker E2E 作为单独的作业,以便安装程序工作不等待根镜像冒烟。

main 推送(包括合并提交)不会强制完整路径;当 changed-scope 逻辑会在推送时请求完整覆盖时,工作流保留快速 Docker 冒烟,将完整安装冒烟留给 nightly 或发布验证。

慢的 Bun 全局安装镜像提供商冒烟由 run_bun_global_install_smoke 单独门控。它在 nightly 调度和发布检查工作流中运行,手动 Install Smoke 调度可以选择加入,但拉取请求和 main 推送不会。QR 和安装程序 Docker 测试保留自己的安装特定 Dockerfiles。

本地 Docker E2E

pnpm test:docker:all 预构建一个共享的 live-test 镜像,将 OpenClaw 打包一次为 npm tarball,并构建两个共享的 scripts/e2e/Dockerfile 镜像:

  • 一个裸露的 Node/Git runner 用于安装程序/更新/插件依赖 lane;
  • 一个功能镜像,将相同的 tarball 安装到 /app 用于正常功能 lane。

Docker lane 定义位于 scripts/lib/docker-e2e-scenarios.mjs,调度器逻辑位于 scripts/lib/docker-e2e-plan.mjs,runner 仅执行选定的计划。调度器使用 OPENCLAW_DOCKER_E2E_BARE_IMAGEOPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE 为每个 lane 选择镜像,然后使用 OPENCLAW_SKIP_DOCKER_BUILD=1 运行 lane。

可调参数

VariableDefault用途
OPENCLAW_DOCKER_ALL_PARALLELISM10正常 lane 的主池槽位数量。
OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM10提供商敏感的尾部池槽位数量。
OPENCLAW_DOCKER_ALL_LIVE_LIMIT9并发 live lane 上限,避免提供商限制。
OPENCLAW_DOCKER_ALL_NPM_LIMIT10并发 npm install lane 上限。
OPENCLAW_DOCKER_ALL_SERVICE_LIMIT7并发多服务 lane 上限。
OPENCLAW_DOCKER_ALL_START_STAGGER_MS2000lane 启动间隔,避免 Docker daemon create 风暴;设为 0 则无间隔。
OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS7200000每个 lane 的回退超时(120 分钟);选定的 live/tail lane 使用更紧的上限。
OPENCLAW_DOCKER_ALL_DRY_RUNunset1 时打印调度器计划而不运行 lane。
OPENCLAW_DOCKER_ALL_LANESunset逗号分隔的精确 lane 列表;跳过清理冒烟,以便智能体可以复现一个失败的 lane。

比其有效上限更重的 lane 仍然可以从空池启动,然后单独运行直到释放容量。本地聚合预检查 Docker,移除陈旧的 OpenClaw E2E 容器,发出活动 lane 状态,按最长优先顺序持久化 lane 时序,并在第一次失败后默认停止调度新的池中 lane。

可重用 Live/E2E 工作流

可重用 live/E2E 工作流询问 scripts/test-docker-all.mjs --plan-json 需要哪个包、镜像种类、live 镜像、lane 和凭证覆盖。scripts/docker-e2e.mjs 然后将该计划转换为 GitHub 输出和摘要。它通过 scripts/package-openclaw-for-docker.mjs 打包 OpenClaw,下载当前运行的包产物,或从 package_artifact_run_id 下载包产物;验证 tarball 清单;在计划需要包安装的 lane 时,通过 Blacksmith 的 Docker 层缓存构建并推送包摘要标签的裸/功能 GHCR Docker E2E 镜像;并重用提供的 docker_e2e_bare_image/docker_e2e_functional_image 输入或现有的包摘要镜像,而不是重新构建。Docker 镜像拉取具有有界的 180 秒每次尝试超时,因此卡住的注册表/缓存流会快速重试,而不是消耗大部分 CI 关键路径。

发布路径块

发布 Docker 覆盖使用 OPENCLAW_SKIP_DOCKER_BUILD=1 运行较小的分块作业,因此每个块仅拉取所需镜像种类,并通过相同的加权调度器执行多个 lane:

  • OPENCLAW_DOCKER_ALL_PROFILE=release-path
  • OPENCLAW_DOCKER_ALL_CHUNK=core | package-update-openai | package-update-anthropic | package-update-core | plugins-runtime-plugins | plugins-runtime-services | plugins-runtime-install-a..h

当前发布 Docker 块是 corepackage-update-openaipackage-update-anthropicpackage-update-coreplugins-runtime-pluginsplugins-runtime-servicesplugins-runtime-install-aplugins-runtime-install-hpackage-update-openai 包括 live Codex 插件包 lane,它安装候选 OpenClaw 包,从 codex_plugin_spec 或同一 ref 的 tarball 安装 Codex 插件(带有显式 Codex CLI 安装批准),运行 Codex CLI preflight,然后对 OpenAI 运行多个相同会话的 OpenClaw 智能体回合。plugins-runtime-coreplugins-runtimeplugins-integrations 保持聚合的插件/运行时别名。install-e2e lane 别名仍然是两个提供商安装程序 lane 的聚合手动重新运行别名。

OpenWebUI 在完整发布路径覆盖请求时折叠到 plugins-runtime-services 中,并且仅针对仅 OpenWebUI 的调度保持独立的 openwebui 块。Bundled-channel 更新 lane 对瞬态 npm 网络失败重试一次。

每个块上传 .artifacts/docker-tests/,包含 lane 日志、时序、summary.jsonfailures.json、阶段时序、调度器计划 JSON、慢 lane 表和每个 lane 的重新运行命令。工作流 docker_lanes 输入针对准备好的镜像运行选定的 lane,而不是块作业,这使失败的 lane 调试有界到单个定向 Docker 作业,并为该运行准备、下载或重用包产物;如果选定 lane 是 live Docker lane,则定向作业为该重新运行本地构建 live-test 镜像。生成的每个 lane GitHub 重新运行命令在值存在时包括 package_artifact_run_idpackage_artifact_name 和准备好的镜像输入,因此失败的 lane 可以重用来自失败运行的确切包和镜像。

bash
pnpm test:docker:rerun <run-id>      # 下载 Docker 产物并打印组合/每 lane 定向重新运行命令
pnpm test:docker:timings <summary>   # 慢 lane 和阶段关键路径摘要

调度的 live/E2E 工作流每天运行完整的发布路径 Docker 套件。

Plugin Prerelease

Plugin Prerelease 是更昂贵的产品/包覆盖,因此它是一个由 Full Release Validation 或显式操作员调度的独立工作流。正常的拉取请求、main 推送和独立的手动 CI 调度保持该套件关闭。它在八个扩展 worker 之间平衡 bundled plugin 测试;这些扩展分片作业一次运行多达两个插件配置组,每个组一个 Vitest worker,并使用更大的 Node 堆,因此导入密集型插件批处理不会创建额外的 CI 作业。仅发布的 Docker 预发布路径将定向 Docker lane 批处理成小型组,以避免为 1 到 3 分钟的作业保留数十个 runner。该工作流还从 @openclaw/plugin-inspector 上传一个信息性的 plugin-inspector-advisory 产物;inspector 发现是分类输入,不改变阻塞的 Plugin Prerelease 门控。

QA Lab

QA Lab 在主要的智能作用域工作流之外有专用的 CI lane。Agentic 对等嵌套在广泛的 QA 和发布 harnesses 下,而不是一个独立的 PR 工作流。当对等应与广泛的验证运行一起进行时,使用 Full Release Validationrerun_group=qa-parity

  • QA-Lab - All Lanes 工作流在 main 上每晚运行,也可手动调度;它将 mock 对等 lane、live Matrix lane 和 live Telegram 与 Discord lanes 作为并行作业扇出。Live 作业使用 qa-live-shared 环境,Telegram 和 Discord 使用 Convex leases。

发布检查使用确定性 mock provider 和 mock-qualified 模型(mock-openai/gpt-5.5mock-openai/gpt-5.5-alt)运行 Matrix 和 Telegram 实时传输 lane,以便渠道契约与实时模型延迟和正常提供商插件启动隔离。实时传输网关禁用内存搜索,因为 QA 对等单独覆盖内存行为;提供商连接由单独的 live model、原生 provider 和 Docker provider 套件覆盖。

Matrix 使用 --profile fast 用于调度和发布门控,仅当检出 CLI 支持时添加 --fail-fast。CLI 默认和手动工作流输入仍然是 all;手动 matrix_profile=all 调度始终将完整的 Matrix 覆盖分片为 transportmediae2ee-smokee2ee-deepe2ee-cli 作业。

OpenClaw Release Checks 还在发布批准之前运行发布关键的 QA Lab lane;其 QA 对等门控将候选和基线包作为并行 lane 作业运行,然后将两个产物下载到一个小型报告作业中,用于最终对等比较。

对于正常的 PR,遵循作用域 CI/检查证据,而不是将对等视为必需状态。

CodeQL

CodeQL 工作流有意是一个狭窄的首通安全扫描器,不是完整的仓库扫描。每日、手动和非 draft 拉取请求守卫运行扫描 Actions 工作流代码加上最高风险的 JavaScript/TypeScript 表面,使用高/关键 security-severity 的高置信度安全查询过滤。

拉取请求守卫保持轻量:仅在 .github/actions.github/codeql.github/workflowspackagessrc 下的变更时启动,并运行与调度工作流相同的高置信度安全矩阵。Android 和 macOS CodeQL 不会出现在 PR 默认中。

安全类别

Category表面
/codeql-security-high/core-auth-secrets认证、秘密、沙箱、cron、网关基线
/codeql-security-high/channel-runtime-boundary核心渠道实现契约加上渠道插件运行时、网关、Plugin SDK、安全、审计接触点
/codeql-security-high/network-ssrf-boundary核心 SSRF、IP 解析、网络守卫、web-fetch、Plugin SDK SSRF 策略表面
/codeql-security-high/mcp-process-tool-boundaryMCP 服务器、进程执行辅助、出站投递、智能体工具执行门控
/codeql-security-high/plugin-trust-boundary插件安装、加载器、清单、注册表、包管理器安装、源加载、Plugin SDK 包契约信任表面

平台特定安全分片

  • CodeQL Android Critical Security — 调度的 Android 安全分片。手动构建 Android 应用以供 CodeQL 在最小的 Blacksmith Linux runner 上运行(由 workflow sanity 接受)。上传到 /codeql-critical-security/android
  • CodeQL macOS Critical Security — 每周/手动 macOS 安全分片。在 Blacksmith macOS 上手动构建 macOS 应用以供 CodeQL,从上传的 SARIF 中过滤掉依赖构建结果,并上传到 /codeql-critical-security/macos。保持在每日默认值之外,因为 macOS 构建会主导运行时(即使 clean)。

Critical Quality 类别

CodeQL Critical Quality 是匹配的非安全分片。它仅在较小的 Blacksmith Linux runner 上运行错误严重性、非安全的 JavaScript/TypeScript 质量查询,覆盖狭窄的高价值表面。其拉取请求守卫有意小于调度 profile:非 draft PR 仅运行匹配的 agent-runtime-boundaryconfig-boundarycore-auth-secretschannel-runtime-boundarygateway-runtime-boundarymemory-runtime-boundarymcp-process-runtime-boundaryprovider-runtime-boundarysession-diagnostics-boundaryplugin-boundaryplugin-sdk-package-contractplugin-sdk-reply-runtime 分片,用于智能体命令/模型/工具执行和回复调度代码、配置 schema/迁移/IO 代码、认证/秘密/沙箱/安全代码、核心渠道和 bundled channel plugin 运行时、网关协议/服务器方法、内存运行时/SDK glue、MCP/进程/出站投递、提供商运行时/模型目录、会话诊断/投递队列、插件加载器、Plugin SDK/包契约或 Plugin SDK 回复运行时变更。CodeQL 配置和质量工作流变更运行所有 12 个 PR 质量分片。

手动调度接受:

profile=all|agent-runtime-boundary|config-boundary|core-auth-secrets|channel-runtime-boundary|gateway-runtime-boundary|memory-runtime-boundary|mcp-process-runtime-boundary|plugin-boundary|plugin-sdk-package-contract|plugin-sdk-reply-runtime|provider-runtime-boundary|session-diagnostics-boundary

狭窄的 profile 是教学/迭代钩子,用于孤立地运行一个质量分片。

Category表面
/codeql-critical-quality/core-auth-secrets认证、秘密、沙箱、cron、网关安全边界代码
/codeql-critical-quality/config-boundary配置 schema、迁移、规范化、IO 契约
/codeql-critical-quality/gateway-runtime-boundary网关协议 schema 和服务器方法契约
/codeql-critical-quality/channel-runtime-boundary核心渠道和 bundled channel plugin 实现契约
/codeql-critical-quality/agent-runtime-boundary命令执行、模型/提供商调度、自动回复调度和队列、ACP 控制平面运行时契约
/codeql-critical-quality/mcp-process-runtime-boundaryMCP 服务器和工具桥、进程监督辅助、出站投递契约
/codeql-critical-quality/memory-runtime-boundary内存主机 SDK、内存运行时 facade、内存 Plugin SDK 别名、内存运行时激活 glue、内存 doctor 命令
/codeql-critical-quality/session-diagnostics-boundary回复队列内部、会话投递队列、出站会话绑定/投递辅助、诊断事件/日志包表面、会话 doctor CLI 契约
/codeql-critical-quality/plugin-sdk-reply-runtimePlugin SDK 入站回复调度、回复载荷/分块/运行时辅助、渠道回复选项、投递队列、会话/线程绑定辅助
/codeql-critical-quality/provider-runtime-boundary模型目录规范化、提供商认证和发现、提供商运行时注册、提供商默认/目录、web/search/fetch/embedding 注册表
/codeql-critical-quality/ui-control-planeControl UI 引导、本地持久化、网关控制流、任务控制平面运行时契约
/codeql-critical-quality/web-media-runtime-boundary核心 web fetch/search、媒体 IO、媒体理解、图像生成、媒体生成运行时契约
/codeql-critical-quality/plugin-boundary加载器、注册表、公共表面、Plugin SDK 入口点契约
/codeql-critical-quality/plugin-sdk-package-contract已发布包端的 Plugin SDK 源码和插件包契约辅助

质量与安全保持分离,因此质量发现可以被调度、测量、禁用或扩展,而不会掩盖安全信号。Swift、Python 和 bundled-plugin CodeQL 扩展应仅在狭窄 profile 具有稳定运行时和信号后作为作用域或分片的后续工作添加。

维护工作流

Docs Agent

Docs Agent 工作流是一个事件驱动的 Codex 维护 lane,用于使现有文档与最近着陆的变更保持一致。它没有纯调度:在 main 上成功的非机器人推送 CI 运行可以触发它,手动调度可以直接运行它。工作流运行调用在 main 已经前进或另一个非跳过的 Docs Agent 运行在过去一小时内创建时跳过。当它运行时,它审查从上一个非跳过的 Docs Agent 源 SHA 到当前 main 的 commit 范围,因此一次每小时运行可以覆盖自上次文档传递以来积累的所有 main 变更。

Test Performance Agent

Test Performance Agent 工作流是一个事件驱动的 Codex 维护 lane,用于慢测试。它没有纯调度:在 main 上成功的非机器人推送 CI 运行可以触发它,但如果另一个工作流运行调用已经在该 UTC 天运行或正在运行,则跳过。手动调度绕过该日常活动门控。该 lane 构建一个完整套件的分组 Vitest 性能报告,让 Codex 仅进行小的覆盖保留测试性能修复,而不是广泛的 refactor,然后重新运行完整套件报告,并拒绝减少通过基线测试计数的变更。如果基线有失败的测试,Codex 可能仅修复明显的失败,并且在任何内容被提交之前,agent 后的完整套件报告必须通过。当 main 在机器人推送之前前进时,该 lane 重新基 valid 的补丁,重新运行 pnpm check:changed,并重试推送;冲突的陈旧的补丁被跳过。它使用 GitHub 托管的 Ubuntu,以便 Codex 动作可以保持与 docs agent 相同的 drop-sudo 安全姿势。

Duplicate PRs After Merge

Duplicate PRs After Merge 工作流是一个手动维护者工作流,用于着陆后的重复清理。它默认为 dry-run,并且仅当 apply=true 时关闭显式列出的 PR。在突变 GitHub 之前,它验证着陆的 PR 已合并,并且每个重复要么有共享的引用 issue,要么有重叠的变更 hunk。

bash
gh workflow run duplicate-after-merge.yml \
  -f landed_pr=70532 \
  -f duplicate_prs='70530,70592' \
  -f apply=true

本地检查门控和变更路由

本地变更 lane 逻辑位于 scripts/changed-lanes.mjs,由 scripts/check-changed.mjs 执行。该本地检查门控在架构边界上比广泛的 CI 平台作用域更严格:

  • 核心生产变更运行核心生产和核心测试类型检查加上核心 lint/守卫;
  • 核心仅测试变更仅运行核心测试类型检查加上核心 lint;
  • 扩展生产变更运行扩展生产和扩展测试类型检查加上扩展 lint;
  • 扩展仅测试变更运行扩展测试类型检查加上扩展 lint;
  • 公开 Plugin SDK 或插件契约变更扩展到扩展类型检查,因为扩展依赖于这些核心契约(Vitest 扩展扫描保持显式测试工作);
  • 仅发布元数据版本提升运行定向的版本/配置/根依赖检查;
  • 未知根/配置变更安全失败到所有检查 lane。

本地变更测试路由位于 scripts/test-projects.test-support.mjs,并且有意比 check:changed 便宜:直接测试编辑运行自身,源编辑更喜欢显式映射,然后是兄弟测试和导入图依赖者。共享组房间投递配置是显式映射之一:对组可见回复配置、源回复投递模式或消息工具系统提示的变更通过核心回复测试加上 Discord 和 Slack 投递回归路由,因此在第一个 PR 推送之前共享默认变更就会失败。仅当变更足够广泛以至于便宜的映射集不是可信代理时,才使用 OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed

Testbox 验证

Crabbox 是仓库拥有的远程 box 包装器,用于维护者 Linux 验证。当检查对于本地编辑循环太广泛、CI 对等性重要、或者验证需要秘密、Docker、包 lane、可重用 box 或远程日志时,从仓库根目录使用它。正常的 OpenClaw 后端是 blacksmith-testbox;拥有的 AWS/Hetzner 容量是 Blacksmith 中断、配额问题或显式拥有容量测试的回退。

Crabbox 支持的 Blacksmith 运行温暖、认领、同步、运行、报告和清理一次性 Testbox。内置同步完整性检查在必需的根文件(如 pnpm-lock.yaml)消失或 git status --short 显示至少 200 个跟踪删除时快速失败。对于有意的大删除 PR,为远程命令设置 OPENCLAW_TESTBOX_ALLOW_MASS_DELETIONS=1

如果本地 Blacksmith CLI 调用在同步阶段停留超过五分钟而没有同步后输出,Crabbox 也会终止该调用。设置 CRABBOX_BLACKSMITH_SYNC_TIMEOUT_MS=0 以禁用该保护,或为异常大的本地 diff 使用更大的毫秒值。

在首次运行之前,从仓库根目录检查包装器:

bash
pnpm crabbox:run -- --help | sed -n '1,120p'

仓库包装器拒绝不宣称 blacksmith-testbox 的陈旧 Crabbox 二进制文件。即使 .crabbox.yaml 有拥有云默认,也显式传递提供商。在 Codex 工作树或链接/稀疏检出中,避免使用本地 pnpm crabbox:run 脚本,因为 pnpm 可能在 Crabbox 启动之前解决依赖关系;改为直接调用 node 包装器:

bash
node scripts/crabbox-wrapper.mjs run --provider blacksmith-testbox --timing-json --shell -- "pnpm test <path-or-filter>"

变更门控:

bash
pnpm crabbox:run -- --provider blacksmith-testbox \
  --blacksmith-org openclaw \
  --blacksmith-workflow .github/workflows/ci-check-testbox.yml \
  --blacksmith-job check \
  --blacksmith-ref main \
  --idle-timeout 90m \
  --ttl 240m \
  --timing-json \
  --shell -- \
  "env CI=1 NODE_OPTIONS=--max-old-space-size=4096 OPENCLAW_TEST_PROJECTS_PARALLEL=6 OPENCLAW_VITEST_MAX_WORKERS=1 OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS=900000 pnpm check:changed"

聚焦测试重新运行:

bash
pnpm crabbox:run -- --provider blacksmith-testbox \
  --blacksmith-org openclaw \
  --blacksmith-workflow .github/workflows/ci-check-testbox.yml \
  --blacksmith-job check \
  --blacksmith-ref main \
  --idle-timeout 90m \
  --ttl 240m \
  --timing-json \
  --shell -- \
  "env CI=1 NODE_OPTIONS=--max-old-space-size=4096 OPENCLAW_TEST_PROJECTS_PARALLEL=6 OPENCLAW_VITEST_MAX_WORKERS=1 OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS=900000 pnpm test <path-or-filter>"

完整套件:

bash
pnpm crabbox:run -- --provider blacksmith-testbox \
  --blacksmith-org openclaw \
  --blacksmith-workflow .github/workflows/ci-check-testbox.yml \
  --blacksmith-job check \
  --blacksmith-ref main \
  --idle-timeout 90m \
  --ttl 240m \
  --timing-json \
  --shell -- \
  "env CI=1 NODE_OPTIONS=--max-old-space-size=4096 OPENCLAW_TEST_PROJECTS_PARALLEL=6 OPENCLAW_VITEST_MAX_WORKERS=1 OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS=900000 pnpm test"

阅读最终的 JSON 摘要。有用的字段是 providerleaseIdsyncDelegatedexitCodecommandMstotalMs。一次性的 Blacksmith 支持的 Crabbox 运行应自动停止 Testbox;如果运行被中断或清理不清楚,检查实时 box 并仅停止您创建的 box:

bash
blacksmith testbox list --all
blacksmith testbox status --id <tbx_id>
blacksmith testbox stop --id <tbx_id>

仅当您有意需要多个命令在同一个水合 box 上时,才使用重用:

bash
pnpm crabbox:run -- --provider blacksmith-testbox --id <tbx_id> --no-sync --timing-json --shell -- "pnpm test <path-or-filter>"
pnpm crabbox:stop -- <tbx_id>

如果 Crabbox 是损坏的层但 Blacksmith 本身工作,则仅使用直接 Blacksmith 进行诊断,如 liststatus 和 cleanup。在将直接 Blacksmith 运行视为维护者验证之前,修复 Crabbox 路径。

如果 blacksmith testbox list --allblacksmith testbox status 工作,但新的 warmup 在几分钟后仍处于 queued 状态且没有 IP 或 Actions 运行 URL,则将其视为 Blacksmith 提供商、队列、计费或组织限制压力。停止您创建的排队 ID,避免启动更多 Testbox,并在某人检查 Blacksmith 仪表板、计费和 org 限制时将验证移动到拥有的 Crabbox 容量路径。

仅当 Blacksmith 停机、配额不足、缺少所需环境或拥有的容量是明确目标时,才升级到拥有的 Crabbox 容量:

bash
CRABBOX_CAPACITY_REGIONS=eu-west-1,eu-west-2,eu-central-1,us-east-1,us-west-2 \
  pnpm crabbox:warmup -- --provider aws --class standard --market on-demand --idle-timeout 90m
pnpm crabbox:hydrate -- --id <cbx_id-or-slug>
pnpm crabbox:run -- --id <cbx_id-or-slug> --timing-json --shell -- "env NODE_OPTIONS=--max-old-space-size=4096 OPENCLAW_TEST_PROJECTS_PARALLEL=6 OPENCLAW_VITEST_MAX_WORKERS=1 OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS=900000 pnpm check:changed"
pnpm crabbox:stop -- <cbx_id-or-slug>

在 AWS 压力下,避免使用 class=beast,除非任务真的需要 48xlarge 类 CPU。beast 请求从 192 vCPU 开始,并且是触发区域 EC2 Spot 或 On-Demand Standard 配额的最简单方式。仓库拥有的 .crabbox.yaml 默认使用 standard、多个容量区域和 capacity.hints: true,因此代理的 AWS 租约会打印选定的区域/市场、配额压力、Spot 回退和高压力类警告。对更重的广泛检查使用 fast,仅在 standard/fast 不够时使用 large,仅对异常的 CPU 密集型 lane(如完整套件或所有插件 Docker 矩阵、显式发布/阻塞验证或高核心性能分析)使用 beast。不要对 pnpm check:changed、聚焦测试、仅文档工作、普通 lint/typecheck、小型 E2E 重现或 Blacksmith 中断分类使用 beast。对于容量诊断,使用 --market on-demand,以便 Spot 市场波动不会混入信号。

.crabbox.yaml 拥有拥有云 lane 的提供商、同步和 GitHub Actions 水合默认值。它排除本地 .git,以便水合的 Actions checkout 保持自己的远程 Git 元数据,而不是同步维护者本地 remotes 和对象存储,并且它排除永远不应传输的本地运行时/构建产物。.github/workflows/crabbox-hydrate.yml 拥有 checkout、Node/pnpm 设置、origin/main 获取以及拥有云 crabbox run --id &lt;cbx_id&gt; 命令的非秘密环境交握。

相关

常见问题

提交代码后,为什么 GitHub Actions 只跑了 preflight 就结束了?

这表示你的修改命中了 CI 的智能作用域跳过逻辑。例如你只修改了文档或与 CI 不相关的测试辅助代码,CI 判断无需运行完整的编译和测试流程,以节省时间和算力。你可以检查 preflight 日志中的 changed-scope 输出来确认哪些区域被跳过。

怎么手动触发一次完整的 CI 验证,包括所有平台和插件?

使用 gh workflow run ci.yml --ref main 或指定分支。手动调度会绕过作用域检测,强制运行所有非 Android 的 lane。如果需要 Android,添加 -f include_android=true。完整的发布候选验证应使用 full-release-validation.yml

本地跑 pnpm test 全绿,但 CI 却挂在 check 作业上?

check 作业不仅仅是测试,它还包括更严格的 TypeScript 类型检查(pnpm check)、lint 和架构守卫。推代码前最好运行完整的 pnpm checkpnpm check:changed 来模拟 CI 的门控逻辑。如果本地修改仅限于测试,pnpm check:changed 会只运行相关的类型检查和 lint。