diff --git a/docs/zh-CN/ci.md b/docs/zh-CN/ci.md index ae14eaeb9..f6659b91a 100644 --- a/docs/zh-CN/ci.md +++ b/docs/zh-CN/ci.md @@ -1,94 +1,94 @@ --- read_when: - - 你需要了解 CI 作业为什么运行或未运行 - - 你正在调试一个失败的 GitHub Actions 检查 + - 你需要了解 CI 作业为何运行或未运行 + - 你正在调试一个未通过的 GitHub Actions 检查 - 你正在协调一次发布验证运行或重新运行 - - 你正在更改 ClawSweeper 调度或 GitHub 活动转发 -summary: CI 作业图、范围门禁、发布总控和本地命令等价项 + - 你正在更改 ClawSweeper 派发或 GitHub 活动转发 +summary: CI 作业图、范围门禁、发布总括项和本地命令等效项 title: CI 流水线 x-i18n: - generated_at: "2026-05-02T18:56:41Z" + generated_at: "2026-05-02T20:01:43Z" model: gpt-5.5 provider: openai - source_hash: 8533e12d2ea99c6c342db46452bc448099c75e4bfc78edbb4b582118567421fd + source_hash: 39410c5ceb3598e9e1771f98fba79485b13967df372c7a3f55ef5a5350416435 source_path: ci.md workflow: 16 --- -OpenClaw CI 会在每次推送到 `main` 以及每个拉取请求上运行。`preflight` 作业会对差异进行分类,并在仅有无关区域发生更改时关闭昂贵的通道。手动 `workflow_dispatch` 运行会有意绕过智能范围限定,并为候选发布版和广泛验证展开完整图。Android 通道通过 `include_android` 保持选择加入。仅发布相关的插件覆盖位于单独的 [`插件预发布`](#plugin-prerelease) 工作流中,并且只会从 [`完整发布验证`](#full-release-validation) 或显式手动分发运行。 +OpenClaw CI 会在每次推送到 `main` 以及每个拉取请求时运行。`preflight` 作业会对差异进行分类,并在只有无关区域发生更改时关闭昂贵的通道。手动 `workflow_dispatch` 运行会有意绕过智能范围限定,并为候选发布和广泛验证展开完整图。Android 通道继续通过 `include_android` 保持选择加入。仅发布使用的插件覆盖范围位于单独的 [`插件预发布`](#plugin-prerelease) 工作流中,并且只会从 [`全量发布验证`](#full-release-validation) 或显式手动调度运行。 -## 流水线概览 +## 管道概览 -| 作业 | 用途 | 运行时机 | +| 作业 | 用途 | 运行时机 | | -------------------------------- | --------------------------------------------------------------------------------------------------------- | ---------------------------------- | -| `preflight` | 检测仅文档更改、已更改范围、已更改插件,并构建 CI 清单 | 始终在非草稿推送和 PR 上运行 | -| `security-scm-fast` | 通过 `zizmor` 检测私钥并审计工作流 | 始终在非草稿推送和 PR 上运行 | -| `security-dependency-audit` | 针对 npm 公告执行无依赖的生产锁文件审计 | 始终在非草稿推送和 PR 上运行 | -| `security-fast` | 快速安全作业的必需聚合 | 始终在非草稿推送和 PR 上运行 | -| `check-dependencies` | 生产 Knip 仅依赖检查,以及未使用文件允许列表守卫 | Node 相关更改 | -| `build-artifacts` | 构建 `dist/`、Control UI、构建产物检查,以及可复用下游产物 | Node 相关更改 | -| `checks-fast-core` | 快速 Linux 正确性通道,例如内置/插件契约/协议检查 | Node 相关更改 | -| `checks-fast-contracts-channels` | 带稳定聚合检查结果的分片渠道契约检查 | Node 相关更改 | -| `checks-node-core-test` | 核心 Node 测试分片,不包括渠道、内置、契约和插件通道 | Node 相关更改 | -| `check` | 分片的主本地门禁等价项:生产类型、lint、守卫、测试类型和严格冒烟 | Node 相关更改 | -| `check-additional` | 架构、边界、插件表面守卫、包边界和 Gateway 网关 watch 分片 | Node 相关更改 | -| `build-smoke` | 构建后 CLI 冒烟测试和启动内存冒烟 | Node 相关更改 | -| `checks` | 构建产物渠道测试的验证器 | Node 相关更改 | -| `checks-node-compat-node22` | Node 22 兼容性构建和冒烟通道 | 发布版的手动 CI 分发 | -| `check-docs` | 文档格式化、lint 和断链检查 | 文档已更改 | -| `skills-python` | 针对 Python 支持的 Skills 运行 Ruff + pytest | Python Skills 相关更改 | -| `checks-windows` | Windows 特定的进程/路径测试,以及共享运行时导入说明符回归 | Windows 相关更改 | -| `macos-node` | 使用共享构建产物的 macOS TypeScript 测试通道 | macOS 相关更改 | -| `macos-swift` | macOS 应用的 Swift lint、构建和测试 | macOS 相关更改 | -| `android` | 两种 flavor 的 Android 单元测试,以及一次 debug APK 构建 | Android 相关更改 | -| `test-performance-agent` | 受信任活动后的每日 Codex 慢测试优化 | 主 CI 成功或手动分发 | -| `openclaw-performance` | 带 mock-provider、deep-profile 和 GPT 5.4 live 通道的每日/按需 Kova 运行时性能报告 | 定时和手动分发 | +| `preflight` | 检测仅文档变更、变更范围、变更插件,并构建 CI 清单 | 始终在非草稿推送和 PR 上运行 | +| `security-scm-fast` | 通过 `zizmor` 进行私钥检测和工作流审计 | 始终在非草稿推送和 PR 上运行 | +| `security-dependency-audit` | 针对 npm 公告执行无依赖的生产 lockfile 审计 | 始终在非草稿推送和 PR 上运行 | +| `security-fast` | 快速安全作业的必需聚合项 | 始终在非草稿推送和 PR 上运行 | +| `check-dependencies` | 仅生产 Knip 依赖检查,以及未使用文件 allowlist 防护 | Node 相关变更 | +| `build-artifacts` | 构建 `dist/`、Control UI、构建产物检查,以及可复用的下游产物 | Node 相关变更 | +| `checks-fast-core` | 快速 Linux 正确性通道,例如内置/插件契约/协议检查 | Node 相关变更 | +| `checks-fast-contracts-channels` | 分片的渠道契约检查,并提供稳定的聚合检查结果 | Node 相关变更 | +| `checks-node-core-test` | 核心 Node 测试分片,不包括渠道、内置、契约和插件通道 | Node 相关变更 | +| `check` | 分片的主本地门禁等价项:生产类型、lint、防护、测试类型和严格 smoke | Node 相关变更 | +| `check-additional` | 架构、边界、插件表面防护、包边界和 gateway-watch 分片 | Node 相关变更 | +| `build-smoke` | 已构建 CLI 的 smoke 测试和启动内存 smoke | Node 相关变更 | +| `checks` | 已构建产物渠道测试的验证器 | Node 相关变更 | +| `checks-node-compat-node22` | Node 22 兼容性构建和 smoke 通道 | 发布使用的手动 CI 调度 | +| `check-docs` | 文档格式、lint 和断链检查 | 文档已变更 | +| `skills-python` | 针对 Python 支持的 Skills 运行 Ruff + pytest | Python skill 相关变更 | +| `checks-windows` | Windows 特定的进程/路径测试,以及共享运行时导入说明符回归检查 | Windows 相关变更 | +| `macos-node` | 使用共享构建产物的 macOS TypeScript 测试通道 | macOS 相关变更 | +| `macos-swift` | macOS 应用的 Swift lint、构建和测试 | macOS 相关变更 | +| `android` | 两种 flavor 的 Android 单元测试,以及一个 debug APK 构建 | Android 相关变更 | +| `test-performance-agent` | 在可信活动后每日进行 Codex 慢测试优化 | 主 CI 成功或手动调度 | +| `openclaw-performance` | 每日/按需生成 Kova 运行时性能报告,包含 mock-provider、deep-profile 和 GPT 5.4 实时通道 | 定时和手动调度 | ## 快速失败顺序 -1. `preflight` 决定哪些通道实际存在。`docs-scope` 和 `changed-scope` 逻辑是此作业内的步骤,不是独立作业。 -2. `security-scm-fast`、`security-dependency-audit`、`security-fast`、`check`、`check-additional`、`check-docs` 和 `skills-python` 会快速失败,不等待更重的产物和平台矩阵作业。 -3. `build-artifacts` 与快速 Linux 通道重叠运行,以便下游消费者能在共享构建准备好后立即开始。 +1. `preflight` 决定哪些通道实际存在。`docs-scope` 和 `changed-scope` 逻辑是此作业内的步骤,而不是独立作业。 +2. `security-scm-fast`、`security-dependency-audit`、`security-fast`、`check`、`check-additional`、`check-docs` 和 `skills-python` 会快速失败,而无需等待更重的产物和平台矩阵作业。 +3. `build-artifacts` 会与快速 Linux 通道重叠运行,因此下游消费者可以在共享构建就绪后立即启动。 4. 更重的平台和运行时通道随后展开:`checks-fast-core`、`checks-fast-contracts-channels`、`checks-node-core-test`、`checks`、`checks-windows`、`macos-node`、`macos-swift` 和 `android`。 -当同一 PR 或 `main` ref 上有更新推送落地时,GitHub 可能会将被取代的作业标记为 `cancelled`。除非同一 ref 的最新运行也失败,否则应将其视为 CI 噪声。聚合分片检查使用 `!cancelled() && always()`,因此它们仍会报告正常的分片失败,但不会在整个工作流已经被取代后继续排队。自动 CI 并发键带版本号(`CI-v7-*`),因此 GitHub 侧旧队列组中的僵尸运行无法无限期阻塞更新的 main 运行。手动全套件运行使用 `CI-manual-v1-*`,且不会取消正在进行的运行。 +当同一个 PR 或 `main` ref 上有新的推送落地时,GitHub 可能会将被取代的作业标记为 `cancelled`。除非同一 ref 的最新运行也在失败,否则将其视为 CI 噪音。聚合分片检查使用 `!cancelled() && always()`,因此它们仍会报告正常的分片失败,但在整个工作流已经被取代后不会继续排队。自动 CI 并发键带有版本号(`CI-v7-*`),因此 GitHub 侧旧队列组中的僵尸任务无法无限期阻塞较新的 main 运行。手动全套件运行使用 `CI-manual-v1-*`,并且不会取消正在进行的运行。 ## 范围和路由 -范围逻辑位于 `scripts/ci-changed-scope.mjs`,并由 `src/scripts/ci-changed-scope.test.ts` 中的单元测试覆盖。手动分发会跳过已更改范围检测,并让预检清单表现得像每个有范围的区域都已更改。 +范围逻辑位于 `scripts/ci-changed-scope.mjs`,并由 `src/scripts/ci-changed-scope.test.ts` 中的单元测试覆盖。手动调度会跳过 changed-scope 检测,并让 preflight 清单表现得像每个限定范围区域都发生了变更。 -- **CI 工作流编辑**会验证 Node CI 图以及工作流 linting,但不会单独强制 Windows、Android 或 macOS 原生构建;这些平台通道仍限定于平台源代码更改。 -- **仅 CI 路由编辑、选定的低成本核心测试 fixture 编辑,以及窄范围插件契约 helper/测试路由编辑**会使用快速 Node-only 清单路径:`preflight`、安全检查和单个 `checks-fast-core` 任务。当更改仅限于该快速任务直接覆盖的路由或 helper 表面时,该路径会跳过构建产物、Node 22 兼容性、渠道契约、完整核心分片、内置插件分片和额外守卫矩阵。 -- **Windows Node 检查**限定于 Windows 特定的进程/路径包装器、npm/pnpm/UI 运行器 helper、包管理器配置,以及执行该通道的 CI 工作流表面;无关源码、插件、安装冒烟和仅测试更改会保留在 Linux Node 通道上。 +- **CI 工作流编辑**会验证 Node CI 图和工作流 lint,但不会单独强制运行 Windows、Android 或 macOS 原生构建;这些平台通道仍限定到平台源代码变更。 +- **仅 CI 路由编辑、选定的廉价核心测试 fixture 编辑,以及窄范围的插件契约 helper/测试路由编辑**会使用快速的仅 Node 清单路径:`preflight`、安全检查和一个 `checks-fast-core` 任务。当变更仅限于该快速任务直接覆盖的路由或 helper 表面时,此路径会跳过构建产物、Node 22 兼容性、渠道契约、完整核心分片、内置插件分片,以及额外防护矩阵。 +- **Windows Node 检查**限定到 Windows 特定的进程/路径 wrapper、npm/pnpm/UI runner helper、包管理器配置,以及执行该通道的 CI 工作流表面;无关的源代码、插件、install-smoke 和仅测试变更会留在 Linux Node 通道上。 -最慢的 Node 测试族会被拆分或平衡,让每个作业保持小规模且不过度预留 runner:渠道契约作为三个加权分片运行,小型核心单元通道成对运行,auto-reply 作为四个平衡 worker 运行(reply 子树拆分为 agent-runner、dispatch 和 commands/state-routing 分片),agentic Gateway 网关/插件配置则分布在现有仅源码 agentic Node 作业中,而不是等待构建产物。广泛的浏览器、QA、媒体和杂项插件测试使用各自专用的 Vitest 配置,而不是共享的插件兜底配置。包含模式分片使用 CI 分片名称记录计时条目,因此 `.artifacts/vitest-shard-timings.json` 可以区分完整配置与过滤后的分片。`check-additional` 会将包边界编译/canary 工作保持在一起,并把运行时拓扑架构与 Gateway 网关 watch 覆盖分开;边界守卫分片会在一个作业内并发运行其小型独立守卫。在 `dist/` 和 `dist-runtime/` 已构建完成后,Gateway 网关 watch、渠道测试和核心支持边界分片会在 `build-artifacts` 内并发运行。 +最慢的 Node 测试系列会被拆分或平衡,让每个作业保持较小规模,同时不过度预留 runner:渠道契约作为三个加权分片运行,小型核心单元通道会成对运行,auto-reply 作为四个平衡 worker 运行(reply 子树拆分为 agent-runner、dispatch 和 commands/state-routing 分片),agentic gateway/插件配置会分布在现有的仅源码 agentic Node 作业中,而不是等待构建产物。广泛的浏览器、QA、媒体和杂项插件测试使用各自专用的 Vitest 配置,而不是共享的插件兜底配置。include-pattern 分片使用 CI 分片名称记录计时条目,因此 `.artifacts/vitest-shard-timings.json` 可以区分整个配置与经过过滤的分片。`check-additional` 将包边界编译/canary 工作放在一起,并将运行时拓扑架构与 Gateway 网关 watch 覆盖范围分开;边界防护分片会在一个作业内并发运行它的小型独立防护。Gateway 网关 watch、渠道测试和核心支持边界分片会在 `dist/` 和 `dist-runtime/` 已经构建完成后,在 `build-artifacts` 内并发运行。 -Android CI 会同时运行 `testPlayDebugUnitTest` 和 `testThirdPartyDebugUnitTest`,然后构建 Play debug APK。第三方 flavor 没有单独的 source set 或 manifest;其单元测试通道仍会使用 SMS/call-log BuildConfig 标志编译该 flavor,同时避免在每个 Android 相关推送上重复执行 debug APK 打包作业。 +Android CI 会运行 `testPlayDebugUnitTest` 和 `testThirdPartyDebugUnitTest`,然后构建 Play debug APK。third-party flavor 没有单独的 source set 或 manifest;它的单元测试通道仍会使用 SMS/通话记录 BuildConfig 标志编译该 flavor,同时避免在每个 Android 相关推送上重复执行 debug APK 打包作业。 -`check-dependencies` 分片运行 `pnpm deadcode:dependencies`(生产 Knip 仅依赖检查,固定到最新 Knip 版本,并为 `dlx` 安装禁用 pnpm 的最低发布时间)和 `pnpm deadcode:unused-files`,后者会将 Knip 的生产未使用文件发现结果与 `scripts/deadcode-unused-files.allowlist.mjs` 进行比较。当 PR 添加新的未经审查的未使用文件,或留下过期的允许列表条目时,未使用文件守卫会失败,同时保留 Knip 无法静态解析的有意动态插件、生成产物、构建、live-test 和包桥接表面。 +`check-dependencies` 分片会运行 `pnpm deadcode:dependencies`(一个仅生产 Knip 依赖检查,固定到最新 Knip 版本,并在 `dlx` 安装时禁用 pnpm 的 minimum release age)和 `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 令牌,然后向 `openclaw/clawsweeper` 分发紧凑的 `repository_dispatch` 负载。 +`.github/workflows/clawsweeper-dispatch.yml` 是从 OpenClaw 仓库活动到 ClawSweeper 的目标侧桥接。它不会检出或执行不可信的拉取请求代码。该工作流会从 `CLAWSWEEPER_APP_PRIVATE_KEY` 创建 GitHub App token,然后向 `openclaw/clawsweeper` 调度紧凑的 `repository_dispatch` payload。 -该工作流有四个通道: +该工作流有四条通道: -- `clawsweeper_item` 用于精确的问题和拉取请求审查请求; -- `clawsweeper_comment` 用于问题评论中的显式 ClawSweeper 命令; +- `clawsweeper_item` 用于精确的 issue 和拉取请求审查请求; +- `clawsweeper_comment` 用于 issue 评论中的显式 ClawSweeper 命令; - `clawsweeper_commit_review` 用于 `main` 推送上的提交级审查请求; - `github_activity` 用于 ClawSweeper 智能体可能检查的一般 GitHub 活动。 -`github_activity` 通道只转发规范化元数据:事件类型、操作、actor、仓库、条目编号、URL、标题、状态,以及存在评论或审查时的短摘录。它有意避免转发完整 webhook 正文。`openclaw/clawsweeper` 中的接收工作流是 `.github/workflows/github-activity.yml`,该工作流会将规范化事件发布到 ClawSweeper 智能体的 OpenClaw Gateway 网关钩子。 +`github_activity` 通道只转发规范化的元数据:事件类型、动作、参与者、仓库、条目编号、URL、标题、状态,以及存在评论或审查时的短摘录。它有意避免转发完整 webhook body。`openclaw/clawsweeper` 中的接收工作流是 `.github/workflows/github-activity.yml`,该工作流会将规范化事件发布到面向 ClawSweeper 智能体的 OpenClaw Gateway 网关 hook。 -一般活动是观察,而不是默认投递。ClawSweeper 智能体会在其提示中收到 Discord 目标,并且只有当事件令人意外、可执行、有风险或具备运维价值时,才应发布到 `#clawsweeper`。常规打开、编辑、机器人变动、重复 webhook 噪声和正常审查流量应返回 `NO_REPLY`。 +一般活动是观察,而不是默认投递。ClawSweeper 智能体会在其 prompt 中收到 Discord 目标,并且只有当事件令人意外、可执行、有风险或对运营有用时,才应发布到 `#clawsweeper`。例行打开、编辑、机器人噪音、重复 webhook 噪音以及正常审查流量应返回 `NO_REPLY`。 -在此路径中,始终将 GitHub 标题、评论、正文、审查文本、分支名称和提交消息视为不受信任的数据。它们是用于摘要和分诊的输入,不是工作流或智能体运行时的指令。 +在整个路径中,都应将 GitHub 标题、评论、正文、审查文本、分支名称和提交消息视为不可信数据。它们是摘要和分流的输入,而不是工作流或智能体运行时的指令。 -## 手动分发 +## 手动调度 -手动 CI 调度运行与普通 CI 相同的作业图,但强制启用每个非 Android 范围的执行线:Linux Node 分片、内置插件分片、渠道契约、Node 22 兼容性、`check`、`check-additional`、构建冒烟、文档检查、Python Skills、Windows、macOS 和 Control UI i18n。独立的手动 CI 调度仅在 `include_android=true` 时运行 Android;完整发布总控工作流通过传入 `include_android=true` 启用 Android。插件预发布静态检查、仅发布使用的 `agentic-plugins` 分片、完整插件批量扫描,以及插件预发布 Docker 执行线不包含在 CI 中。Docker 预发布套件仅在 `Full Release Validation` 调度单独的 `Plugin Prerelease` 工作流并启用发布验证门禁时运行。 +手动 CI 调度运行与常规 CI 相同的任务图,但会强制开启每个非 Android 范围的 lane:Linux Node 分片、内置插件分片、渠道契约、Node 22 兼容性、`check`、`check-additional`、构建冒烟、文档检查、Python Skills、Windows、macOS 和 Control UI i18n。独立的手动 CI 调度仅在 `include_android=true` 时运行 Android;完整发布总控通过传入 `include_android=true` 启用 Android。插件预发布静态检查、仅发布使用的 `agentic-plugins` 分片、完整插件批量扫描以及插件预发布 Docker lane 都不包含在 CI 中。Docker 预发布套件仅在 `Full Release Validation` 调度单独的 `Plugin Prerelease` 工作流并启用发布验证门禁时运行。 -手动运行使用唯一的并发组,因此发布候选版本的完整套件不会被同一 ref 上的另一个推送或 PR 运行取消。可选的 `target_ref` 输入允许受信任的调用方在使用所选调度 ref 中的工作流文件时,针对某个分支、标签或完整提交 SHA 运行该作业图。 +手动运行使用唯一的并发组,因此候选发布的完整套件不会被同一 ref 上的另一个 push 或 PR 运行取消。可选的 `target_ref` 输入允许受信任的调用方在使用所选调度 ref 中的工作流文件时,针对分支、标签或完整提交 SHA 运行该任务图。 ```bash gh workflow run ci.yml --ref release/YYYY.M.D @@ -98,17 +98,17 @@ gh workflow run full-release-validation.yml --ref main -f ref= ## 运行器 -| 运行器 | 作业 | +| 运行器 | 任务 | | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `ubuntu-24.04` | `preflight`,快速安全作业和聚合(`security-scm-fast`、`security-dependency-audit`、`security-fast`),快速协议/契约/内置检查,分片渠道契约检查,除 lint 外的 `check` 分片,`check-additional` 分片和聚合,Node 测试聚合验证器,文档检查,Python Skills,workflow-sanity,labeler,auto-response;install-smoke 预检也使用 GitHub 托管的 Ubuntu,使 Blacksmith 矩阵可以更早排队 | -| `blacksmith-4vcpu-ubuntu-2404` | `CodeQL Critical Quality`,较轻量的插件分片,`checks-fast-core`,`checks-node-compat-node22`,`check-prod-types` 和 `check-test-types` | -| `blacksmith-8vcpu-ubuntu-2404` | `build-artifacts`,build-smoke,Linux Node 测试分片,内置插件测试分片,`android` | -| `blacksmith-16vcpu-ubuntu-2404` | `check-lint`(对 CPU 足够敏感,8 vCPU 的成本超过了节省的时间);install-smoke Docker 构建(32-vCPU 的排队时间成本超过了节省的时间) | +| `ubuntu-24.04` | `preflight`,快速安全任务和聚合任务(`security-scm-fast`、`security-dependency-audit`、`security-fast`)、快速协议/契约/内置检查、分片渠道契约检查、除 lint 外的 `check` 分片、`check-additional` 分片和聚合任务、Node 测试聚合验证器、文档检查、Python Skills、workflow-sanity、labeler、auto-response;install-smoke 预检也使用 GitHub 托管的 Ubuntu,以便 Blacksmith 矩阵可以更早排队 | +| `blacksmith-4vcpu-ubuntu-2404` | `CodeQL Critical Quality`、较低权重的插件分片、`checks-fast-core`、`checks-node-compat-node22`、`check-prod-types` 和 `check-test-types` | +| `blacksmith-8vcpu-ubuntu-2404` | `build-artifacts`、build-smoke、Linux Node 测试分片、内置插件测试分片、`android` | +| `blacksmith-16vcpu-ubuntu-2404` | `check-lint`(对 CPU 足够敏感,8 vCPU 的成本超过了节省的成本);install-smoke Docker 构建(32-vCPU 排队时间的成本超过了节省的成本) | | `blacksmith-16vcpu-windows-2025` | `checks-windows` | | `blacksmith-6vcpu-macos-latest` | `openclaw/openclaw` 上的 `macos-node`;fork 回退到 `macos-latest` | | `blacksmith-12vcpu-macos-latest` | `openclaw/openclaw` 上的 `macos-swift`;fork 回退到 `macos-latest` | -## 本地等效命令 +## 本地等价命令 ```bash pnpm changed:lanes # inspect the local changed-lane classifier for origin/main...HEAD @@ -135,7 +135,7 @@ pnpm test:perf:groups:compare .artifacts/test-perf/baseline-before.json .artifac pnpm perf:kova:summary --report .artifacts/kova/reports/mock-provider/report.json --output .artifacts/kova/summary.md ``` -## OpenClaw 性能 +## OpenClaw Performance `OpenClaw Performance` 是产品/运行时性能工作流。它每天在 `main` 上运行,也可以手动调度: @@ -144,23 +144,23 @@ gh workflow run openclaw-performance.yml --ref main -f profile=diagnostic -f rep gh workflow run openclaw-performance.yml --ref main -f profile=smoke -f repeat=1 -f deep_profile=true -f live_gpt54=true ``` -该工作流从固定版本安装 OCM,并从固定的 `kova_ref` 输入安装 Kova,然后运行三条执行线: +该工作流从固定发布版本安装 OCM,并从固定的 `kova_ref` 输入安装 Kova,然后运行三个 lane: -- `mock-provider`:针对本地构建运行时的 Kova 诊断场景,使用确定性的假 OpenAI 兼容凭证。 -- `mock-deep-profile`:针对启动、Gateway 网关和智能体轮次热点的 CPU/堆/追踪分析。 -- `live-gpt54`:真实的 OpenAI `openai/gpt-5.4` 智能体轮次,在 `OPENAI_API_KEY` 不可用时跳过。 +- `mock-provider`:使用确定性的假 OpenAI 兼容凭证,针对本地构建运行时运行 Kova 诊断场景。 +- `mock-deep-profile`:针对启动、gateway 和 agent-turn 热点进行 CPU/堆/trace 分析。 +- `live-gpt54`:一次真实的 OpenAI `openai/gpt-5.4` agent turn,在 `OPENAI_API_KEY` 不可用时跳过。 -mock-provider 执行线还会在 Kova 通过后运行 OpenClaw 原生源码探针:默认、hook 和 50 插件启动场景下的 Gateway 网关启动计时和内存;重复的模拟 OpenAI `channel-chat-baseline` hello 循环;以及针对已启动 Gateway 网关的 CLI 启动命令。源码探针 Markdown 摘要位于报告包中的 `source/index.md`,旁边有原始 JSON。 +mock-provider lane 还会在 Kova 通过后运行 OpenClaw 原生源码探针:覆盖默认、hook 和 50 插件启动场景的 gateway 启动耗时和内存;重复的 mock-OpenAI `channel-chat-baseline` hello 循环;以及针对已启动 gateway 的 CLI 启动命令。源码探针的 Markdown 摘要位于报告包中的 `source/index.md`,原始 JSON 位于其旁边。 -每条执行线都会上传 GitHub 构件。配置 `CLAWGRIT_REPORTS_TOKEN` 后,工作流还会将 `report.json`、`report.md`、包、`index.md` 和源码探针构件提交到 `openclaw/clawgrit-reports` 的 `openclaw-performance//-//` 下。当前分支指针会写入 `openclaw-performance//latest-.json`。 +每个 lane 都会上传 GitHub artifact。当配置了 `CLAWGRIT_REPORTS_TOKEN` 时,该工作流还会将 `report.json`、`report.md`、bundle、`index.md` 和源码探针 artifact 提交到 `openclaw/clawgrit-reports` 中的 `openclaw-performance//-//` 下。当前分支指针会写入 `openclaw-performance//latest-.json`。 ## 完整发布验证 -`Full Release Validation` 是用于“发布前运行所有内容”的手动总控工作流。它接受分支、标签或完整提交 SHA,使用该目标调度手动 `CI` 工作流,调度 `Plugin Prerelease` 以提供仅发布使用的插件/包/静态/Docker 证明,并调度 `OpenClaw Release Checks` 以运行安装冒烟、包验收、Docker 发布路径套件、live/E2E、OpenWebUI、QA Lab parity、Matrix 和 Telegram 执行线。当 `rerun_group=all` 且 `release_profile=full` 时,它还会针对发布检查产生的 `release-package-under-test` 构件运行 `NPM Telegram Beta E2E`。发布后,传入 `npm_telegram_package_spec` 可针对已发布的 npm 包重新运行同一 Telegram 包执行线。 +`Full Release Validation` 是用于“发布前运行所有内容”的手动总控工作流。它接受分支、标签或完整提交 SHA,使用该目标调度手动 `CI` 工作流,为仅发布使用的插件/包/静态/Docker 证明调度 `Plugin Prerelease`,并为安装冒烟、包验收、Docker 发布路径套件、live/E2E、OpenWebUI、QA Lab parity、Matrix 和 Telegram lane 调度 `OpenClaw Release Checks`。在 `rerun_group=all` 且 `release_profile=full` 时,它还会针对发布检查中的 `release-package-under-test` artifact 运行 `NPM Telegram Beta E2E`。发布后,传入 `npm_telegram_package_spec` 以针对已发布的 npm 包重新运行同一个 Telegram 包 lane。 -有关阶段矩阵、确切工作流作业名称、profile 差异、构件和定向重跑句柄,请参阅[完整发布验证](/zh-CN/reference/full-release-validation)。 +请参阅[完整发布验证](/zh-CN/reference/full-release-validation),了解阶段矩阵、确切的工作流任务名称、profile 差异、artifact 以及聚焦重跑句柄。 -`OpenClaw Release Publish` 是会产生变更的手动发布工作流。在发布标签存在且 OpenClaw npm 预检成功后,从 `release/YYYY.M.D` 或 `main` 调度它。它会验证 `pnpm plugins:sync:check`,为所有可发布的插件包调度 `Plugin NPM Release`,为同一个发布 SHA 调度 `Plugin ClawHub Release`,并且只有在这之后才会使用保存的 `preflight_run_id` 调度 `OpenClaw NPM Release`。 +`OpenClaw Release Publish` 是会产生变更的手动发布工作流。请在发布标签存在且 OpenClaw npm 预检成功后,从 `release/YYYY.M.D` 或 `main` 调度它。它会验证 `pnpm plugins:sync:check`,为所有可发布的插件包调度 `Plugin NPM Release`,为同一个发布 SHA 调度 `Plugin ClawHub Release`,然后才使用保存的 `preflight_run_id` 调度 `OpenClaw NPM Release`。 ```bash gh workflow run openclaw-release-publish.yml \ @@ -176,25 +176,25 @@ gh workflow run openclaw-release-publish.yml \ pnpm ci:full-release --sha ``` -GitHub 工作流调度 ref 必须是分支或标签,不能是原始提交 SHA。该辅助命令会在目标 SHA 处推送一个临时 `release-ci/-...` 分支,从该固定 ref 调度 `Full Release Validation`,验证每个子工作流的 `headSha` 都与目标匹配,并在运行完成时删除临时分支。如果任何子工作流在不同的 SHA 上运行,总控验证器也会失败。 +GitHub 工作流调度 ref 必须是分支或标签,不能是原始提交 SHA。该辅助命令会在目标 SHA 上推送一个临时 `release-ci/-...` 分支,从该固定 ref 调度 `Full Release Validation`,验证每个子工作流的 `headSha` 都与目标匹配,并在运行完成后删除临时分支。如果任何子工作流在不同 SHA 上运行,总控验证器也会失败。 -`release_profile` 控制传入发布检查的 live/provider 覆盖范围。手动发布工作流默认使用 `stable`;仅在你有意需要广泛的 advisory provider/media 矩阵时才使用 `full`。 +`release_profile` 控制传入发布检查的 live/provider 覆盖范围。手动发布工作流默认使用 `stable`;仅在你有意需要广泛的 advisory provider/media 矩阵时使用 `full`。 -- `minimum` 保留最快的 OpenAI/核心发布关键执行线。 +- `minimum` 保留最快的 OpenAI/核心发布关键 lane。 - `stable` 添加稳定的 provider/backend 集合。 - `full` 运行广泛的 advisory provider/media 矩阵。 -总控工作流会记录已调度的子运行 ID,最终的 `Verify full validation` 作业会重新检查当前子运行结论,并为每个子运行追加最慢作业表。如果某个子工作流被重新运行并转为绿色,只需重新运行父验证器作业即可刷新总控结果和计时摘要。 +总控会记录已调度的子运行 ID,最终的 `Verify full validation` 任务会重新检查当前子运行结论,并为每个子运行追加最慢任务表。如果某个子工作流被重新运行并转绿,只需重新运行父验证器任务,即可刷新总控结果和耗时摘要。 -为了恢复,`Full Release Validation` 和 `OpenClaw Release Checks` 都接受 `rerun_group`。对发布候选版本使用 `all`,仅对普通完整 CI 子项使用 `ci`,仅对插件预发布子项使用 `plugin-prerelease`,对每个发布子项使用 `release-checks`,或在总括项上使用更窄的分组:`install-smoke`、`cross-os`、`live-e2e`、`package`、`qa`、`qa-parity`、`qa-live` 或 `npm-telegram`。这样可以让一次失败的发布环境在完成聚焦修复后,将重跑范围保持有界。 +为了恢复,`Full Release Validation` 和 `OpenClaw Release Checks` 都接受 `rerun_group`。在总控工作流上,发布候选版本使用 `all`,仅普通完整 CI 子项使用 `ci`,仅插件预发布子项使用 `plugin-prerelease`,每个发布子项使用 `release-checks`,也可以使用更窄的分组:`install-smoke`、`cross-os`、`live-e2e`、`package`、`qa`、`qa-parity`、`qa-live` 或 `npm-telegram`。这能让失败的发布环境在完成针对性修复后,将重跑范围限制住。 -`OpenClaw Release Checks` 使用受信任的 workflow ref 将所选 ref 一次性解析为 `release-package-under-test` tarball,然后把该产物传给 live/E2E 发布路径 Docker workflow 和包验收分片。这样可以让各个发布环境使用一致的包字节,并避免在多个子任务中重新打包同一个候选版本。 +`OpenClaw Release Checks` 使用可信工作流引用,将选定引用解析一次为 `release-package-under-test` tarball,然后把该构件传给实时/E2E 发布路径 Docker 工作流和软件包验收分片。这能让发布环境之间的软件包字节保持一致,并避免在多个子任务中重复打包同一个候选版本。 -对于 `ref=main` 和 `rerun_group=all` 的重复 `Full Release Validation` 运行会取代较旧的总括运行。父级监视器会在父级被取消时,取消它已经派发的任何子 workflow,因此较新的 main 验证不会排在陈旧的两小时 release-check 运行之后。发布分支/标签验证和聚焦重跑分组会保持 `cancel-in-progress: false`。 +对于 `ref=main` 和 `rerun_group=all` 的重复 `Full Release Validation` 运行,会取代较旧的总控工作流。当父监控器被取消时,它会取消已经分发的所有子工作流,因此较新的 main 验证不会排在过期的两小时发布检查运行后面。发布分支/标签验证和聚焦重跑分组会保持 `cancel-in-progress: false`。 -## Live 和 E2E 分片 +## 实时和 E2E 分片 -发布 live/E2E 子项保留宽泛的原生 `pnpm test:live` 覆盖范围,但它会通过 `scripts/test-live-shard.mjs` 以命名分片运行,而不是作为一个串行任务运行: +发布实时/E2E 子项保留广泛的原生 `pnpm test:live` 覆盖,但它通过 `scripts/test-live-shard.mjs` 以命名分片运行,而不是单个串行任务: - `native-live-src-agents` - `native-live-src-gateway-core` @@ -208,57 +208,57 @@ GitHub 工作流调度 ref 必须是分支或标签,不能是原始提交 SHA - `native-live-extensions-xai` - 拆分后的媒体音频/视频分片,以及按提供商过滤的音乐分片 -这样会保持相同的文件覆盖范围,同时让缓慢的 live 提供商失败更容易重跑和诊断。聚合的 `native-live-extensions-o-z`、`native-live-extensions-media` 和 `native-live-extensions-media-music` 分片名称仍可用于手动一次性重跑。 +这会保持相同的文件覆盖,同时让较慢的实时提供商失败更容易重跑和诊断。聚合的 `native-live-extensions-o-z`、`native-live-extensions-media` 和 `native-live-extensions-media-music` 分片名称仍可用于手动一次性重跑。 -原生 live 媒体分片在 `ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04` 中运行,该镜像由 `Live Media Runner Image` workflow 构建。该镜像预装了 `ffmpeg` 和 `ffprobe`;媒体任务只会在设置前验证这些二进制文件。让 Docker 支撑的 live 套件继续在普通 Blacksmith runner 上运行,容器任务不是启动嵌套 Docker 测试的合适位置。 +原生实时媒体分片在 `ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04` 中运行,该镜像由 `Live Media Runner Image` 工作流构建。该镜像预安装了 `ffmpeg` 和 `ffprobe`;媒体任务只会在设置前验证这些二进制文件。将 Docker 支持的实时套件保留在普通 Blacksmith 运行器上,容器任务不适合启动嵌套 Docker 测试。 -Docker 支撑的 live 模型/后端分片会为每个所选提交使用单独的共享 `ghcr.io/openclaw/openclaw-live-test:` 镜像。live 发布 workflow 构建并推送该镜像一次,然后 Docker live 模型、按提供商分片的 Gateway 网关、CLI 后端、ACP bind 和 Codex harness 分片会以 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行。Gateway 网关 Docker 分片带有显式的脚本级 `timeout` 上限,低于 workflow 任务超时,因此卡住的容器或清理路径会快速失败,而不是耗尽整个 release-check 预算。如果这些分片独立重建完整源码 Docker 目标,说明发布运行配置错误,并会把挂钟时间浪费在重复镜像构建上。 +Docker 支持的实时模型/后端分片会为每个选定提交使用单独的共享 `ghcr.io/openclaw/openclaw-live-test:` 镜像。实时发布工作流会构建并推送该镜像一次,然后 Docker 实时模型、按提供商分片的 Gateway 网关、CLI 后端、ACP 绑定和 Codex harness 分片会带着 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行。Gateway 网关 Docker 分片带有显式脚本级 `timeout` 上限,低于工作流任务超时,因此卡住的容器或清理路径会快速失败,而不是消耗整个发布检查预算。如果这些分片独立重建完整源 Docker 目标,则说明发布运行配置错误,并会把墙钟时间浪费在重复镜像构建上。 -## 包验收 +## 软件包验收 -当问题是“这个可安装的 OpenClaw 包是否能作为产品正常工作?”时,使用 `Package Acceptance`。它不同于普通 CI:普通 CI 验证源码树,而包验收会通过用户在安装或更新后使用的同一 Docker E2E harness 来验证单个 tarball。 +当问题是“这个可安装的 OpenClaw 软件包是否作为产品正常工作?”时,使用 `Package Acceptance`。它不同于普通 CI:普通 CI 验证源码树,而软件包验收会通过用户安装或更新后使用的同一套 Docker E2E harness 来验证单个 tarball。 ### 任务 -1. `resolve_package` 检出 `workflow_ref`,解析一个包候选项,写入 `.artifacts/docker-e2e-package/openclaw-current.tgz`,写入 `.artifacts/docker-e2e-package/package-candidate.json`,将两者作为 `package-under-test` 产物上传,并在 GitHub 步骤摘要中打印来源、workflow ref、package ref、版本、SHA-256 和 profile。 -2. `docker_acceptance` 使用 `ref=workflow_ref` 和 `package_artifact_name=package-under-test` 调用 `openclaw-live-and-e2e-checks-reusable.yml`。可复用 workflow 会下载该产物,验证 tarball 清单,在需要时准备 package-digest Docker 镜像,并针对该包运行所选 Docker lanes,而不是打包 workflow 检出内容。当某个 profile 选择多个目标 `docker_lanes` 时,可复用 workflow 会先准备一次包和共享镜像,然后将这些 lanes 扇出为带有唯一产物的并行目标 Docker 任务。 -3. `package_telegram` 可选调用 `NPM Telegram Beta E2E`。当 `telegram_mode` 不是 `none` 时它会运行,并在包验收解析出包后安装同一个 `package-under-test` 产物;独立 Telegram 派发仍然可以安装已发布的 npm spec。 -4. `summary` 会在包解析、Docker 验收或可选 Telegram lane 失败时让 workflow 失败。 +1. `resolve_package` 检出 `workflow_ref`,解析一个软件包候选,写入 `.artifacts/docker-e2e-package/openclaw-current.tgz`,写入 `.artifacts/docker-e2e-package/package-candidate.json`,将二者作为 `package-under-test` 构件上传,并在 GitHub 步骤摘要中打印来源、工作流引用、软件包引用、版本、SHA-256 和配置档。 +2. `docker_acceptance` 使用 `ref=workflow_ref` 和 `package_artifact_name=package-under-test` 调用 `openclaw-live-and-e2e-checks-reusable.yml`。可复用工作流会下载该构件,验证 tarball 清单,在需要时准备软件包摘要 Docker 镜像,并针对该软件包运行选定的 Docker lanes,而不是打包工作流检出内容。当某个配置档选择多个目标 `docker_lanes` 时,可复用工作流会准备一次软件包和共享镜像,然后将这些 lanes 扇出为并行的目标 Docker 任务,并使用唯一构件。 +3. `package_telegram` 可选调用 `NPM Telegram Beta E2E`。当 `telegram_mode` 不是 `none` 时运行;如果软件包验收解析了一个 `package-under-test` 构件,它会安装同一个构件;独立 Telegram 分发仍可安装已发布的 npm 规范。 +4. 如果软件包解析、Docker 验收或可选 Telegram lane 失败,`summary` 会使工作流失败。 ### 候选来源 -- `source=npm` 只接受 `openclaw@alpha`、`openclaw@beta`、`openclaw@latest`,或精确的 OpenClaw 发布版本,例如 `openclaw@2026.4.27-beta.2`。将它用于已发布预发布版/稳定版验收。 -- `source=ref` 会打包受信任的 `package_ref` 分支、标签或完整提交 SHA。解析器会获取 OpenClaw 分支/标签,验证所选提交可从仓库分支历史或发布标签到达,在 detached worktree 中安装依赖,并用 `scripts/package-openclaw-for-docker.mjs` 打包它。 +- `source=npm` 只接受 `openclaw@alpha`、`openclaw@beta`、`openclaw@latest` 或精确的 OpenClaw 发布版本,例如 `openclaw@2026.4.27-beta.2`。用于已发布的预发布/稳定版验收。 +- `source=ref` 打包可信的 `package_ref` 分支、标签或完整提交 SHA。解析器会获取 OpenClaw 分支/标签,验证选定提交可从仓库分支历史或发布标签到达,在分离 worktree 中安装依赖,并用 `scripts/package-openclaw-for-docker.mjs` 打包。 - `source=url` 下载 HTTPS `.tgz`;必须提供 `package_sha256`。 -- `source=artifact` 从 `artifact_run_id` 和 `artifact_name` 下载一个 `.tgz`;`package_sha256` 可选,但应为外部共享的产物提供它。 +- `source=artifact` 从 `artifact_run_id` 和 `artifact_name` 下载一个 `.tgz`;`package_sha256` 可选,但对于外部共享构件应提供。 -保持 `workflow_ref` 和 `package_ref` 分离。`workflow_ref` 是运行测试的受信任 workflow/harness 代码。`package_ref` 是在 `source=ref` 时被打包的源提交。这样当前测试 harness 可以验证较旧的受信任源提交,而无需运行旧的 workflow 逻辑。 +保持 `workflow_ref` 和 `package_ref` 分离。`workflow_ref` 是运行测试的可信工作流/harness 代码。`package_ref` 是当 `source=ref` 时要打包的源提交。这让当前测试 harness 能够验证较旧的可信源提交,而不运行旧的工作流逻辑。 -### 套件 profile +### 套件配置档 - `smoke` — `npm-onboard-channel-agent`、`gateway-network`、`config-reload` - `package` — `npm-onboard-channel-agent`、`doctor-switch`、`update-channel-switch`、`upgrade-survivor`、`published-upgrade-survivor`、`plugins-offline`、`plugin-update` - `product` — `package` 加上 `mcp-channels`、`cron-mcp-cleanup`、`openai-web-search-minimal`、`openwebui` -- `full` — 带 OpenWebUI 的完整 Docker 发布路径块 +- `full` — 带 OpenWebUI 的完整 Docker 发布路径分块 - `custom` — 精确的 `docker_lanes`;当 `suite_profile=custom` 时必需 -`package` profile 使用离线插件覆盖范围,因此已发布包验证不会受 live ClawHub 可用性限制。可选 Telegram lane 会在 `NPM Telegram Beta E2E` 中复用 `package-under-test` 产物,同时保留已发布 npm spec 路径用于独立派发。 +`package` 配置档使用离线插件覆盖,因此已发布软件包验证不会受实时 ClawHub 可用性限制。可选 Telegram lane 会在 `NPM Telegram Beta E2E` 中复用 `package-under-test` 构件,同时为独立分发保留已发布 npm 规范路径。 -有关专门的更新和插件测试策略,包括本地命令、Docker lanes、包验收输入、发布默认值和失败分诊,请参阅 [更新和插件测试](/zh-CN/help/testing-updates-plugins)。 +有关专门的更新和插件测试策略,包括本地命令、Docker lanes、软件包验收输入、发布默认值和失败分诊,请参见[更新和插件测试](/zh-CN/help/testing-updates-plugins)。 -发布检查会使用 `source=artifact`、准备好的发布包产物、`suite_profile=custom`、`docker_lanes='doctor-switch update-channel-switch upgrade-survivor published-upgrade-survivor plugins-offline plugin-update'`、`published_upgrade_survivor_baselines=all-since-2026.4.23`、`published_upgrade_survivor_scenarios=reported-issues` 和 `telegram_mode=mock-openai` 调用包验收。这样可以把包迁移、更新、陈旧插件依赖清理、已配置插件安装修复、离线插件、插件更新和 Telegram 证明放在同一个已解析包 tarball 上。在 Full Release Validation 或 OpenClaw Release Checks 上设置 `package_acceptance_package_spec`,可针对已发布 npm 包而不是基于 SHA 构建的产物运行同一矩阵。跨 OS 发布检查仍然覆盖 OS 特定的新手引导、安装器和平台行为;包/更新产品验证应从包验收开始。`published-upgrade-survivor` Docker lane 每次运行会验证一个已发布包基线。在包验收中,解析出的 `package-under-test` tarball 始终是候选项,而 `published_upgrade_survivor_baseline` 选择回退的已发布基线,默认是 `openclaw@latest`;失败 lane 的重跑命令会保留该基线。设置 `published_upgrade_survivor_baselines=all-since-2026.4.23` 可将 Full Release CI 扩展到从 `2026.4.23` 到 `latest` 的每个稳定 npm 发布版;`release-history` 仍可用于以较旧的日期前锚点进行手动更宽采样。设置 `published_upgrade_survivor_scenarios=reported-issues` 可将相同基线扩展到问题形态的 fixtures,覆盖 Feishu 配置、保留的 bootstrap/persona 文件、已配置的 OpenClaw 插件安装、波浪号日志路径和陈旧旧版插件依赖根。单独的 `Update Migration` workflow 会在问题是穷尽式已发布更新清理,而不是普通 Full Release CI 广度时,使用带 `all-since-2026.4.23` 和 `plugin-deps-cleanup` 的 `update-migration` Docker lane。本地聚合运行可以通过 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPECS` 传入精确包 spec,使用 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPEC` 保持单个 lane,例如 `openclaw@2026.4.15`,或设置 `OPENCLAW_UPGRADE_SURVIVOR_SCENARIOS` 以运行场景矩阵。已发布 lane 使用内置的 `openclaw config set` 命令 recipe 配置基线,在 `summary.json` 中记录 recipe 步骤,并在 Gateway 网关启动后探测 `/healthz`、`/readyz` 以及 RPC 状态。Windows 打包和安装器全新 lane 还会验证已安装包能否从原始绝对 Windows 路径导入 browser-control override。OpenAI 跨 OS agent-turn smoke 在设置时默认使用 `OPENCLAW_CROSS_OS_OPENAI_MODEL`,否则使用 `openai/gpt-5.4`,因此安装和 Gateway 网关证明会保持在 GPT-5 测试模型上,同时避免 GPT-4.x 默认值。 +发布检查会调用软件包验收,并使用 `source=artifact`、已准备好的发布软件包构件、`suite_profile=custom`、`docker_lanes='doctor-switch update-channel-switch upgrade-survivor published-upgrade-survivor plugins-offline plugin-update'`、`published_upgrade_survivor_baselines=all-since-2026.4.23`、`published_upgrade_survivor_scenarios=reported-issues` 和 `telegram_mode=mock-openai`。这能让软件包迁移、更新、过期插件依赖清理、已配置插件安装修复、离线插件、插件更新和 Telegram 证明都基于同一个已解析的软件包 tarball。在 Full Release Validation 或 OpenClaw Release Checks 上设置 `package_acceptance_package_spec`,可对已发布的 npm 软件包运行同一矩阵,而不是针对 SHA 构建的构件运行。跨操作系统发布检查仍覆盖特定操作系统的新手引导、安装程序和平台行为;软件包/更新产品验证应从软件包验收开始。`published-upgrade-survivor` Docker lane 在每次运行中验证一个已发布软件包基线。在软件包验收中,已解析的 `package-under-test` tarball 始终是候选包,而 `published_upgrade_survivor_baseline` 选择回退的已发布基线,默认是 `openclaw@latest`;失败 lane 重跑命令会保留该基线。设置 `published_upgrade_survivor_baselines=all-since-2026.4.23`,可将完整发布 CI 扩展到从 `2026.4.23` 到 `latest` 的每个稳定 npm 发布;`release-history` 仍可用于使用较旧日期前锚点的手动更广采样。设置 `published_upgrade_survivor_scenarios=reported-issues`,可将同一组基线扩展到类似问题的夹具,覆盖 Feishu 配置、保留的 bootstrap/persona 文件、已配置的 OpenClaw 插件安装、波浪号日志路径和过期旧版插件依赖根。单独的 `Update Migration` 工作流在问题是穷尽式已发布更新清理而非普通完整发布 CI 广度时,会使用带 `all-since-2026.4.23` 和 `plugin-deps-cleanup` 的 `update-migration` Docker lane。本地聚合运行可以通过 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPECS` 传入精确软件包规范,通过 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPEC` 保持单个 lane,例如 `openclaw@2026.4.15`,或者为场景矩阵设置 `OPENCLAW_UPGRADE_SURVIVOR_SCENARIOS`。已发布 lane 会用内置的 `openclaw config set` 命令配方配置基线,在 `summary.json` 中记录配方步骤,并在 Gateway 网关启动后探测 `/healthz`、`/readyz` 以及 RPC 状态。Windows 打包和安装程序全新安装 lanes 还会验证已安装软件包可以从原始绝对 Windows 路径导入 browser-control 覆盖。OpenAI 跨操作系统 agent 回合冒烟在设置时默认使用 `OPENCLAW_CROSS_OS_OPENAI_MODEL`,否则使用 `openai/gpt-5.4`,因此安装和 Gateway 网关证明会保留在 GPT-5 测试模型上,同时避免 GPT-4.x 默认值。 ### 旧版兼容窗口 -包验收对已经发布的包有有界的旧版兼容窗口。到 `2026.4.25` 为止的包,包括 `2026.4.25-beta.*`,可以使用兼容路径: +软件包验收为已经发布的软件包提供有界旧版兼容窗口。到 `2026.4.25` 为止的软件包,包括 `2026.4.25-beta.*`,可以使用兼容路径: -- `dist/postinstall-inventory.json` 中的已知私有 QA 条目可以指向 tarball 省略的文件; -- 当包未暴露 `gateway install --wrapper` 标志时,`doctor-switch` 可以跳过持久化子用例; -- `update-channel-switch` 可以从 tarball 派生的假 git fixture 中剪除缺失的 `pnpm.patchedDependencies`,并可以记录缺失的持久化 `update.channel`; -- 插件 smokes 可以读取旧版安装记录位置,或接受缺失的 marketplace 安装记录持久化; -- `plugin-update` 可以允许配置元数据迁移,同时仍要求安装记录和无重装行为保持不变。 +- `dist/postinstall-inventory.json` 中的已知私有 QA 条目可以指向 tarball 中省略的文件; +- 当软件包未暴露 `gateway install --wrapper` 标志时,`doctor-switch` 可以跳过其持久化子用例; +- `update-channel-switch` 可以从 tarball 派生的伪 git 夹具中剪除缺失的 `pnpm.patchedDependencies`,并且可以记录缺失的持久化 `update.channel`; +- 插件冒烟可以读取旧版安装记录位置,或接受缺失的 marketplace 安装记录持久化; +- `plugin-update` 可以允许配置元数据迁移,同时仍要求安装记录和不重装行为保持不变。 -已发布的 `2026.4.26` 包也可以对已经发布的本地构建元数据戳记文件发出警告。后续包必须满足现代契约;相同条件会失败,而不是警告或跳过。 +已发布的 `2026.4.26` 软件包也可以对已发布的本地构建元数据戳文件发出警告。后续软件包必须满足现代契约;相同条件会失败,而不是警告或跳过。 ### 示例 @@ -301,152 +301,151 @@ gh workflow run package-acceptance.yml \ -f docker_lanes='install-e2e plugin-update' ``` -调试失败的软件包验收运行时,先查看 `resolve_package` 摘要,确认软件包来源、版本和 SHA-256。然后检查 `docker_acceptance` 子运行及其 Docker 工件:`.artifacts/docker-tests/**/summary.json`、`failures.json`、通道日志、阶段计时和重新运行命令。优先重新运行失败的软件包配置文件或精确的 Docker 通道,而不是重新运行完整发布验证。 +调试失败的包验收运行时,先查看 `resolve_package` 摘要,以确认包来源、版本和 SHA-256。然后检查 `docker_acceptance` 子运行及其 Docker 工件:`.artifacts/docker-tests/**/summary.json`、`failures.json`、测试线日志、阶段耗时和重新运行命令。优先重新运行失败的包配置文件或精确 Docker 测试线,而不是重新运行完整发布验证。 ## 安装冒烟测试 -单独的 `Install Smoke` 工作流通过自己的 `preflight` 作业复用同一个范围脚本。它将冒烟覆盖拆分为 `run_fast_install_smoke` 和 `run_full_install_smoke`。 +独立的 `Install Smoke` 工作流通过自己的 `preflight` 作业复用同一个作用域脚本。它将冒烟覆盖拆分为 `run_fast_install_smoke` 和 `run_full_install_smoke`。 -- **快速路径**会针对触及 Docker/软件包表面、内置插件软件包/清单变更,或 Docker 冒烟作业会覆盖的核心插件/渠道/Gateway 网关/插件 SDK 表面的拉取请求运行。仅源码的内置插件变更、仅测试编辑和仅文档编辑不会预留 Docker worker。快速路径会构建一次根 Dockerfile 镜像,检查 CLI,运行智能体删除共享工作区 CLI 冒烟测试,运行容器 gateway-network e2e,验证内置插件构建参数,并在 240 秒聚合命令超时内运行有界内置插件 Docker 配置文件(每个场景的 Docker 运行会单独设定上限)。 -- **完整路径**保留 QR 软件包安装以及安装器 Docker/更新覆盖,用于每夜定时运行、手动分发、workflow-call 发布检查,以及确实触及安装器/软件包/Docker 表面的拉取请求。在完整模式下,install-smoke 会准备或复用一个目标 SHA 的 GHCR 根 Dockerfile 冒烟镜像,然后将 QR 软件包安装、根 Dockerfile/Gateway 网关冒烟、安装器/更新冒烟,以及快速内置插件 Docker E2E 作为独立作业运行,这样安装器工作不会排在根镜像冒烟之后等待。 +- **快速路径** 会在拉取请求触及 Docker/包表面、内置插件包/清单变更,或 Docker 冒烟作业会覆盖的核心插件/渠道/Gateway 网关/插件 SDK 表面时运行。仅源码的内置插件变更、仅测试编辑和仅文档编辑不会占用 Docker 工作器。快速路径会构建一次根 Dockerfile 镜像,检查 CLI,运行 agents delete 共享工作区 CLI 冒烟测试,运行容器 gateway-network e2e,验证内置扩展构建参数,并在 240 秒聚合命令超时内运行有界的内置插件 Docker 配置文件(每个场景的 Docker 运行单独设有上限)。 +- **完整路径** 为夜间定时运行、手动分派、workflow-call 发布检查,以及真正触及安装器/包/Docker 表面的拉取请求保留 QR 包安装和安装器 Docker/更新覆盖。在完整模式下,install-smoke 会准备或复用一个目标 SHA 的 GHCR 根 Dockerfile 冒烟镜像,然后将 QR 包安装、根 Dockerfile/Gateway 网关冒烟测试、安装器/更新冒烟测试,以及快速内置插件 Docker E2E 作为独立作业运行,因此安装器工作不必等待根镜像冒烟测试。 -`main` 推送(包括合并提交)不会强制使用完整路径;当变更范围逻辑会在推送上请求完整覆盖时,工作流会保留快速 Docker 冒烟,并将完整安装冒烟留给每夜运行或发布验证。 +`main` 推送(包括合并提交)不会强制完整路径;当变更作用域逻辑会在推送上请求完整覆盖时,工作流会保留快速 Docker 冒烟测试,并把完整安装冒烟测试留给夜间或发布验证。 -较慢的 Bun 全局安装 image-provider 冒烟测试由 `run_bun_global_install_smoke` 单独控制。它会在每夜计划任务和发布检查工作流中运行,手动 `Install Smoke` 分发可以选择启用它,但拉取请求和 `main` 推送不会运行它。QR 和安装器 Docker 测试保留各自面向安装的 Dockerfile。 +较慢的 Bun 全局安装 image-provider 冒烟测试由 `run_bun_global_install_smoke` 单独控制。它会在夜间计划和发布检查工作流中运行,手动 `Install Smoke` 分派也可以选择加入它,但拉取请求和 `main` 推送不会运行。QR 和安装器 Docker 测试保留各自以安装为重点的 Dockerfile。 ## 本地 Docker E2E -`pnpm test:docker:all` 会预构建一个共享的实时测试镜像,将 OpenClaw 打包一次为 npm tarball,并构建两个共享的 `scripts/e2e/Dockerfile` 镜像: +`pnpm test:docker:all` 会预构建一个共享实时测试镜像,将 OpenClaw 打包一次为 npm tarball,并构建两个共享的 `scripts/e2e/Dockerfile` 镜像: -- 一个用于安装器/更新/插件依赖通道的裸 Node/Git runner; -- 一个功能镜像,会将同一个 tarball 安装到 `/app`,用于普通功能通道。 +- 一个用于安装器/更新/plugin-dependency 测试线的裸 Node/Git 运行器; +- 一个会把同一个 tarball 安装到 `/app`、用于常规功能测试线的功能镜像。 -Docker 通道定义位于 `scripts/lib/docker-e2e-scenarios.mjs`,规划器逻辑位于 `scripts/lib/docker-e2e-plan.mjs`,runner 只执行选中的计划。调度器通过 `OPENCLAW_DOCKER_E2E_BARE_IMAGE` 和 `OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE` 为每个通道选择镜像,然后使用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行通道。 +Docker 测试线定义位于 `scripts/lib/docker-e2e-scenarios.mjs`,规划器逻辑位于 `scripts/lib/docker-e2e-plan.mjs`,运行器只执行选中的计划。调度器使用 `OPENCLAW_DOCKER_E2E_BARE_IMAGE` 和 `OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE` 为每条测试线选择镜像,然后使用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行测试线。 ### 可调参数 -| 变量 | 默认值 | 用途 | -| -------------------------------------- | ------ | --------------------------------------------------------------------------------------------- | -| `OPENCLAW_DOCKER_ALL_PARALLELISM` | 10 | 普通通道的主池槽位数。 | -| `OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM` | 10 | provider 敏感尾部池槽位数。 | -| `OPENCLAW_DOCKER_ALL_LIVE_LIMIT` | 9 | 并发实时通道上限,避免 provider 限流。 | -| `OPENCLAW_DOCKER_ALL_NPM_LIMIT` | 10 | 并发 npm 安装通道上限。 | -| `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT` | 7 | 并发多服务通道上限。 | -| `OPENCLAW_DOCKER_ALL_START_STAGGER_MS` | 2000 | 通道启动之间的错峰时间,用于避免 Docker daemon 创建风暴;设为 `0` 表示不做错峰。 | -| `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS` | 7200000 | 每个通道的兜底超时(120 分钟);选定的实时/尾部通道会使用更严格的上限。 | -| `OPENCLAW_DOCKER_ALL_DRY_RUN` | unset | `1` 会打印调度器计划而不运行通道。 | -| `OPENCLAW_DOCKER_ALL_LANES` | unset | 逗号分隔的精确通道列表;跳过清理冒烟,便于智能体复现一个失败通道。 | +| 变量 | 默认值 | 用途 | +| -------------------------------------- | ------- | --------------------------------------------------------------------------------------------- | +| `OPENCLAW_DOCKER_ALL_PARALLELISM` | 10 | 常规测试线的主池槽位数。 | +| `OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM` | 10 | 提供商敏感尾池的槽位数。 | +| `OPENCLAW_DOCKER_ALL_LIVE_LIMIT` | 9 | 并发实时测试线上限,避免提供商限流。 | +| `OPENCLAW_DOCKER_ALL_NPM_LIMIT` | 10 | 并发 npm 安装测试线上限。 | +| `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT` | 7 | 并发多服务测试线上限。 | +| `OPENCLAW_DOCKER_ALL_START_STAGGER_MS` | 2000 | 测试线启动之间的错峰间隔,用于避免 Docker daemon 创建风暴;设置为 `0` 表示不做错峰。 | +| `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS` | 7200000 | 每条测试线的兜底超时(120 分钟);选定的实时/尾部测试线使用更严格的上限。 | +| `OPENCLAW_DOCKER_ALL_DRY_RUN` | unset | `1` 会打印调度器计划而不运行测试线。 | +| `OPENCLAW_DOCKER_ALL_LANES` | unset | 逗号分隔的精确测试线列表;跳过清理冒烟测试,以便智能体复现一条失败测试线。 | -超过有效上限的较重通道仍可从空池启动,然后会单独运行,直到释放容量。本地聚合流程会预检 Docker,移除陈旧的 OpenClaw E2E 容器,输出活动通道 Status,持久化通道计时以便最长优先排序,并默认在第一次失败后停止调度新的池化通道。 +比其有效上限更重的测试线仍可从空池启动,然后会独占运行,直到释放容量。本地聚合会预检 Docker,移除过期的 OpenClaw E2E 容器,输出活动测试线状态,持久化测试线耗时以便按最长优先排序,并且默认在第一次失败后停止调度新的池化测试线。 ### 可复用实时/E2E 工作流 -可复用的实时/E2E 工作流会询问 `scripts/test-docker-all.mjs --plan-json` 需要哪些软件包、镜像类型、实时镜像、通道和凭据覆盖。随后 `scripts/docker-e2e.mjs` 会将该计划转换为 GitHub 输出和摘要。它会通过 `scripts/package-openclaw-for-docker.mjs` 打包 OpenClaw、下载当前运行的软件包工件,或从 `package_artifact_run_id` 下载软件包工件;验证 tarball 清单;在计划需要已安装软件包的通道时,通过 Blacksmith 的 Docker 层缓存构建并推送带有软件包摘要标签的裸/功能 GHCR Docker E2E 镜像;并复用提供的 `docker_e2e_bare_image`/`docker_e2e_functional_image` 输入或现有的软件包摘要镜像,而不是重新构建。Docker 镜像拉取会以每次尝试 180 秒的有界超时重试,因此卡住的 registry/cache 流会快速重试,而不会消耗 CI 关键路径的大部分时间。 +可复用实时/E2E 工作流会询问 `scripts/test-docker-all.mjs --plan-json` 需要哪种包、镜像种类、实时镜像、测试线和凭据覆盖。随后 `scripts/docker-e2e.mjs` 会将该计划转换为 GitHub 输出和摘要。它会通过 `scripts/package-openclaw-for-docker.mjs` 打包 OpenClaw,下载当前运行的包工件,或从 `package_artifact_run_id` 下载包工件;验证 tarball 清单;在计划需要已安装包的测试线时,通过 Blacksmith 的 Docker layer cache 构建并推送带包摘要标签的裸/功能 GHCR Docker E2E 镜像;并复用提供的 `docker_e2e_bare_image`/`docker_e2e_functional_image` 输入或现有包摘要镜像,而不是重新构建。Docker 镜像拉取会使用有界的每次尝试 180 秒超时重试,因此卡住的 registry/cache 流会快速重试,而不会消耗 CI 关键路径的大部分时间。 ### 发布路径分块 -发布 Docker 覆盖会以更小的分块作业运行,并设置 `OPENCLAW_SKIP_DOCKER_BUILD=1`,因此每个分块只拉取自己需要的镜像类型,并通过同一个加权调度器执行多个通道: +发布 Docker 覆盖会使用带有 `OPENCLAW_SKIP_DOCKER_BUILD=1` 的较小分块作业运行,因此每个分块只拉取它需要的镜像种类,并通过同一个加权调度器执行多条测试线: - `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 分块为 `core`、`package-update-openai`、`package-update-anthropic`、`package-update-core`、`plugins-runtime-plugins`、`plugins-runtime-services`,以及从 `plugins-runtime-install-a` 到 `plugins-runtime-install-h`。`plugins-runtime-core`、`plugins-runtime` 和 `plugins-integrations` 仍然是聚合插件/运行时别名。`install-e2e` 通道别名仍然是两个 provider 安装器通道的聚合手动重新运行别名。 +当前发布 Docker 分块为 `core`、`package-update-openai`、`package-update-anthropic`、`package-update-core`、`plugins-runtime-plugins`、`plugins-runtime-services`,以及从 `plugins-runtime-install-a` 到 `plugins-runtime-install-h`。`plugins-runtime-core`、`plugins-runtime` 和 `plugins-integrations` 仍保留为聚合插件/运行时别名。`install-e2e` 测试线别名仍是两个提供商安装器测试线的聚合手动重新运行别名。 -当完整 release-path 覆盖请求 OpenWebUI 时,OpenWebUI 会并入 `plugins-runtime-services`,并且只在仅 OpenWebUI 的分发中保留独立的 `openwebui` 分块。内置渠道更新通道会针对临时 npm 网络失败重试一次。 +当完整 release-path 覆盖请求 OpenWebUI 时,它会被并入 `plugins-runtime-services`,并且仅为 OpenWebUI 专用分派保留独立的 `openwebui` 分块。内置渠道更新测试线会针对短暂 npm 网络故障重试一次。 -每个分块都会上传 `.artifacts/docker-tests/`,其中包含通道日志、计时、`summary.json`、`failures.json`、阶段计时、调度器计划 JSON、慢通道表和每通道重新运行命令。工作流的 `docker_lanes` 输入会针对已准备好的镜像运行选定通道,而不是运行分块作业,这使失败通道调试被限制在一个有针对性的 Docker 作业内,并会为该运行准备、下载或复用软件包工件;如果选中的通道是实时 Docker 通道,定向作业会为这次重新运行在本地构建实时测试镜像。生成的每通道 GitHub 重新运行命令会在这些值存在时包含 `package_artifact_run_id`、`package_artifact_name` 和已准备好的镜像输入,因此失败通道可以复用失败运行中的精确软件包和镜像。 +每个分块都会上传 `.artifacts/docker-tests/`,其中包含测试线日志、耗时、`summary.json`、`failures.json`、阶段耗时、调度器计划 JSON、慢测试线表,以及每条测试线的重新运行命令。工作流 `docker_lanes` 输入会针对已准备的镜像运行选定测试线,而不是运行分块作业,这样就能把失败测试线调试限制在一个目标 Docker 作业内,并为该运行准备、下载或复用包工件;如果选中的测试线是实时 Docker 测试线,目标作业会为该次重新运行在本地构建实时测试镜像。生成的每条测试线 GitHub 重新运行命令会在这些值存在时包含 `package_artifact_run_id`、`package_artifact_name` 和已准备的镜像输入,因此失败测试线可以复用失败运行中的精确包和镜像。 ```bash pnpm test:docker:rerun # download Docker artifacts and print combined/per-lane targeted rerun commands pnpm test:docker:timings # slow-lane and phase critical-path summaries ``` -定时实时/E2E 工作流每天运行完整 release-path Docker 套件。 +计划的实时/E2E 工作流每天运行完整 release-path Docker 套件。 ## 插件预发布 -`Plugin Prerelease` 是成本更高的产品/软件包覆盖,因此它是一个由 `Full Release Validation` 或显式操作员分发的独立工作流。普通拉取请求、`main` 推送和独立的手动 CI 分发都会关闭该套件。它会在八个插件 worker 之间平衡内置插件测试;这些插件分片作业一次最多运行两个插件配置组,每组使用一个 Vitest worker 和更大的 Node 堆,这样导入较重的插件批次不会创建额外的 CI 作业。仅发布使用的 Docker 预发布路径会将定向 Docker 通道按小组批处理,避免为一到三分钟的作业预留数十个 runner。 +`Plugin Prerelease` 是成本更高的产品/包覆盖,因此它是一个由 `Full Release Validation` 或显式操作员分派的独立工作流。普通拉取请求、`main` 推送和独立手动 CI 分派都会关闭该套件。它会在八个扩展工作器之间平衡内置插件测试;这些扩展分片作业一次最多运行两个插件配置组,每个组使用一个 Vitest 工作器和更大的 Node 堆,因此导入密集的插件批次不会创建额外 CI 作业。仅发布的 Docker 预发布路径会将目标 Docker 测试线按小组批处理,以避免为一到三分钟的作业占用大量运行器。 ## QA Lab -QA Lab 在主智能范围工作流之外有专用 CI 通道。 +QA Lab 在主智能作用域工作流之外有专用 CI 测试线。智能体一致性嵌套在广泛的 QA 和发布 harness 下,而不是独立的 PR 工作流。当一致性应随广泛验证运行一起执行时,使用带有 `rerun_group=qa-parity` 的 `Full Release Validation`。 -- `Parity gate` 工作流会在匹配的 PR 变更和手动分发时运行;它会构建私有 QA 运行时,并比较 mock GPT-5.5 和 Opus 4.6 智能体包。 -- `QA-Lab - All Lanes` 工作流每夜在 `main` 上运行,也可手动分发;它会将 mock parity gate、实时 Matrix 通道,以及实时 Telegram 和 Discord 通道作为并行作业扇出。实时作业使用 `qa-live-shared` 环境,Telegram/Discord 使用 Convex 租约。 +- `QA-Lab - All Lanes` 工作流每晚在 `main` 上运行,并支持手动分派;它会将模拟一致性测试线、实时 Matrix 测试线,以及实时 Telegram 和 Discord 测试线展开为并行作业。实时作业使用 `qa-live-shared` 环境,Telegram/Discord 使用 Convex 租约。 -发布检查会使用确定性 mock provider 和符合 mock 要求的模型(`mock-openai/gpt-5.5` 和 `mock-openai/gpt-5.5-alt`)运行 Matrix 和 Telegram 实时传输通道,因此渠道契约会与实时模型延迟和普通 provider 插件启动隔离。实时传输 Gateway 网关会禁用记忆搜索,因为 QA parity 会单独覆盖记忆行为;provider 连接性由单独的实时模型、原生 provider 和 Docker provider 套件覆盖。 +发布检查使用确定性模拟提供商和模拟限定模型(`mock-openai/gpt-5.5` 与 `mock-openai/gpt-5.5-alt`)运行 Matrix 和 Telegram 实时传输测试线,因此渠道契约会与实时模型延迟和常规提供商插件启动隔离。实时传输 Gateway 网关会禁用记忆搜索,因为 QA 一致性会单独覆盖记忆行为;提供商连通性由单独的实时模型、原生提供商和 Docker 提供商套件覆盖。 -Matrix 对定时和发布门禁使用 `--profile fast`,并且只在检出的 CLI 支持时添加 `--fail-fast`。CLI 默认值和手动工作流输入仍为 `all`;手动 `matrix_profile=all` 分发始终会将完整 Matrix 覆盖分片为 `transport`、`media`、`e2ee-smoke`、`e2ee-deep` 和 `e2ee-cli` 作业。 +Matrix 对计划和发布门禁使用 `--profile fast`,并且仅在检出的 CLI 支持时添加 `--fail-fast`。CLI 默认值和手动工作流输入仍为 `all`;手动 `matrix_profile=all` 分派始终会将完整 Matrix 覆盖分片为 `transport`、`media`、`e2ee-smoke`、`e2ee-deep` 和 `e2ee-cli` 作业。 -`OpenClaw Release Checks` 也会在发布批准前运行发布关键的 QA Lab 通道;其 QA parity gate 会将候选包和基线包作为并行通道作业运行,然后将两个工件下载到一个小型报告作业中,用于最终 parity 比较。 +`OpenClaw Release Checks` 也会在发布批准前运行发布关键的 QA Lab 测试线;它的 QA 一致性门禁会将候选包和基线包作为并行测试线作业运行,然后将两个工件下载到一个小型报告作业中,用于最终一致性比较。 -不要把 PR 落地路径置于 `Parity gate` 之后,除非变更确实触及 QA 运行时、模型包一致性,或一致性工作流负责的表面。对于常规渠道、配置、文档或单元测试修复,应将其视为可选信号,并改为遵循限定范围内的 CI/检查证据。 +对于普通 PR,请遵循作用域内 CI/检查证据,而不是将一致性视为必需状态。 ## CodeQL -`CodeQL` 工作流有意作为窄范围的一轮安全扫描器,而不是完整仓库扫描。每日、手动和非草稿拉取请求保护运行会扫描 Actions 工作流代码,以及最高风险的 JavaScript/TypeScript 表面,并使用高置信度安全查询,过滤到高/严重 `security-severity`。 +`CodeQL` 工作流有意作为范围较窄的第一轮安全扫描器,而不是完整的仓库扫描。每日、手动和非草稿拉取请求守护运行会扫描 Actions 工作流代码,以及最高风险的 JavaScript/TypeScript 表面,并使用高置信度安全查询筛选出 high/critical `security-severity`。 -拉取请求保护保持轻量:它只会在 `.github/actions`、`.github/codeql`、`.github/workflows`、`packages` 或 `src` 下的变更中启动,并运行与定时工作流相同的高置信度安全矩阵。Android 和 macOS CodeQL 不包含在 PR 默认项中。 +拉取请求守护保持轻量:它只会针对 `.github/actions`、`.github/codeql`、`.github/workflows`、`packages` 或 `src` 下的变更启动,并运行与定时工作流相同的高置信度安全矩阵。Android 和 macOS CodeQL 不在 PR 默认范围内。 ### 安全类别 | 类别 | 表面 | | ------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | -| `/codeql-security-high/core-auth-secrets` | 凭证、密钥、沙箱、cron 和 Gateway 网关基线 | -| `/codeql-security-high/channel-runtime-boundary` | 核心渠道实现契约,以及渠道插件运行时、Gateway 网关、插件 SDK、密钥、审计触点 | -| `/codeql-security-high/network-ssrf-boundary` | 核心 SSRF、IP 解析、网络防护、Web 获取和插件 SDK SSRF 策略表面 | -| `/codeql-security-high/mcp-process-tool-boundary` | MCP 服务器、进程执行辅助工具、出站交付,以及智能体工具执行门禁 | -| `/codeql-security-high/plugin-trust-boundary` | 插件安装、加载器、清单、注册表、包管理器安装、源码加载,以及插件 SDK 包契约信任表面 | +| `/codeql-security-high/core-auth-secrets` | 凭证、密钥、沙箱、cron 和 Gateway 网关基线 | +| `/codeql-security-high/channel-runtime-boundary` | 核心渠道实现契约,以及渠道插件运行时、Gateway 网关、插件 SDK、密钥、审计接触点 | +| `/codeql-security-high/network-ssrf-boundary` | 核心 SSRF、IP 解析、网络守护、web-fetch 和插件 SDK SSRF 策略表面 | +| `/codeql-security-high/mcp-process-tool-boundary` | MCP 服务器、进程执行辅助工具、出站交付,以及智能体工具执行闸门 | +| `/codeql-security-high/plugin-trust-boundary` | 插件安装、加载器、清单、注册表、包管理器安装、源加载,以及插件 SDK 包契约信任表面 | ### 平台特定安全分片 -- `CodeQL Android Critical Security` — 定时 Android 安全分片。在工作流健全性接受的最小 Blacksmith Linux runner 上为 CodeQL 手动构建 Android 应用。上传到 `/codeql-critical-security/android` 下。 -- `CodeQL macOS Critical Security` — 每周/手动 macOS 安全分片。在 Blacksmith macOS 上为 CodeQL 手动构建 macOS 应用,从上传的 SARIF 中过滤掉依赖构建结果,并上传到 `/codeql-critical-security/macos` 下。它被保留在每日默认项之外,因为即使结果干净,macOS 构建也会主导运行时间。 +- `CodeQL Android Critical Security` — 定时 Android 安全分片。在工作流完整性检查接受的最小 Blacksmith Linux 运行器上为 CodeQL 手动构建 Android 应用。上传到 `/codeql-critical-security/android` 下。 +- `CodeQL macOS Critical Security` — 每周/手动 macOS 安全分片。在 Blacksmith macOS 上为 CodeQL 手动构建 macOS 应用,从上传的 SARIF 中过滤掉依赖构建结果,并上传到 `/codeql-critical-security/macos` 下。由于 macOS 构建即使干净也会主导运行时间,因此保持在每日默认范围之外。 ### 关键质量类别 -`CodeQL Critical Quality` 是对应的非安全分片。它只在较小的 Blacksmith Linux runner 上,对窄范围高价值表面运行错误严重级别、非安全的 JavaScript/TypeScript 质量查询。它的拉取请求保护有意小于定时配置文件:非草稿 PR 只会为智能体命令/模型/工具执行和回复分发代码、配置架构/迁移/IO 代码、凭证/密钥/沙箱/安全代码、核心渠道和内置渠道插件运行时、Gateway 网关协议/服务器方法、记忆运行时/SDK 胶水代码、MCP/进程/出站交付、提供商运行时/模型目录、会话诊断/交付队列、插件加载器、插件 SDK/包契约,或插件 SDK 回复运行时变更,运行对应的 `agent-runtime-boundary`、`config-boundary`、`core-auth-secrets`、`channel-runtime-boundary`、`gateway-runtime-boundary`、`memory-runtime-boundary`、`mcp-process-runtime-boundary`、`provider-runtime-boundary`、`session-diagnostics-boundary`、`plugin-boundary`、`plugin-sdk-package-contract` 和 `plugin-sdk-reply-runtime` 分片。CodeQL 配置和质量工作流变更会运行全部十二个 PR 质量分片。 +`CodeQL Critical Quality` 是对应的非安全分片。它只在较小的 Blacksmith Linux 运行器上,针对范围较窄的高价值表面运行 error-severity、非安全的 JavaScript/TypeScript 质量查询。它的拉取请求守护有意小于定时配置:非草稿 PR 只会针对智能体命令/模型/工具执行和回复分发代码、配置 schema/迁移/IO 代码、凭证/密钥/沙箱/安全代码、核心渠道和内置渠道插件运行时、Gateway 网关协议/server-method、记忆运行时/SDK 胶水、MCP/进程/出站交付、提供商运行时/模型目录、会话诊断/交付队列、插件加载器、插件 SDK/包契约,或插件 SDK 回复运行时变更,运行匹配的 `agent-runtime-boundary`、`config-boundary`、`core-auth-secrets`、`channel-runtime-boundary`、`gateway-runtime-boundary`、`memory-runtime-boundary`、`mcp-process-runtime-boundary`、`provider-runtime-boundary`、`session-diagnostics-boundary`、`plugin-boundary`、`plugin-sdk-package-contract` 和 `plugin-sdk-reply-runtime` 分片。CodeQL 配置和质量工作流变更会运行全部十二个 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 ``` -窄范围配置文件是用于单独运行一个质量分片的教学/迭代钩子。 +这些窄配置是用于单独运行一个质量分片的教学/迭代钩子。 | 类别 | 表面 | | ------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `/codeql-critical-quality/core-auth-secrets` | 凭证、密钥、沙箱、cron 和 Gateway 网关安全边界代码 | -| `/codeql-critical-quality/config-boundary` | 配置架构、迁移、规范化和 IO 契约 | -| `/codeql-critical-quality/gateway-runtime-boundary` | Gateway 网关协议架构和服务器方法契约 | -| `/codeql-critical-quality/channel-runtime-boundary` | 核心渠道和内置渠道插件实现契约 | -| `/codeql-critical-quality/agent-runtime-boundary` | 命令执行、模型/提供商分发、自动回复分发和队列,以及 ACP 控制平面运行时契约 | -| `/codeql-critical-quality/mcp-process-runtime-boundary` | MCP 服务器和工具桥接、进程监督辅助工具,以及出站交付契约 | -| `/codeql-critical-quality/memory-runtime-boundary` | 记忆宿主 SDK、记忆运行时门面、记忆插件 SDK 别名、记忆运行时激活胶水代码,以及记忆 Doctor 命令 | -| `/codeql-critical-quality/session-diagnostics-boundary` | 回复队列内部、会话交付队列、出站会话绑定/交付辅助工具、诊断事件/日志包表面,以及会话 Doctor CLI 契约 | -| `/codeql-critical-quality/plugin-sdk-reply-runtime` | 插件 SDK 入站回复分发、回复载荷/分块/运行时辅助工具、渠道回复选项、交付队列,以及会话/线程绑定辅助工具 | -| `/codeql-critical-quality/provider-runtime-boundary` | 模型目录规范化、提供商凭证和设备发现、提供商运行时注册、提供商默认值/目录,以及 Web/搜索/获取/嵌入注册表 | -| `/codeql-critical-quality/ui-control-plane` | 控制 UI 引导、本地持久化、Gateway 网关控制流,以及任务控制平面运行时契约 | -| `/codeql-critical-quality/web-media-runtime-boundary` | 核心 Web 获取/搜索、媒体 IO、媒体理解、图像生成,以及媒体生成运行时契约 | -| `/codeql-critical-quality/plugin-boundary` | 加载器、注册表、公共表面,以及插件 SDK 入口点契约 | -| `/codeql-critical-quality/plugin-sdk-package-contract` | 已发布包侧插件 SDK 源码和插件包契约辅助工具 | +| `/codeql-critical-quality/core-auth-secrets` | 凭证、密钥、沙箱、cron 和 Gateway 网关安全边界代码 | +| `/codeql-critical-quality/config-boundary` | 配置 schema、迁移、规范化和 IO 契约 | +| `/codeql-critical-quality/gateway-runtime-boundary` | Gateway 网关协议 schema 和服务器方法契约 | +| `/codeql-critical-quality/channel-runtime-boundary` | 核心渠道和内置渠道插件实现契约 | +| `/codeql-critical-quality/agent-runtime-boundary` | 命令执行、模型/提供商分发、自动回复分发和队列,以及 ACP 控制平面运行时契约 | +| `/codeql-critical-quality/mcp-process-runtime-boundary` | MCP 服务器和工具桥接、进程监督辅助工具,以及出站交付契约 | +| `/codeql-critical-quality/memory-runtime-boundary` | 记忆主机 SDK、记忆运行时 facade、记忆插件 SDK 别名、记忆运行时激活胶水,以及记忆 Doctor 命令 | +| `/codeql-critical-quality/session-diagnostics-boundary` | 回复队列内部机制、会话交付队列、出站会话绑定/交付辅助工具、诊断事件/日志包表面,以及会话 Doctor CLI 契约 | +| `/codeql-critical-quality/plugin-sdk-reply-runtime` | 插件 SDK 入站回复分发、回复 payload/分块/运行时辅助工具、渠道回复选项、交付队列,以及会话/线程绑定辅助工具 | +| `/codeql-critical-quality/provider-runtime-boundary` | 模型目录规范化、提供商凭证和设备发现、提供商运行时注册、提供商默认值/目录,以及 web/search/fetch/embedding 注册表 | +| `/codeql-critical-quality/ui-control-plane` | 控制 UI 启动、本地持久化、Gateway 网关控制流,以及任务控制平面运行时契约 | +| `/codeql-critical-quality/web-media-runtime-boundary` | 核心 web fetch/search、媒体 IO、媒体理解、图像生成和媒体生成运行时契约 | +| `/codeql-critical-quality/plugin-boundary` | 加载器、注册表、公共表面和插件 SDK 入口点契约 | +| `/codeql-critical-quality/plugin-sdk-package-contract` | 已发布包侧插件 SDK 源代码和插件包契约辅助工具 | -质量与安全保持分离,这样质量发现就可以被定时运行、度量、禁用或扩展,而不会遮蔽安全信号。Swift、Python 和内置插件的 CodeQL 扩展,只有在窄范围配置文件具备稳定运行时间和信号之后,才应作为限定范围或分片的后续工作重新加入。 +质量与安全保持分离,因此质量发现可以被定时运行、度量、禁用或扩展,而不会遮蔽安全信号。Swift、Python 和内置插件的 CodeQL 扩展只应在窄配置具备稳定运行时间和信号之后,作为有范围或分片的后续工作重新加入。 ## 维护工作流 ### Docs Agent -`Docs Agent` 工作流是一个事件驱动的 Codex 维护通道,用于让现有文档与最近落地的变更保持一致。它没有纯定时计划:`main` 上一次成功的非机器人 push CI 运行可以触发它,手动分发也可以直接运行它。当 `main` 已经前进,或过去一小时内已经创建另一个未跳过的 Docs Agent 运行时,workflow-run 调用会跳过。运行时,它会审查从上一个未跳过的 Docs Agent 来源 SHA 到当前 `main` 的提交范围,因此一次每小时运行可以覆盖自上次文档巡检以来累积的所有 main 变更。 +`Docs Agent` 工作流是一个事件驱动的 Codex 维护通道,用于让现有文档与最近落地的变更保持一致。它没有纯定时计划:`main` 上成功的非 bot push CI 运行可以触发它,手动调度也可以直接运行它。当 `main` 已经向前移动,或过去一小时内已经创建了另一个未跳过的 Docs Agent 运行时,workflow-run 调用会跳过。运行时,它会审查从上一个未跳过的 Docs Agent 源 SHA 到当前 `main` 的提交范围,因此每小时一次的运行可以覆盖自上次文档检查以来累积的所有 main 变更。 ### Test Performance Agent -`Test Performance Agent` 工作流是一个事件驱动的 Codex 维护通道,用于慢测试。它没有纯定时计划:`main` 上一次成功的非机器人 push CI 运行可以触发它,但如果当天 UTC 已经有另一个 workflow-run 调用运行过或正在运行,它会跳过。手动分发会绕过这个每日活动门禁。该通道会构建完整套件分组 Vitest 性能报告,让 Codex 只进行小型且保持覆盖率的测试性能修复,而不是大范围重构,然后重新运行完整套件报告,并拒绝会降低通过基线测试数量的变更。如果基线中存在失败测试,Codex 只能修复明显失败项,且 agent 后的完整套件报告必须通过,之后才能提交任何内容。当 `main` 在机器人 push 落地前前进时,该通道会对已验证补丁执行 rebase,重新运行 `pnpm check:changed`,并重试 push;存在冲突的过期补丁会被跳过。它使用 GitHub 托管的 Ubuntu,因此 Codex action 可以保持与 docs agent 相同的 drop-sudo 安全姿态。 +`Test Performance Agent` 工作流是一个事件驱动的 Codex 维护通道,用于处理慢测试。它没有纯定时计划:`main` 上成功的非 bot push CI 运行可以触发它,但如果当天 UTC 已有另一个 workflow-run 调用运行过或正在运行,它会跳过。手动调度会绕过这个每日活动闸门。该通道会生成完整套件分组 Vitest 性能报告,让 Codex 只做保持覆盖率的小型测试性能修复,而不是广泛重构,然后重新运行完整套件报告,并拒绝会降低通过基线测试数量的变更。如果基线存在失败测试,Codex 只能修复明显失败,并且 agent 后的完整套件报告必须通过后才能提交任何内容。当 bot push 落地前 `main` 向前推进时,该通道会 rebase 已验证的补丁、重新运行 `pnpm check:changed`,并重试 push;有冲突的陈旧补丁会被跳过。它使用 GitHub 托管的 Ubuntu,因此 Codex action 可以保持与 docs agent 相同的 drop-sudo 安全姿态。 ### 合并后的重复 PR -`Duplicate PRs After Merge` 工作流是一个手动维护者工作流,用于落地后的重复清理。它默认 dry-run,并且只有在 `apply=true` 时才会关闭明确列出的 PR。在修改 GitHub 前,它会验证已落地的 PR 已合并,并验证每个重复项要么有共享的引用 issue,要么有重叠的变更 hunk。 +`Duplicate PRs After Merge` 工作流是一个手动维护者工作流,用于落地后的重复项清理。它默认 dry-run,并且只有在 `apply=true` 时才会关闭显式列出的 PR。在修改 GitHub 之前,它会验证已落地 PR 已合并,并且每个重复项都有共享的引用 issue 或重叠的变更 hunk。 ```bash gh workflow run duplicate-after-merge.yml \ @@ -455,29 +454,29 @@ gh workflow run duplicate-after-merge.yml \ -f apply=true ``` -## 本地检查门禁和变更路由 +## 本地检查闸门和变更路由 -本地变更通道逻辑位于 `scripts/changed-lanes.mjs`,并由 `scripts/check-changed.mjs` 执行。相比宽泛的 CI 平台范围,该本地检查门禁对架构边界更严格: +本地 changed-lane 逻辑位于 `scripts/changed-lanes.mjs`,并由 `scripts/check-changed.mjs` 执行。该本地检查闸门在架构边界上比宽泛的 CI 平台范围更严格: -- 核心生产变更会运行核心生产和核心测试类型检查,以及核心 lint/防护; -- 仅核心测试变更只会运行核心测试类型检查,以及核心 lint; -- 插件生产变更会运行插件生产和插件测试类型检查,以及插件 lint; -- 仅插件测试变更会运行插件测试类型检查,以及插件 lint; +- 核心生产变更会运行核心 prod 和核心 test 类型检查,以及核心 lint/guards; +- 仅核心测试的变更只会运行核心 test 类型检查,以及核心 lint; +- 插件生产变更会运行插件 prod 和插件 test 类型检查,以及插件 lint; +- 仅插件测试的变更会运行插件 test 类型检查,以及插件 lint; - 公共插件 SDK 或插件契约变更会扩展到插件类型检查,因为插件依赖这些核心契约(Vitest 插件扫描仍然是显式测试工作); -- 仅发布元数据的版本号提升会运行定向版本/配置/根依赖检查; -- 未知根目录/配置变更会故障保护到所有检查通道。 +- 仅发布元数据的版本 bump 会运行定向版本/配置/根依赖检查; +- 未知根目录/配置变更会安全失败到所有检查通道。 -本地变更测试路由位于 `scripts/test-projects.test-support.mjs`,并且有意比 `check:changed` 更轻量:直接修改测试会运行这些测试本身,源代码修改会优先使用显式映射,然后是同级测试和导入图依赖项。共享群组房间投递配置是显式映射之一:对群组可见回复配置、源回复投递模式或 message-tool 系统提示词的更改,会路由到核心回复测试以及 Discord 和 Slack 投递回归测试,这样共享默认值变更会在第一次 PR 推送前失败。仅当变更的范围大到覆盖整个 harness,以至于这个轻量映射集合不能作为可信代理时,才使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`。 +本地 changed-test 路由位于 `scripts/test-projects.test-support.mjs`,并且有意比 `check:changed` 更便宜:直接测试编辑会运行自身,源代码编辑优先使用显式映射,然后是同级测试和 import-graph 依赖项。共享群组房间交付配置是显式映射之一:对群组可见回复配置、源回复交付模式或 message-tool 系统提示的变更,会通过核心回复测试以及 Discord 和 Slack 交付回归测试进行路由,因此共享默认值变更会在第一次 PR push 前失败。只有当变更覆盖整个 harness,以至于廉价映射集合不能作为可信代理时,才使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`。 ## Testbox 验证 -从仓库根目录运行 Testbox,并且在进行广泛证明时优先使用一个新预热的 box。在把一个慢速 gate 花在被复用、已过期或刚刚报告异常大同步量的 box 上之前,先在该 box 内运行 `pnpm testbox:sanity`。 +从仓库根目录运行 Testbox,并优先使用新的已预热 box 做广泛验证。在复用过、已过期,或刚报告了异常大规模同步的 box 上投入慢速门禁前,先在该 box 内运行 `pnpm testbox:sanity`。 -当 `pnpm-lock.yaml` 等必需的根文件消失,或 `git status --short` 显示至少 200 个已跟踪删除项时,sanity check 会快速失败。这通常意味着远程同步状态不是 PR 的可信副本;应停止该 box 并预热一个新的,而不是调试产品测试失败。对于有意的大量删除 PR,请为该次 sanity 运行设置 `OPENCLAW_TESTBOX_ALLOW_MASS_DELETIONS=1`。 +当 `pnpm-lock.yaml` 等必需根目录文件消失,或 `git status --short` 显示至少 200 个已跟踪文件被删除时,完整性检查会快速失败。这通常意味着远程同步状态不是 PR 的可信副本;停止该 box 并预热一个新的,而不是调试产品测试失败。对于有意进行大规模删除的 PR,为该完整性检查运行设置 `OPENCLAW_TESTBOX_ALLOW_MASS_DELETIONS=1`。 -如果本地 Blacksmith CLI 调用停留在同步阶段超过五分钟且没有同步后输出,`pnpm testbox:run` 也会终止它。设置 `OPENCLAW_TESTBOX_SYNC_TIMEOUT_MS=0` 可禁用该保护,或为异常大的本地差异使用更大的毫秒值。 +如果本地 Blacksmith CLI 调用停留在同步阶段超过五分钟且没有同步后的输出,`pnpm testbox:run` 也会终止该调用。设置 `OPENCLAW_TESTBOX_SYNC_TIMEOUT_MS=0` 可禁用该保护,或为异常大的本地 diff 使用更大的毫秒值。 -当 Blacksmith 不可用,或更适合使用自有云容量时,Crabbox 是仓库自有的第二条远程 box Linux 验证路径。预热一个 box,通过项目工作流为其 hydration,然后通过 Crabbox CLI 运行命令: +当 Blacksmith 不可用,或更适合使用自有云容量时,Crabbox 是仓库自有的第二条 Linux 远程 box 验证路径。预热一个 box,通过项目工作流注水,然后通过 Crabbox CLI 运行命令: ```bash pnpm crabbox:warmup -- --idle-timeout 90m @@ -486,9 +485,9 @@ pnpm crabbox:run -- --id --shell "OPENCLAW_TESTBOX=1 pnpm check:changed pnpm crabbox:stop -- ``` -`.crabbox.yaml` 负责 provider、同步和 GitHub Actions hydration 默认值。它会排除本地 `.git`,这样 hydration 后的 Actions checkout 会保留自己的远程 Git 元数据,而不是同步维护者本地的 remotes 和 object stores;它还会排除不应被传输的本地运行时/构建产物。`.github/workflows/crabbox-hydrate.yml` 负责 checkout、Node/pnpm 设置、`origin/main` 获取,以及后续 `crabbox run --id ` 命令会 source 的非 secret 环境交接。 +`.crabbox.yaml` 负责提供商、同步和 GitHub Actions 注水默认值。它会排除本地 `.git`,这样注水后的 Actions checkout 会保留自己的远程 Git 元数据,而不是同步维护者本地的 remote 和 object store;它还会排除不应被传输的本地运行时/构建产物。`.github/workflows/crabbox-hydrate.yml` 负责 checkout、Node/pnpm 设置、`origin/main` 获取,以及非 secret 环境交接,后续的 `crabbox run --id ` 命令会加载这些环境。 -## 相关内容 +## 相关 - [安装概览](/zh-CN/install) - [开发渠道](/zh-CN/install/development-channels) diff --git a/docs/zh-CN/concepts/qa-e2e-automation.md b/docs/zh-CN/concepts/qa-e2e-automation.md index 40572a70a..54ac37898 100644 --- a/docs/zh-CN/concepts/qa-e2e-automation.md +++ b/docs/zh-CN/concepts/qa-e2e-automation.md @@ -1,58 +1,58 @@ --- read_when: - - 了解 QA 堆栈如何协同工作 + - 了解 QA 栈如何协同工作 - 扩展 qa-lab、qa-channel 或传输适配器 - - 添加基于仓库的 QA 场景 - - 围绕 Gateway 网关仪表板构建更高真实度的 QA 自动化 -summary: QA 栈概览:qa-lab、qa-channel、由仓库支持的场景、实时传输通道、传输适配器和报告。 + - 添加由仓库支持的 QA 场景 + - 围绕 Gateway 网关仪表盘构建更接近真实场景的 QA 自动化 +summary: QA 栈概览:qa-lab、qa-channel、仓库驱动的场景、实时传输通道、传输适配器和报告。 title: QA overview x-i18n: - generated_at: "2026-04-28T11:50:04Z" + generated_at: "2026-05-02T20:01:39Z" model: gpt-5.5 provider: openai - source_hash: b62a5081fc2b67333f2ec6f3469e97043f048d5912858b9d8cc565c2e5fc8de2 + source_hash: 1f1cba04d6624bb1e0fc54105bd836f16ada0ba1cc1de9ab7065b90220e23bdf source_path: concepts/qa-e2e-automation.md workflow: 16 --- -这个私有 QA 栈旨在以比单个单元测试更真实、更接近渠道形态的方式测试 OpenClaw。 +私有 QA 栈旨在以比单个单元测试更真实、更接近渠道形态的方式演练 OpenClaw。 -当前组件: +当前组成部分: -- `extensions/qa-channel`:模拟消息渠道,包含私信、渠道、线程、回应、编辑和删除表面。 -- `extensions/qa-lab`:调试器 UI 和 QA 总线,用于观察文字记录、注入入站消息并导出 Markdown 报告。 -- `extensions/qa-matrix`、未来的运行器插件:实时传输适配器,在子 QA Gateway 网关内驱动真实渠道。 -- `qa/`:由仓库支持的启动任务和基线 QA 场景种子资产。 +- `extensions/qa-channel`:合成消息渠道,包含私信、渠道、话题串、回应、编辑和删除界面。 +- `extensions/qa-lab`:调试器 UI 和 QA 总线,用于观察转录、注入入站消息,并导出 Markdown 报告。 +- `extensions/qa-matrix`、未来的运行器插件:实时传输适配器,用于在子 QA Gateway 网关内驱动真实渠道。 +- `qa/`:由仓库支持的种子资产,用于启动任务和基线 QA 场景。 -## 命令表面 +## 命令界面 -每个 QA 流程都在 `pnpm openclaw qa ` 下运行。许多命令有 `pnpm qa:*` 脚本别名;两种形式都受支持。 +每个 QA 流程都在 `pnpm openclaw qa ` 下运行。许多流程有 `pnpm qa:*` 脚本别名;两种形式都受支持。 -| 命令 | 用途 | -| --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `qa run` | 内置 QA 自检;写入 Markdown 报告。 | -| `qa suite` | 针对 QA Gateway 网关线路运行由仓库支持的场景。别名:`pnpm openclaw qa suite --runner multipass`,用于一次性 Linux VM。 | -| `qa coverage` | 打印 markdown 场景覆盖清单(`--json` 用于机器输出)。 | -| `qa parity-report` | 比较两个 `qa-suite-summary.json` 文件,并写入智能体式一致性门禁报告。 | -| `qa character-eval` | 跨多个实时模型运行角色 QA 场景,并生成带评判的报告。参见[报告](#reporting)。 | -| `qa manual` | 针对所选提供商/模型线路运行一次性 prompt。 | -| `qa ui` | 启动 QA 调试器 UI 和本地 QA 总线(别名:`pnpm qa:lab:ui`)。 | -| `qa docker-build-image` | 构建预烘焙的 QA Docker 镜像。 | -| `qa docker-scaffold` | 为 QA 仪表板 + Gateway 网关线路写入 docker-compose 脚手架。 | -| `qa up` | 构建 QA 站点,启动由 Docker 支持的栈,并打印 URL(别名:`pnpm qa:lab:up`;`:fast` 变体会添加 `--use-prebuilt-image --bind-ui-dist --skip-ui-build`)。 | -| `qa aimock` | 仅启动 AIMock provider 服务器。 | -| `qa mock-openai` | 仅启动具备场景感知能力的 `mock-openai` provider 服务器。 | -| `qa credentials doctor` / `add` / `list` / `remove` | 管理共享 Convex 凭据池。 | -| `qa matrix` | 针对一次性 Tuwunel homeserver 的实时传输线路。参见 [Matrix QA](/zh-CN/concepts/qa-matrix)。 | -| `qa telegram` | 针对真实私有 Telegram 群组的实时传输线路。 | -| `qa discord` | 针对真实私有 Discord guild 渠道的实时传输线路。 | +| 命令 | 用途 | +| --------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `qa run` | 内置 QA 自检;写入 Markdown 报告。 | +| `qa suite` | 针对 QA Gateway 网关通道运行由仓库支持的场景。别名:`pnpm openclaw qa suite --runner multipass` 用于一次性 Linux VM。 | +| `qa coverage` | 打印 Markdown 场景覆盖清单(`--json` 用于机器输出)。 | +| `qa parity-report` | 比较两个 `qa-suite-summary.json` 文件,并写入智能体一致性报告。 | +| `qa character-eval` | 跨多个实时模型运行角色 QA 场景,并生成评审报告。参见 [报告](#reporting)。 | +| `qa manual` | 针对所选提供商/模型通道运行一次性提示词。 | +| `qa ui` | 启动 QA 调试器 UI 和本地 QA 总线(别名:`pnpm qa:lab:ui`)。 | +| `qa docker-build-image` | 构建预烘焙的 QA Docker 镜像。 | +| `qa docker-scaffold` | 为 QA 仪表板 + Gateway 网关通道写入 docker-compose 脚手架。 | +| `qa up` | 构建 QA 站点,启动 Docker 支持的栈,打印 URL(别名:`pnpm qa:lab:up`;`:fast` 变体会添加 `--use-prebuilt-image --bind-ui-dist --skip-ui-build`)。 | +| `qa aimock` | 仅启动 AIMock provider 服务器。 | +| `qa mock-openai` | 仅启动可感知场景的 `mock-openai` 提供商服务器。 | +| `qa credentials doctor` / `add` / `list` / `remove` | 管理共享的 Convex 凭据池。 | +| `qa matrix` | 针对一次性 Tuwunel homeserver 的实时传输通道。参见 [Matrix QA](/zh-CN/concepts/qa-matrix)。 | +| `qa telegram` | 针对真实私有 Telegram 群组的实时传输通道。 | +| `qa discord` | 针对真实私有 Discord guild 渠道的实时传输通道。 | ## 操作员流程 -当前 QA 操作员流程是一个双栏 QA 站点: +当前 QA 操作员流程是一个双窗格 QA 站点: -- 左侧:带智能体的 Gateway 网关仪表板(Control UI)。 -- 右侧:QA Lab,显示类似 Slack 的文字记录和场景计划。 +- 左侧:包含智能体的 Gateway 网关仪表板(Control UI)。 +- 右侧:QA Lab,显示类似 Slack 的转录和场景计划。 运行方式: @@ -60,9 +60,9 @@ x-i18n: pnpm qa:lab:up ``` -这会构建 QA 站点,启动由 Docker 支持的 Gateway 网关线路,并公开 QA Lab 页面,操作员或自动化循环可以在其中给智能体分配 QA 任务、观察真实渠道行为,并记录哪些内容有效、失败或仍被阻塞。 +这会构建 QA 站点,启动 Docker 支持的 Gateway 网关通道,并公开 QA Lab 页面,操作员或自动化循环可在该页面给智能体分配 QA 任务、观察真实渠道行为,并记录哪些有效、失败或仍被阻塞。 -为了更快迭代 QA Lab UI,而不必每次都重建 Docker 镜像,可以用 bind-mounted QA Lab bundle 启动栈: +为了更快迭代 QA Lab UI,而不必每次都重新构建 Docker 镜像,请使用 bind-mounted QA Lab 包启动栈: ```bash pnpm openclaw qa docker-build-image @@ -71,88 +71,88 @@ pnpm qa:lab:up:fast pnpm qa:lab:watch ``` -`qa:lab:up:fast` 会让 Docker 服务使用预构建镜像,并将 `extensions/qa-lab/web/dist` bind-mount 到 `qa-lab` 容器中。`qa:lab:watch` 会在变更时重建该 bundle,当 QA Lab 资产哈希变化时浏览器会自动重新加载。 +`qa:lab:up:fast` 会让 Docker 服务使用预构建镜像,并将 `extensions/qa-lab/web/dist` bind-mount 到 `qa-lab` 容器中。`qa:lab:watch` 会在变更时重建该包,当 QA Lab 资产哈希变化时,浏览器会自动重新加载。 -对于本地 OpenTelemetry trace 冒烟测试,请运行: +若要运行本地 OpenTelemetry trace smoke,请执行: ```bash pnpm qa:otel:smoke ``` -该脚本会启动本地 OTLP/HTTP trace 接收器,启用 `diagnostics-otel` 插件运行 `otel-trace-smoke` QA 场景,然后解码导出的 protobuf spans 并断言发布关键形态:必须存在 `openclaw.run`、`openclaw.harness.run`、`openclaw.model.call`、`openclaw.context.assembled` 和 `openclaw.message.delivery`;成功回合中的模型调用不得导出 `StreamAbandoned`;原始诊断 ID 和 `openclaw.content.*` 属性必须留在 trace 之外。它会在 QA suite 产物旁写入 `otel-smoke-summary.json`。 +该脚本会启动本地 OTLP/HTTP trace 接收器,在启用 `diagnostics-otel` 插件的情况下运行 `otel-trace-smoke` QA 场景,然后解码导出的 protobuf spans,并断言发布关键形态:必须存在 `openclaw.run`、`openclaw.harness.run`、`openclaw.model.call`、`openclaw.context.assembled` 和 `openclaw.message.delivery`;成功轮次中的模型调用不得导出 `StreamAbandoned`;原始诊断 ID 和 `openclaw.content.*` 属性必须留在 trace 之外。它会在 QA suite 工件旁写入 `otel-smoke-summary.json`。 -可观测性 QA 仅适用于源码检出。npm tarball 会有意省略 QA Lab,因此 package Docker 发布线路不会运行 `qa` 命令。更改诊断插桩时,请从已构建的源码检出运行 `pnpm qa:otel:smoke`。 +可观测性 QA 仅保留在源码 checkout 中。npm tarball 会有意省略 QA Lab,因此包 Docker 发布通道不会运行 `qa` 命令。更改诊断插桩时,请从已构建的源码 checkout 运行 `pnpm qa:otel:smoke`。 -对于使用真实传输的 Matrix 冒烟测试线路,请运行: +若要运行传输真实的 Matrix smoke 通道,请执行: ```bash pnpm openclaw qa matrix --profile fast --fail-fast ``` -此线路的完整 CLI 参考、profile/场景目录、环境变量和产物布局位于 [Matrix QA](/zh-CN/concepts/qa-matrix)。简要来说:它会在 Docker 中配置一次性 Tuwunel homeserver,注册临时 driver/SUT/observer 用户,在限定到该传输的子 QA Gateway 网关中运行真实 Matrix 插件(无 `qa-channel`),然后在 `.artifacts/qa-e2e/matrix-/` 下写入 Markdown 报告、JSON 摘要、observed-events 产物和合并输出日志。 +此通道的完整 CLI 参考、配置文件/场景目录、环境变量和工件布局位于 [Matrix QA](/zh-CN/concepts/qa-matrix)。简要来说:它会在 Docker 中配置一次性 Tuwunel homeserver,注册临时 driver/SUT/observer 用户,在限定到该传输的子 QA Gateway 网关内运行真实 Matrix 插件(不使用 `qa-channel`),然后在 `.artifacts/qa-e2e/matrix-/` 下写入 Markdown 报告、JSON 摘要、observed-events 工件和合并输出日志。 -对于使用真实传输的 Telegram 和 Discord 冒烟测试线路: +对于传输真实的 Telegram 和 Discord smoke 通道: ```bash pnpm openclaw qa telegram pnpm openclaw qa discord ``` -两者都面向带两个 bot(driver + SUT)的预先存在真实渠道。所需环境变量、场景列表、输出产物和 Convex 凭据池记录在下方的 [Telegram 和 Discord QA 参考](#telegram-and-discord-qa-reference)中。 +两者都面向一个已有真实渠道,并使用两个机器人(driver + SUT)。所需环境变量、场景列表、输出工件和 Convex 凭据池记录在下面的 [Telegram 和 Discord QA 参考](#telegram-and-discord-qa-reference) 中。 -使用池化实时凭据前,请运行: +使用池化实时凭据之前,请运行: ```bash pnpm openclaw qa credentials doctor ``` -Doctor 会检查 Convex broker 环境、验证 endpoint 设置,并在维护者密钥存在时验证 admin/list 可达性。它只报告密钥的已设置/缺失状态。 +该 Doctor 会检查 Convex broker 环境,验证端点设置,并在维护者密钥存在时验证 admin/list 可达性。它只报告密钥的已设置/缺失状态。 ## 实时传输覆盖范围 -实时传输线路共享一个契约,而不是各自发明自己的场景列表形态。`qa-channel` 是广泛的模拟产品行为 suite,不属于实时传输覆盖矩阵。 +实时传输通道共享一个契约,而不是各自发明自己的场景列表形态。`qa-channel` 是广泛的合成产品行为 suite,不属于实时传输覆盖矩阵。 -| 线路 | 金丝雀 | 提及门控 | Bot 到 bot | 允许列表阻止 | 顶层回复 | 重启恢复 | 线程后续回复 | 线程隔离 | 回应观察 | 帮助命令 | 原生命令注册 | -| -------- | ------ | -------- | ---------- | ------------ | -------- | -------- | ------------ | -------- | -------- | -------- | ------------ | -| Matrix | x | x | x | x | x | x | x | x | x | | | -| Telegram | x | x | x | | | | | | | x | | -| Discord | x | x | x | | | | | | | | x | +| 通道 | 金丝雀 | 提及门控 | 机器人到机器人 | 允许列表阻断 | 顶层回复 | 重启恢复 | 话题串跟进 | 话题串隔离 | 回应观察 | 帮助命令 | 原生命令注册 | +| -------- | ------ | -------- | -------------- | ------------ | -------- | -------- | ---------- | ---------- | -------- | -------- | ------------ | +| Matrix | x | x | x | x | x | x | x | x | x | | | +| Telegram | x | x | x | | | | | | | x | | +| Discord | x | x | x | | | | | | | | x | -这会将 `qa-channel` 保持为广泛的产品行为 suite,同时让 Matrix、Telegram 和未来的实时传输共享一个明确的传输契约检查清单。 +这会让 `qa-channel` 继续作为广泛的产品行为 suite,同时让 Matrix、Telegram 以及未来的实时传输共享一个显式的传输契约检查清单。 -对于不把 Docker 带入 QA 路径的一次性 Linux VM 线路,请运行: +若要运行一个不把 Docker 带入 QA 路径的一次性 Linux VM 通道,请执行: ```bash pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline ``` -这会启动全新的 Multipass guest,安装依赖,在 guest 内构建 OpenClaw,运行 `qa suite`,然后将常规 QA 报告和摘要复制回主机上的 `.artifacts/qa-e2e/...`。 +这会启动一个全新的 Multipass guest,安装依赖,在 guest 内构建 OpenClaw,运行 `qa suite`,然后把常规 QA 报告和摘要复制回主机上的 `.artifacts/qa-e2e/...`。 它复用与主机上 `qa suite` 相同的场景选择行为。 -主机和 Multipass suite 运行默认会使用隔离的 Gateway 网关 worker 并行执行多个所选场景。`qa-channel` 默认并发数为 4,并受所选场景数限制。使用 `--concurrency ` 调整 worker 数量,或使用 `--concurrency 1` 串行执行。 -当任何场景失败时,该命令会以非零状态退出。当你想要产物但不想让退出码失败时,请使用 `--allow-failures`。 -实时运行会转发对 guest 来说可行的受支持 QA 认证输入:基于环境的 provider 密钥、QA 实时 provider 配置路径,以及存在时的 `CODEX_HOME`。请将 `--output-dir` 保持在仓库根目录下,这样 guest 才能通过挂载的工作区写回。 +主机和 Multipass suite 运行默认会使用隔离的 Gateway 网关 worker 并行执行多个所选场景。`qa-channel` 默认并发数为 4,并受所选场景数量限制。使用 `--concurrency ` 调整 worker 数量,或使用 `--concurrency 1` 进行串行执行。 +任何场景失败时,该命令会以非零状态退出。如果你想获取工件但不希望失败退出码,请使用 `--allow-failures`。 +实时运行会转发对 guest 可行的受支持 QA 认证输入:基于环境的提供商密钥、QA live 提供商配置路径,以及存在时的 `CODEX_HOME`。请将 `--output-dir` 保持在仓库根目录下,以便 guest 可通过挂载的工作区写回。 ## Telegram 和 Discord QA 参考 -Matrix 有一个[专用页面](/zh-CN/concepts/qa-matrix),因为它的场景数量和由 Docker 支持的 homeserver 配置更多。Telegram 和 Discord 更小,每个只有少量场景、没有 profile 系统,并且针对预先存在的真实渠道,因此它们的参考放在这里。 +Matrix 有一个[专用页面](/zh-CN/concepts/qa-matrix),因为它的场景数量更多,并且需要 Docker 支持的 homeserver 配置。Telegram 和 Discord 更小,每个只有少量场景,没有配置文件系统,并针对已有真实渠道,因此它们的参考放在这里。 ### 共享 CLI 标志 -两条线路都通过 `extensions/qa-lab/src/live-transports/shared/live-transport-cli.ts` 注册,并接受相同标志: +两个通道都通过 `extensions/qa-lab/src/live-transports/shared/live-transport-cli.ts` 注册,并接受相同标志: -| 标志 | 默认值 | 描述 | +| 标志 | 默认值 | 说明 | | ------------------------------------- | --------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | | `--scenario ` | — | 仅运行此场景。可重复指定。 | -| `--output-dir ` | `/.artifacts/qa-e2e/{telegram,discord}-` | 写入报告、摘要、观测消息和输出日志的位置。相对路径会基于 `--repo-root` 解析。 | +| `--output-dir ` | `/.artifacts/qa-e2e/{telegram,discord}-` | 写入报告、摘要、观测到的消息和输出日志的位置。相对路径会基于 `--repo-root` 解析。 | | `--repo-root ` | `process.cwd()` | 从中立 cwd 调用时的仓库根目录。 | -| `--sut-account ` | `sut` | QA Gateway 网关配置中的临时账户 id。 | -| `--provider-mode ` | `live-frontier` | `mock-openai` 或 `live-frontier`(旧版 `live-openai` 仍可使用)。 | +| `--sut-account ` | `sut` | QA Gateway 网关配置中的临时账号 id。 | +| `--provider-mode ` | `live-frontier` | `mock-openai` 或 `live-frontier`(旧版 `live-openai` 仍可用)。 | | `--model ` / `--alt-model ` | 提供商默认值 | 主模型/备用模型引用。 | -| `--fast` | 关闭 | 提供商支持时启用快速模式。 | -| `--credential-source ` | `env` | 请参阅 [Convex 凭证池](#convex-credential-pool)。 | -| `--credential-role ` | CI 中为 `ci`,否则为 `maintainer` | 使用 `--credential-source convex` 时采用的角色。 | +| `--fast` | 关闭 | 在支持的位置启用提供商快速模式。 | +| `--credential-source ` | `env` | 参见 [Convex 凭证池](#convex-credential-pool)。 | +| `--credential-role ` | CI 中为 `ci`,否则为 `maintainer` | 当 `--credential-source convex` 时使用的角色。 | -任何场景失败时,两者都会以非零状态退出。`--allow-failures` 会写入工件,但不会设置失败退出码。 +任一场景失败时,两者都会以非零状态退出。`--allow-failures` 会写入工件,但不会设置失败退出码。 ### Telegram QA @@ -160,9 +160,9 @@ Matrix 有一个[专用页面](/zh-CN/concepts/qa-matrix),因为它的场景 pnpm openclaw qa telegram ``` -目标是一个真实的私有 Telegram 群组,其中包含两个不同的机器人(驱动端 + SUT)。SUT 机器人必须有 Telegram 用户名;当两个机器人都在 `@BotFather` 中启用**机器人到机器人通信模式**时,机器人到机器人观测效果最佳。 +目标是一个真实的私有 Telegram 群组,其中有两个不同的机器人(driver + SUT)。SUT 机器人必须有 Telegram 用户名;当两个机器人都在 `@BotFather` 中启用 **Bot-to-Bot Communication Mode** 时,机器人到机器人的观测效果最佳。 -使用 `--credential-source env` 时所需的环境变量: +当 `--credential-source env` 时需要的环境变量: - `OPENCLAW_QA_TELEGRAM_GROUP_ID` — 数字聊天 id(字符串)。 - `OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKEN` @@ -170,7 +170,7 @@ pnpm openclaw qa telegram 可选: -- `OPENCLAW_QA_TELEGRAM_CAPTURE_CONTENT=1` 会在观测消息工件中保留消息正文(默认会脱敏)。 +- `OPENCLAW_QA_TELEGRAM_CAPTURE_CONTENT=1` 会在观测消息工件中保留消息正文(默认会遮盖)。 场景(`extensions/qa-lab/src/live-transports/telegram/telegram-live.runtime.ts:44`): @@ -186,8 +186,8 @@ pnpm openclaw qa telegram 输出工件: - `telegram-qa-report.md` -- `telegram-qa-summary.json` — 包含从 canary 开始的逐回复 RTT(驱动端发送 → 观测到 SUT 回复)。 -- `telegram-qa-observed-messages.json` — 除非设置 `OPENCLAW_QA_TELEGRAM_CAPTURE_CONTENT=1`,否则正文会被脱敏。 +- `telegram-qa-summary.json` — 包含从金丝雀开始的每条回复 RTT(driver 发送 → 观测到 SUT 回复)。 +- `telegram-qa-observed-messages.json` — 除非设置 `OPENCLAW_QA_TELEGRAM_CAPTURE_CONTENT=1`,否则正文会被遮盖。 ### Discord QA @@ -195,15 +195,15 @@ pnpm openclaw qa telegram pnpm openclaw qa discord ``` -目标是一个真实的私有 Discord 服务器频道,其中包含两个机器人:一个由 harness 控制的驱动机器人,以及一个由子 OpenClaw Gateway 网关通过内置 Discord 插件启动的 SUT 机器人。验证频道提及处理,并验证 SUT 机器人已向 Discord 注册原生 `/help` 命令。 +目标是一个真实的私有 Discord guild 渠道,其中有两个机器人:一个由 harness 控制的 driver 机器人,以及一个由子 OpenClaw Gateway 网关通过内置 Discord 插件启动的 SUT 机器人。验证渠道提及处理,以及 SUT 机器人是否已向 Discord 注册原生 `/help` 命令。 -使用 `--credential-source env` 时所需的环境变量: +当 `--credential-source env` 时需要的环境变量: - `OPENCLAW_QA_DISCORD_GUILD_ID` - `OPENCLAW_QA_DISCORD_CHANNEL_ID` - `OPENCLAW_QA_DISCORD_DRIVER_BOT_TOKEN` - `OPENCLAW_QA_DISCORD_SUT_BOT_TOKEN` -- `OPENCLAW_QA_DISCORD_SUT_APPLICATION_ID` — 必须与 Discord 返回的 SUT 机器人用户 id 匹配(否则该 lane 会快速失败)。 +- `OPENCLAW_QA_DISCORD_SUT_APPLICATION_ID` — 必须匹配 Discord 返回的 SUT 机器人用户 id(否则该 lane 会快速失败)。 可选: @@ -219,18 +219,18 @@ pnpm openclaw qa discord - `discord-qa-report.md` - `discord-qa-summary.json` -- `discord-qa-observed-messages.json` — 除非设置 `OPENCLAW_QA_DISCORD_CAPTURE_CONTENT=1`,否则正文会被脱敏。 +- `discord-qa-observed-messages.json` — 除非设置 `OPENCLAW_QA_DISCORD_CAPTURE_CONTENT=1`,否则正文会被遮盖。 ### Convex 凭证池 -Telegram 和 Discord 两条 lane 都可以从共享 Convex 池租用凭证,而不是读取上述环境变量。传入 `--credential-source convex`(或设置 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex`);QA Lab 会获取独占租约,在运行期间发送心跳,并在关闭时释放租约。池类型为 `"telegram"` 和 `"discord"`。 +Telegram 和 Discord 两条 lane 都可以从共享 Convex 池租用凭证,而不是读取上面的环境变量。传入 `--credential-source convex`(或设置 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex`);QA Lab 会获取一个独占租约,在运行期间为其发送 Heartbeat,并在关闭时释放它。池类型为 `"telegram"` 和 `"discord"`。 broker 在 `admin/add` 上验证的载荷形状: -- Telegram(`kind: "telegram"`):`{ groupId: string, driverToken: string, sutToken: string }` — `groupId` 必须是数字聊天 id 字符串。 +- Telegram(`kind: "telegram"`):`{ groupId: string, driverToken: string, sutToken: string }` — `groupId` 必须是数字 chat-id 字符串。 - Discord(`kind: "discord"`):`{ guildId: string, channelId: string, driverBotToken: string, sutBotToken: string, sutApplicationId: string }`。 -运维环境变量和 Convex broker 端点契约位于[测试 → 通过 Convex 共享 Telegram 凭证](/zh-CN/help/testing#shared-telegram-credentials-via-convex-v1)(该章节名称早于 Discord 支持;两种类型的 broker 语义相同)。 +操作环境变量和 Convex broker 端点契约位于 [测试 → 通过 Convex 共享 Telegram 凭证](/zh-CN/help/testing#shared-telegram-credentials-via-convex-v1)(该小节名称早于 Discord 支持;两种类型的 broker 语义相同)。 ## 仓库支持的种子 @@ -239,7 +239,7 @@ broker 在 `admin/add` 上验证的载荷形状: - `qa/scenarios/index.md` - `qa/scenarios//*.md` -这些内容有意放在 git 中,因此 QA 计划对人类和智能体都可见。 +这些内容有意纳入 git,因此 QA 计划对人类和智能体都可见。 `qa-lab` 应保持为通用 Markdown 运行器。每个场景 Markdown 文件都是一次测试运行的事实来源,并应定义: @@ -250,11 +250,11 @@ broker 在 `admin/add` 上验证的载荷形状: - 可选的 Gateway 网关配置补丁 - 可执行的 `qa-flow` -支持 `qa-flow` 的可复用运行时表面可以保持通用且横切。例如,Markdown 场景可以组合传输侧辅助函数和浏览器侧辅助函数,通过 Gateway 网关 `browser.request` seam 驱动嵌入式 Control UI,而不需要添加特殊情况运行器。 +支撑 `qa-flow` 的可复用运行时表面允许保持通用和横切。例如,Markdown 场景可以组合传输侧 helper 与浏览器侧 helper,后者通过 Gateway 网关 `browser.request` seam 驱动嵌入式 Control UI,而无需添加特殊情况运行器。 场景文件应按产品能力分组,而不是按源码树文件夹分组。文件移动时保持场景 ID 稳定;使用 `docsRefs` 和 `codeRefs` 实现实现可追溯性。 -基线列表应保持足够广,以覆盖: +基线列表应保持足够宽,以覆盖: - 私信和渠道聊天 - 线程行为 @@ -262,42 +262,42 @@ broker 在 `admin/add` 上验证的载荷形状: - cron 回调 - 记忆召回 - 模型切换 -- 子智能体交接 +- subagent 移交 - 仓库读取和文档读取 - 一个小型构建任务,例如 Lobster Invaders -## 提供商模拟 lane +## 提供商 mock lane -`qa suite` 有两个本地提供商模拟 lane: +`qa suite` 有两条本地提供商 mock lane: -- `mock-openai` 是具备场景感知能力的 OpenClaw 模拟。它仍然是仓库支持 QA 和一致性门禁的默认确定性模拟 lane。 -- `aimock` 会启动一个由 AIMock 支持的提供商服务器,用于实验性协议、fixture、录制/回放和混沌覆盖。它是增量功能,不会取代 `mock-openai` 场景分发器。 +- `mock-openai` 是感知场景的 OpenClaw mock。它仍然是仓库支持 QA 和 parity gate 的默认确定性 mock lane。 +- `aimock` 会启动一个由 AIMock 支撑的提供商服务器,用于实验性协议、fixture、录制/回放和混沌覆盖。它是增量能力,并不会替代 `mock-openai` 场景分发器。 -提供商 lane 实现位于 `extensions/qa-lab/src/providers/` 下。每个提供商拥有自己的默认值、本地服务器启动、Gateway 网关模型配置、auth-profile 暂存需求,以及 live/mock 能力标志。共享 suite 和 Gateway 网关代码应通过提供商注册表路由,而不是基于提供商名称分支。 +提供商 lane 实现位于 `extensions/qa-lab/src/providers/` 下。每个提供商拥有自己的默认值、本地服务器启动、Gateway 网关模型配置、auth-profile 暂存需求以及 live/mock 能力标志。共享 suite 和 Gateway 网关代码应通过提供商 registry 路由,而不是按提供商名称分支。 ## 传输适配器 -`qa-lab` 为 Markdown QA 场景拥有一个通用传输 seam。`qa-channel` 是该 seam 上的第一个适配器,但设计目标更广:未来真实或合成的渠道应接入同一个 suite 运行器,而不是添加特定传输的 QA 运行器。 +`qa-lab` 为 Markdown QA 场景拥有一个通用传输 seam。`qa-channel` 是该 seam 上的第一个适配器,但设计目标更宽:未来真实或合成渠道应接入同一个 suite 运行器,而不是添加传输特定的 QA 运行器。 在架构层面,拆分如下: -- `qa-lab` 负责通用场景执行、worker 并发、工件写入和报告。 -- 传输适配器负责 Gateway 网关配置、就绪状态、入站和出站观测、传输操作以及规范化的传输状态。 -- `qa/scenarios/` 下的 Markdown 场景文件定义测试运行;`qa-lab` 提供执行这些文件的可复用运行时表面。 +- `qa-lab` 拥有通用场景执行、worker 并发、工件写入和报告。 +- 传输适配器拥有 Gateway 网关配置、就绪状态、入站和出站观测、传输操作以及规范化传输状态。 +- `qa/scenarios/` 下的 Markdown 场景文件定义测试运行;`qa-lab` 提供执行它们的可复用运行时表面。 ### 添加渠道 向 Markdown QA 系统添加渠道只需要两件事: 1. 该渠道的传输适配器。 -2. 覆盖该渠道契约的场景包。 +2. 覆盖渠道契约的场景包。 -当共享 `qa-lab` 宿主可以拥有该流程时,不要添加新的顶层 QA 命令根。 +当共享 `qa-lab` host 可以拥有流程时,不要添加新的顶层 QA 命令根。 -`qa-lab` 拥有共享宿主机制: +`qa-lab` 拥有共享 host 机制: - `openclaw qa` 命令根 -- suite 启动和拆除 +- suite 启动和 teardown - worker 并发 - 工件写入 - 报告生成 @@ -306,35 +306,35 @@ broker 在 `admin/add` 上验证的载荷形状: 运行器插件拥有传输契约: -- `openclaw qa ` 如何挂载在共享 `qa` 根之下 -- Gateway 网关如何为该传输配置 +- `openclaw qa ` 如何挂载到共享 `qa` 根下 +- 如何为该传输配置 Gateway 网关 - 如何检查就绪状态 - 如何注入入站事件 - 如何观测出站消息 - 如何暴露 transcript 和规范化传输状态 -- 如何执行传输支持的操作 -- 如何处理特定传输的重置或清理 +- 如何执行由传输支撑的操作 +- 如何处理传输特定的重置或清理 -新渠道的最低采用门槛: +新渠道的最低采用标准: 1. 保持 `qa-lab` 作为共享 `qa` 根的所有者。 -2. 在共享 `qa-lab` 宿主 seam 上实现传输运行器。 -3. 将特定传输机制保留在运行器插件或渠道 harness 内。 -4. 将运行器挂载为 `openclaw qa `,而不是注册竞争性的根命令。运行器插件应在 `openclaw.plugin.json` 中声明 `qaRunners`,并从 `runtime-api.ts` 导出匹配的 `qaRunnerCliRegistrations` 数组。保持 `runtime-api.ts` 轻量;惰性 CLI 和运行器执行应留在单独入口点之后。 -5. 在按主题组织的 `qa/scenarios/` 目录下编写或调整 Markdown 场景。 -6. 对新场景使用通用场景辅助函数。 +2. 在共享 `qa-lab` host seam 上实现传输运行器。 +3. 将传输特定机制保留在运行器插件或渠道 harness 内。 +4. 将运行器挂载为 `openclaw qa `,而不是注册竞争性的根命令。运行器插件应在 `openclaw.plugin.json` 中声明 `qaRunners`,并从 `runtime-api.ts` 导出匹配的 `qaRunnerCliRegistrations` 数组。保持 `runtime-api.ts` 轻量;懒加载 CLI 和运行器执行应放在单独入口点之后。 +5. 在按主题组织的 `qa/scenarios/` 目录下编写或改写 Markdown 场景。 +6. 对新场景使用通用场景 helper。 7. 除非仓库正在进行有意迁移,否则保持现有兼容别名可用。 决策规则很严格: -- 如果行为可以在 `qa-lab` 中表达一次,就放在 `qa-lab` 中。 -- 如果行为依赖某个渠道传输,就保留在该运行器插件或插件 harness 中。 -- 如果某个场景需要多个渠道都能使用的新能力,就添加通用辅助函数,而不是在 `suite.ts` 中添加特定渠道分支。 -- 如果某个行为只对一种传输有意义,就保持场景特定于传输,并在场景契约中明确说明。 +- 如果行为可以在 `qa-lab` 中表达一次,就放到 `qa-lab` 中。 +- 如果行为依赖某一个渠道传输,就将其保留在该运行器插件或插件 harness 中。 +- 如果场景需要不止一个渠道可使用的新能力,请添加通用 helper,而不是在 `suite.ts` 中添加渠道特定分支。 +- 如果某个行为只对一个传输有意义,就让该场景保持传输特定,并在场景契约中明确说明。 -### 场景辅助函数名称 +### 场景 helper 名称 -新场景首选的通用辅助函数: +新场景首选的通用 helper: - `waitForTransportReady` - `waitForChannelReady` @@ -349,21 +349,20 @@ broker 在 `admin/add` 上验证的载荷形状: - `formatTransportTranscript` - `resetTransport` -兼容别名仍可用于现有场景 — `waitForQaChannelReady`、`waitForOutboundMessage`、`waitForNoOutbound`、`formatConversationTranscript`、`resetBus` — 但新场景编写应使用通用名称。这些别名用于避免一次性迁移,而不是未来采用的模型。 +兼容别名仍可用于现有场景:`waitForQaChannelReady`、`waitForOutboundMessage`、`waitForNoOutbound`、`formatConversationTranscript`、`resetBus`,但新场景编写应使用通用名称。这些别名的存在是为了避免一次性迁移,而不是作为未来模型。 ## 报告 -`qa-lab` 会从观测到的总线时间线导出 Markdown 协议报告。 -报告应回答: +`qa-lab` 会从观测到的 bus timeline 导出 Markdown 协议报告。报告应回答: -- 哪些工作正常 -- 哪些失败了 -- 哪些仍然被阻塞 +- 哪些有效 +- 哪些失败 +- 哪些仍被阻塞 - 哪些后续场景值得添加 -如需查看可用场景清单(在评估后续工作量或接入新传输协议时很有用),请运行 `pnpm openclaw qa coverage`(添加 `--json` 可获得机器可读输出)。 +要查看可用场景清单,在评估后续工作量或接入新的传输协议时很有用,请运行 `pnpm openclaw qa coverage`(添加 `--json` 可获得机器可读输出)。 -如需进行角色与风格检查,请在多个实时模型 ref 上运行同一个场景,并写出经过评判的 Markdown 报告: +要进行角色和风格检查,请在多个实时模型引用上运行同一个场景,并写入一份经评判的 Markdown 报告: ```bash pnpm openclaw qa character-eval \ @@ -382,22 +381,22 @@ pnpm openclaw qa character-eval \ --judge-concurrency 16 ``` -该命令运行本地 QA Gateway 网关子进程,而不是 Docker。角色评估场景应通过 `SOUL.md` 设置 persona,然后运行普通用户轮次,例如聊天、工作区帮助和小文件任务。不应告知候选模型它正在接受评估。该命令会保留每份完整转录,记录基本运行统计信息,然后在支持的情况下以 fast 模式和 `xhigh` 推理请求评判模型按自然度、气质和幽默感对运行结果排序。比较提供商时使用 `--blind-judge-models`:评判提示仍会获得每份转录和运行状态,但候选 ref 会被替换为中性标签,例如 `candidate-01`;报告会在解析后将排名映射回真实 ref。 -候选运行默认使用 `high` thinking,GPT-5.5 使用 `medium`,支持的较旧 OpenAI 评估 ref 使用 `xhigh`。可用 `--model provider/model,thinking=` 内联覆盖特定候选。`--thinking ` 仍会设置全局 fallback,较旧的 `--model-thinking ` 形式会为兼容性保留。 -OpenAI 候选 ref 默认使用 fast 模式,以便在提供商支持时使用优先处理。当某个候选或评判需要覆盖时,内联添加 `,fast`、`,no-fast` 或 `,fast=false`。仅当你想强制每个候选模型都开启 fast 模式时,才传入 `--fast`。候选和评判耗时会记录在报告中用于基准分析,但评判提示会明确说明不要按速度排名。 -候选和评判模型运行都默认使用并发数 16。当提供商限制或本地 Gateway 网关压力使运行噪声过大时,降低 `--concurrency` 或 `--judge-concurrency`。 +该命令运行本地 QA Gateway 网关子进程,而不是 Docker。角色评估场景应通过 `SOUL.md` 设置人格,然后运行普通用户轮次,例如聊天、工作区帮助和小文件任务。不应告知候选模型它正在接受评估。该命令会保留每份完整转录,记录基本运行统计,然后在支持的情况下以快速模式和 `xhigh` 推理请求评判模型按自然度、感觉和幽默感对运行结果进行排序。比较提供商时使用 `--blind-judge-models`:评判提示仍会获得每份转录和运行 Status,但候选引用会替换为中性标签,例如 `candidate-01`;报告会在解析后将排名映射回真实引用。 +候选运行默认使用 `high` 思考;GPT-5.5 使用 `medium`,支持该级别的较旧 OpenAI 评估引用使用 `xhigh`。可通过 `--model provider/model,thinking=` 内联覆盖特定候选。`--thinking ` 仍会设置全局回退,较旧的 `--model-thinking ` 形式会保留以保持兼容。 +OpenAI 候选引用默认使用快速模式,因此会在提供商支持时使用优先处理。当单个候选或评判模型需要覆盖时,可内联添加 `,fast`、`,no-fast` 或 `,fast=false`。仅当你想为每个候选模型强制启用快速模式时,才传递 `--fast`。报告中会记录候选和评判模型的耗时以用于基准分析,但评判提示会明确要求不要按速度排序。 +候选和评判模型运行都默认使用并发 16。当提供商限制或本地 Gateway 网关压力使运行噪声过大时,请降低 `--concurrency` 或 `--judge-concurrency`。 未传入候选 `--model` 时,角色评估默认使用 `openai/gpt-5.5`、`openai/gpt-5.2`、`openai/gpt-5`、`anthropic/claude-opus-4-6`、 `anthropic/claude-sonnet-4-6`、`zai/glm-5.1`、 `moonshot/kimi-k2.5` 和 `google/gemini-3.1-pro-preview`。 -未传入 `--judge-model` 时,评判默认使用 +未传入 `--judge-model` 时,评判模型默认使用 `openai/gpt-5.5,thinking=xhigh,fast` 和 `anthropic/claude-opus-4-6,thinking=high`。 ## 相关文档 - [Matrix QA](/zh-CN/concepts/qa-matrix) -- [QA Channel](/zh-CN/channels/qa-channel) +- [QA 渠道](/zh-CN/channels/qa-channel) - [测试](/zh-CN/help/testing) -- [仪表板](/zh-CN/web/dashboard) +- [仪表盘](/zh-CN/web/dashboard) diff --git a/docs/zh-CN/help/testing.md b/docs/zh-CN/help/testing.md index 397a37138..c0f95953f 100644 --- a/docs/zh-CN/help/testing.md +++ b/docs/zh-CN/help/testing.md @@ -1,44 +1,44 @@ --- read_when: - 在本地或 CI 中运行测试 - - 为模型/提供商 bug 添加回归测试 + - 为模型/提供商缺陷添加回归测试 - 调试 Gateway 网关 + 智能体行为 -summary: 测试工具包:unit/e2e/live 套件、Docker 运行器,以及每项测试涵盖的内容 +summary: 测试工具包:unit/e2e/live 套件、Docker 运行器,以及每项测试覆盖的内容 title: 测试 x-i18n: - generated_at: "2026-05-02T18:56:28Z" + generated_at: "2026-05-02T20:01:33Z" model: gpt-5.5 provider: openai - source_hash: 723d4769d13a83482bd4afcd1878579ba2b245c8e49cefc2794e865da1ab7dc7 + source_hash: a5bfbd2ea78b05ca23e97318943e0043645814d2aa4ccb7540a2bf7c601d0d09 source_path: help/testing.md workflow: 16 --- -OpenClaw 有三个 Vitest 套件(单元/集成、e2e、live)和一小组 Docker 运行器。这份文档是“我们如何测试”的指南: +OpenClaw 有三套 Vitest 测试套件(单元/集成、e2e、live)和少量 Docker 运行器。本文档是“我们如何测试”的指南: -- 每个套件覆盖什么(以及刻意_不_覆盖什么)。 -- 常见工作流(本地、推送前、调试)应该运行哪些命令。 -- live 测试如何发现凭据并选择模型/提供商。 -- 如何为真实世界中的模型/提供商问题添加回归测试。 +- 每个套件覆盖什么(以及它刻意_不_覆盖什么)。 +- 常见工作流(本地、推送前、调试)应运行哪些命令。 +- live 测试如何发现凭证并选择模型/提供商。 +- 如何为真实世界的模型/提供商问题添加回归测试。 -**QA 栈(qa-lab、qa-channel、live 传输通道)**单独记录在以下文档中: +**QA 栈(qa-lab、qa-channel、live 传输通道)**在单独文档中说明: - [QA overview](/zh-CN/concepts/qa-e2e-automation) — 架构、命令界面、场景编写。 -- [Matrix QA](/zh-CN/concepts/qa-matrix) — `pnpm openclaw qa matrix` 的参考。 -- [QA channel](/zh-CN/channels/qa-channel) — repo 支持的场景所使用的合成传输插件。 +- [Matrix QA](/zh-CN/concepts/qa-matrix) — `pnpm openclaw qa matrix` 参考。 +- [QA channel](/zh-CN/channels/qa-channel) — 由仓库支持的场景使用的合成传输插件。 -本页介绍如何运行常规测试套件和 Docker/Parallels 运行器。下面的 QA 专用运行器部分([QA 专用运行器](#qa-specific-runners))列出了具体的 `qa` 调用,并指回上面的参考资料。 +本页面覆盖常规测试套件和 Docker/Parallels 运行器。下面的 QA 专用运行器部分([QA-specific runners](#qa-specific-runners))列出了具体的 `qa` 调用,并指回上面的参考资料。 ## 快速开始 -大多数时候: +大多数日子: -- 完整门禁(推送前预期运行):`pnpm build && pnpm check && pnpm check:test-types && pnpm test` -- 在空间充足的机器上更快地运行本地完整套件:`pnpm test:max` +- 完整门禁(推送前预期执行):`pnpm build && pnpm check && pnpm check:test-types && pnpm test` +- 在资源充足的机器上更快运行本地完整套件:`pnpm test:max` - 直接的 Vitest 监听循环:`pnpm test:watch` -- 现在直接定位文件也会路由 extension/channel 路径:`pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` +- 直接文件定向现在也会路由插件/渠道路径:`pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` - 当你在迭代单个失败时,优先使用定向运行。 - Docker 支持的 QA 站点:`pnpm qa:lab:up` - Linux VM 支持的 QA 通道:`pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline` @@ -48,59 +48,55 @@ OpenClaw 有三个 Vitest 套件(单元/集成、e2e、live)和一小组 Doc - 覆盖率门禁:`pnpm test:coverage` - E2E 套件:`pnpm test:e2e` -调试真实提供商/模型时(需要真实凭据): +调试真实提供商/模型时(需要真实凭证): - live 套件(模型 + Gateway 网关工具/图像探测):`pnpm test:live` -- 静默定位一个 live 文件:`pnpm test:live -- src/agents/models.profiles.live.test.ts` -- 运行时性能报告:分派 `OpenClaw Performance`,使用 - `live_gpt54=true` 进行一次真实的 `openai/gpt-5.4` 智能体回合,或使用 - `deep_profile=true` 生成 Kova CPU/堆/跟踪工件。每日定时运行会在配置了 - `CLAWGRIT_REPORTS_TOKEN` 时,将 mock-provider、deep-profile 和 GPT 5.4 通道工件发布到 - `openclaw/clawgrit-reports`。mock-provider 报告还包括源码级 Gateway 网关启动、内存、 - 插件压力、重复 fake-model hello-loop 和 CLI 启动指标。 +- 安静地定向一个 live 文件:`pnpm test:live -- src/agents/models.profiles.live.test.ts` +- 运行时性能报告:调度 `OpenClaw Performance`,将 + `live_gpt54=true` 用于一次真实的 `openai/gpt-5.4` 智能体轮次,或将 + `deep_profile=true` 用于 Kova CPU/堆/跟踪工件。每日计划运行会在配置 + `CLAWGRIT_REPORTS_TOKEN` 时,将 mock-provider、deep-profile 和 GPT 5.4 + 通道工件发布到 `openclaw/clawgrit-reports`。mock-provider 报告还包括源码级 + Gateway 网关启动、内存、插件压力、重复 fake-model hello-loop 和 CLI 启动数据。 - Docker live 模型扫描:`pnpm test:docker:live-models` - - 每个被选择的模型现在会运行一个文本回合,以及一个小型文件读取风格探测。 - 元数据标示支持 `image` 输入的模型还会运行一个小型图像回合。 - 在隔离提供商失败时,可以用 `OPENCLAW_LIVE_MODEL_FILE_PROBE=0` 或 + - 每个选定模型现在会运行一次文本轮次,以及一个小型文件读取风格探测。 + 元数据声明支持 `image` 输入的模型还会运行一个小型图像轮次。 + 在隔离提供商失败时,可用 `OPENCLAW_LIVE_MODEL_FILE_PROBE=0` 或 `OPENCLAW_LIVE_MODEL_IMAGE_PROBE=0` 禁用额外探测。 - CI 覆盖:每日 `OpenClaw Scheduled Live And E2E Checks` 和手动 - `OpenClaw Release Checks` 都会调用可复用的 live/E2E 工作流,并设置 - `include_live_suites: true`,其中包括按提供商分片的独立 Docker live 模型矩阵作业。 - - 对于聚焦的 CI 重跑,分派 `OpenClaw Live And E2E Checks (Reusable)`,并设置 - `include_live_suites: true` 和 `live_models_only: true`。 - - 将新的高信号提供商 secret 添加到 `scripts/ci-hydrate-live-auth.sh`、 - `.github/workflows/openclaw-live-and-e2e-checks-reusable.yml` 及其 - 定时/发布调用方。 + `OpenClaw Release Checks` 都会以 `include_live_suites: true` 调用可复用 live/E2E 工作流, + 其中包含按提供商分片的独立 Docker live 模型矩阵作业。 + - 对于聚焦的 CI 重跑,调度 `OpenClaw Live And E2E Checks (Reusable)`, + 并设置 `include_live_suites: true` 和 `live_models_only: true`。 + - 将新的高信号提供商密钥添加到 `scripts/ci-hydrate-live-auth.sh`, + 以及 `.github/workflows/openclaw-live-and-e2e-checks-reusable.yml` 和它的计划/发布调用方。 - 原生 Codex 绑定聊天冒烟测试:`pnpm test:docker:live-codex-bind` - 针对 Codex app-server 路径运行 Docker live 通道,绑定一个带 `/codex bind` 的合成 - Slack 私信,执行 `/codex fast` 和 - `/codex permissions`,然后验证普通回复和图像附件通过原生插件绑定而不是 ACP 路由。 + Slack 私信,执行 `/codex fast` 和 `/codex permissions`,然后验证普通回复和图像附件 + 通过原生插件绑定路由,而不是通过 ACP。 - Codex app-server harness 冒烟测试:`pnpm test:docker:live-codex-harness` - - 通过插件拥有的 Codex app-server harness 运行 Gateway 网关智能体回合, - 验证 `/codex status` 和 `/codex models`,并默认执行图像、 - cron MCP、子智能体和 Guardian 探测。在隔离其他 Codex - app-server 失败时,用 + - 通过插件自有的 Codex app-server harness 运行 Gateway 网关智能体轮次, + 验证 `/codex status` 和 `/codex models`,并默认执行图像、cron MCP、子智能体和 Guardian 探测。 + 在隔离其他 Codex app-server 失败时,可用 `OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_PROBE=0` 禁用子智能体探测。对于聚焦的子智能体检查,禁用其他探测: `OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=0 OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=0 OPENCLAW_LIVE_CODEX_HARNESS_GUARDIAN_PROBE=0 OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_PROBE=1 pnpm test:docker:live-codex-harness`。 - 这会在子智能体探测后退出,除非设置了 - `OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_ONLY=0`。 + 除非设置 `OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_ONLY=0`,否则它会在子智能体探测后退出。 - Crestodian 救援命令冒烟测试:`pnpm test:live:crestodian-rescue-channel` - - 针对消息渠道救援命令界面的可选双重保障检查。 - 它会执行 `/crestodian status`,排队一个持久模型变更, - 回复 `/crestodian yes`,并验证审计/配置写入路径。 -- Crestodian planner Docker 冒烟测试:`pnpm test:docker:crestodian-planner` - - 在无配置容器中运行 Crestodian,并在 `PATH` 上提供一个假 Claude CLI, - 然后验证模糊 planner 回退会转换为已审计的类型化配置写入。 + - 针对消息渠道救援命令界面的可选双重检查。它会执行 `/crestodian status`, + 排队一个持久模型更改,回复 `/crestodian yes`,并验证审计/配置写入路径。 +- Crestodian 规划器 Docker 冒烟测试:`pnpm test:docker:crestodian-planner` + - 在无配置容器中运行 Crestodian,`PATH` 上带有假的 Claude CLI, + 并验证模糊规划器回退会转换为经过审计的类型化配置写入。 - Crestodian 首次运行 Docker 冒烟测试:`pnpm test:docker:crestodian-first-run` - - 从空 OpenClaw 状态目录开始,将裸 `openclaw` 路由到 + - 从空的 OpenClaw 状态目录开始,将裸 `openclaw` 路由到 Crestodian,应用设置/模型/智能体/Discord 插件 + SecretRef 写入, - 验证配置,并验证审计条目。同一个 Ring 0 设置路径也由 QA Lab 中的 + 验证配置,并验证审计条目。相同的 Ring 0 设置路径也由 QA Lab 中的 `pnpm openclaw qa suite --scenario crestodian-ring-zero-setup` 覆盖。 - Moonshot/Kimi 成本冒烟测试:设置 `MOONSHOT_API_KEY` 后,运行 `openclaw models list --provider moonshot --json`,然后针对 `moonshot/kimi-k2.6` 运行一个隔离的 `openclaw agent --local --session-id live-kimi-cost --message 'Reply exactly: KIMI_LIVE_OK' --thinking off --json`。 - 验证 JSON 报告 Moonshot/K2.6,并且助手 transcript 存储了标准化的 `usage.cost`。 + 验证 JSON 报告 Moonshot/K2.6,并且助手转录存储规范化后的 `usage.cost`。 当你只需要一个失败用例时,优先通过下面描述的 allowlist 环境变量缩小 live 测试范围。 @@ -108,52 +104,57 @@ OpenClaw 有三个 Vitest 套件(单元/集成、e2e、live)和一小组 Doc ## QA 专用运行器 -当你需要 QA-lab 真实度时,这些命令与主测试套件并列使用: +当你需要 QA-lab 真实度时,这些命令与主测试套件并列: -CI 在专用工作流中运行 QA Lab。`Parity gate` 会在匹配的 PR 上运行,也可以通过使用 mock 提供商的手动分派运行。`QA-Lab - All Lanes` 每晚在 -`main` 上运行,也可以通过手动分派运行,并将 mock parity gate、live Matrix 通道、 -Convex 管理的 live Telegram 通道和 Convex 管理的 live Discord 通道作为并行作业运行。定时 QA 和发布检查会显式传递 Matrix `--profile fast`, -而 Matrix CLI 和手动工作流输入的默认值仍为 -`all`;手动分派可以将 `all` 分片为 `transport`、`media`、`e2ee-smoke`、 -`e2ee-deep` 和 `e2ee-cli` 作业。`OpenClaw Release Checks` 会在发布批准前运行 parity 以及 fast Matrix 和 Telegram 通道,发布传输检查使用 -`mock-openai/gpt-5.5`,以便保持确定性并避免正常的提供商插件启动。这些 live 传输 Gateway 网关会禁用记忆搜索;记忆行为仍由 QA parity 套件覆盖。 +CI 在专用工作流中运行 QA Lab。Agentic parity 嵌套在 +`QA-Lab - All Lanes` 和发布验证下,而不是独立的 PR 工作流。 +广泛验证应使用 `Full Release Validation`,并设置 +`rerun_group=qa-parity`,或使用 release-checks QA 组。`QA-Lab - All Lanes` +每晚在 `main` 上运行,也可通过手动调度运行,并将 mock parity 通道、live +Matrix 通道、Convex 管理的 live Telegram 通道和 Convex 管理的 live Discord +通道作为并行作业。计划 QA 和发布检查会显式传递 Matrix +`--profile fast`,而 Matrix CLI 和手动工作流输入默认值仍为 `all`;手动调度可以将 `all` +分片为 `transport`、`media`、`e2ee-smoke`、`e2ee-deep` 和 `e2ee-cli` 作业。 +`OpenClaw Release Checks` 会在发布批准前运行 parity,以及 fast Matrix 和 Telegram +通道,发布传输检查使用 `mock-openai/gpt-5.5`,以便保持确定性并避免正常提供商插件启动。 +这些 live 传输 Gateway 网关会禁用记忆搜索;记忆行为仍由 QA parity 套件覆盖。 完整发布 live 媒体分片使用 `ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04`,其中已经包含 `ffmpeg` 和 `ffprobe`。Docker live 模型/后端分片使用共享的 -`ghcr.io/openclaw/openclaw-live-test:` 镜像,该镜像会为每个被选择的提交构建一次,然后使用 -`OPENCLAW_SKIP_DOCKER_BUILD=1` 拉取它,而不是在每个分片内部重新构建。 +`ghcr.io/openclaw/openclaw-live-test:` 镜像,该镜像针对每个选定提交只构建一次, +然后使用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 拉取它,而不是在每个分片内部重新构建。 - `pnpm openclaw qa suite` - - 直接在主机上运行由仓库支撑的 QA 场景。 - - 默认使用隔离的 Gateway 网关工作进程并行运行多个选定场景。`qa-channel` 默认并发数为 4(受选定场景数量限制)。使用 `--concurrency ` 调整工作进程数量,或使用 `--concurrency 1` 运行较旧的串行通道。 - - 任何场景失败时以非零状态退出。如果你想获取工件但不希望退出码失败,请使用 `--allow-failures`。 - - 支持提供商模式 `live-frontier`、`mock-openai` 和 `aimock`。`aimock` 会启动一个由本地 AIMock 支撑的提供商服务器,用于实验性的 fixture 和协议模拟覆盖,同时不会替换具备场景感知能力的 `mock-openai` 通道。 + - 直接在主机上运行由仓库支持的 QA 场景。 + - 默认使用隔离的 Gateway 网关 worker 并行运行多个已选场景。`qa-channel` 默认并发数为 4(受已选场景数量限制)。使用 `--concurrency ` 调整 worker 数量,或使用 `--concurrency 1` 进入较旧的串行通道。 + - 任何场景失败时以非零状态退出。当你想获取构件但不希望失败退出码时,使用 `--allow-failures`。 + - 支持提供商模式 `live-frontier`、`mock-openai` 和 `aimock`。`aimock` 会启动一个本地 AIMock 支持的提供商服务器,用于实验性的 fixture 和协议 mock 覆盖,而不会替代可感知场景的 `mock-openai` 通道。 - `pnpm test:gateway:cpu-scenarios` - - 运行 Gateway 网关启动基准测试以及一个小型 mock QA Lab 场景包(`channel-chat-baseline`、`memory-failure-fallback`、`gateway-restart-inflight-run`),并在 `.artifacts/gateway-cpu-scenarios/` 下写入合并后的 CPU 观测摘要。 - - 默认只标记持续的高 CPU 观测(`--cpu-core-warn` 加 `--hot-wall-warn-ms`),因此短暂的启动突增会被记录为指标,而不会看起来像持续数分钟的 Gateway 网关占满 CPU 回归。 - - 使用已构建的 `dist` 工件;如果当前检出尚无新的运行时输出,请先运行构建。 + - 运行 Gateway 网关启动基准测试,加上一小组 mock QA Lab 场景包(`channel-chat-baseline`、`memory-failure-fallback`、`gateway-restart-inflight-run`),并在 `.artifacts/gateway-cpu-scenarios/` 下写入合并后的 CPU 观察摘要。 + - 默认只标记持续的高 CPU 观察结果(`--cpu-core-warn` 加 `--hot-wall-warn-ms`),因此短暂的启动峰值会被记录为指标,而不会看起来像持续数分钟的 Gateway 网关占满回归。 + - 使用已构建的 `dist` 构件;当检出内容中尚无最新运行时输出时,请先运行构建。 - `pnpm openclaw qa suite --runner multipass` - - 在一次性 Multipass Linux VM 内运行同一套 QA 套件。 - - 保持与主机上 `qa suite` 相同的场景选择行为。 + - 在一次性 Multipass Linux VM 内运行同一个 QA 套件。 + - 保持与主机上的 `qa suite` 相同的场景选择行为。 - 复用与 `qa suite` 相同的提供商/模型选择标志。 - - 实时运行会转发对 guest 可用且实际可行的受支持 QA 鉴权输入:基于环境变量的提供商密钥、QA 实时提供商配置路径,以及存在时的 `CODEX_HOME`。 - - 输出目录必须保留在仓库根目录下,以便 guest 可以通过挂载的工作区写回。 - - 在 `.artifacts/qa-e2e/...` 下写入常规 QA 报告和摘要,以及 Multipass 日志。 + - 实时运行会转发适合 guest 使用的受支持 QA 认证输入:基于环境的提供商密钥、QA 实时提供商配置路径,以及存在时的 `CODEX_HOME`。 + - 输出目录必须位于仓库根目录下,以便 guest 可以通过挂载的工作区写回。 + - 在 `.artifacts/qa-e2e/...` 下写入常规 QA 报告 + 摘要以及 Multipass 日志。 - `pnpm qa:lab:up` - - 启动由 Docker 支撑的 QA 站点,用于操作员式 QA 工作。 + - 启动由 Docker 支持的 QA 站点,用于操作员风格的 QA 工作。 - `pnpm test:docker:npm-onboard-channel-agent` - - 从当前检出构建 npm tarball,在 Docker 中全局安装,运行非交互式 OpenAI API key 新手引导,默认配置 Telegram,验证打包后的插件运行时可在无需启动依赖修复的情况下加载,运行 Doctor,并针对 mock 的 OpenAI 端点运行一次本地智能体回合。 - - 使用 `OPENCLAW_NPM_ONBOARD_CHANNEL=discord` 可用 Discord 运行同一条打包安装通道。 + - 从当前检出内容构建 npm tarball,在 Docker 中全局安装,运行非交互式 OpenAI API key 新手引导,默认配置 Telegram,验证打包后的插件运行时无需启动依赖修复即可加载,运行 Doctor,并针对 mock 的 OpenAI 端点运行一次本地智能体回合。 + - 使用 `OPENCLAW_NPM_ONBOARD_CHANNEL=discord` 以 Discord 运行同一个打包安装通道。 - `pnpm test:docker:session-runtime-context` - - 针对嵌入式运行时上下文 transcript 运行确定性的已构建应用 Docker smoke。它会验证隐藏的 OpenClaw 运行时上下文作为非显示自定义消息持久化,而不会泄漏到可见的用户回合中;随后播种一个受影响的损坏会话 JSONL,并验证 `openclaw doctor --fix` 会将其重写到当前分支并创建备份。 + - 为嵌入式运行时上下文 transcript 运行确定性的已构建应用 Docker smoke。它会验证隐藏的 OpenClaw 运行时上下文被持久化为非显示自定义消息,而不是泄漏到可见的用户回合中,然后播种一个受影响的损坏会话 JSONL,并验证 `openclaw doctor --fix` 将其重写到 active 分支并创建备份。 - `pnpm test:docker:npm-telegram-live` - 在 Docker 中安装一个 OpenClaw 包候选版本,运行已安装包的新手引导,通过已安装的 CLI 配置 Telegram,然后复用实时 Telegram QA 通道,并将该已安装包作为 SUT Gateway 网关。 - - 默认使用 `OPENCLAW_NPM_TELEGRAM_PACKAGE_SPEC=openclaw@beta`;设置 `OPENCLAW_NPM_TELEGRAM_PACKAGE_TGZ=/path/to/openclaw-current.tgz` 或 `OPENCLAW_CURRENT_PACKAGE_TGZ`,可测试已解析的本地 tarball,而不是从 registry 安装。 - - 使用与 `pnpm openclaw qa telegram` 相同的 Telegram 环境变量凭证或 Convex 凭证来源。对于 CI/发布自动化,请设置 `OPENCLAW_NPM_TELEGRAM_CREDENTIAL_SOURCE=convex`,以及 `OPENCLAW_QA_CONVEX_SITE_URL` 和角色 secret。如果 CI 中存在 `OPENCLAW_QA_CONVEX_SITE_URL` 和 Convex 角色 secret,Docker wrapper 会自动选择 Convex。 + - 默认值为 `OPENCLAW_NPM_TELEGRAM_PACKAGE_SPEC=openclaw@beta`;设置 `OPENCLAW_NPM_TELEGRAM_PACKAGE_TGZ=/path/to/openclaw-current.tgz` 或 `OPENCLAW_CURRENT_PACKAGE_TGZ`,可测试已解析的本地 tarball,而不是从 registry 安装。 + - 使用与 `pnpm openclaw qa telegram` 相同的 Telegram 环境凭证或 Convex 凭证来源。对于 CI/发布自动化,请设置 `OPENCLAW_NPM_TELEGRAM_CREDENTIAL_SOURCE=convex`,再加上 `OPENCLAW_QA_CONVEX_SITE_URL` 和角色密钥。如果 CI 中存在 `OPENCLAW_QA_CONVEX_SITE_URL` 和 Convex 角色密钥,Docker wrapper 会自动选择 Convex。 - `OPENCLAW_NPM_TELEGRAM_CREDENTIAL_ROLE=ci|maintainer` 仅为此通道覆盖共享的 `OPENCLAW_QA_CREDENTIAL_ROLE`。 - - GitHub Actions 将此通道公开为手动 maintainer 工作流 `NPM Telegram Beta E2E`。它不会在合并时运行。该工作流使用 `qa-live-shared` 环境和 Convex CI 凭证租约。 -- GitHub Actions 还提供 `Package Acceptance`,用于针对一个候选包进行旁路产品验证。它接受可信 ref、已发布的 npm spec、HTTPS tarball URL 加 SHA-256,或另一次运行中的 tarball 工件;上传规范化的 `openclaw-current.tgz` 作为 `package-under-test`,然后使用 smoke、package、product、full 或 custom 通道配置文件运行现有 Docker E2E 调度器。设置 `telegram_mode=mock-openai` 或 `live-frontier`,可让 Telegram QA 工作流针对同一个 `package-under-test` 工件运行。 + - GitHub Actions 将此通道暴露为手动维护者 workflow `NPM Telegram Beta E2E`。它不会在 merge 时运行。该 workflow 使用 `qa-live-shared` 环境和 Convex CI 凭证租约。 +- GitHub Actions 还暴露 `Package Acceptance`,用于针对一个候选包进行旁路产品验证。它接受受信任 ref、已发布 npm spec、HTTPS tarball URL 加 SHA-256,或来自另一次运行的 tarball 构件,上传规范化的 `openclaw-current.tgz` 作为 `package-under-test`,然后使用 smoke、package、product、full 或 custom 通道 profile 运行现有 Docker E2E 调度器。设置 `telegram_mode=mock-openai` 或 `live-frontier`,可针对同一个 `package-under-test` 构件运行 Telegram QA workflow。 - 最新 beta 产品验证: ```bash @@ -174,7 +175,7 @@ gh workflow run package-acceptance.yml --ref main \ -f suite_profile=package ``` -- 工件验证会从另一次 Actions 运行中下载 tarball 工件: +- 构件验证会从另一次 Actions 运行下载 tarball 构件: ```bash gh workflow run package-acceptance.yml --ref main \ @@ -186,43 +187,43 @@ gh workflow run package-acceptance.yml --ref main \ - `pnpm test:docker:plugins` - 在 Docker 中打包并安装当前 OpenClaw 构建,启动已配置 OpenAI 的 Gateway 网关,然后通过配置编辑启用内置渠道/插件。 - - 验证设置发现会让未配置的可下载插件保持缺席,第一次配置后的 Doctor 修复会显式安装每个缺失的可下载插件,并且第二次重启不会运行隐藏的依赖修复。 - - 还会安装一个已知的较旧 npm 基线版本,在运行 `openclaw update --tag ` 前启用 Telegram,并验证候选版本的更新后 Doctor 会清理旧版插件依赖残留,而无需 harness 侧 postinstall 修复。 + - 验证设置发现会让未配置的可下载插件保持缺失,第一次已配置的 Doctor 修复会显式安装每个缺失的可下载插件,并且第二次重启不会运行隐藏依赖修复。 + - 还会安装一个已知的较旧 npm 基线,在运行 `openclaw update --tag ` 前启用 Telegram,并验证候选版本的更新后 Doctor 会清理旧插件依赖残留,而无需 harness 侧 postinstall 修复。 - `pnpm test:parallels:npm-update` - - 跨 Parallels guest 运行原生打包安装更新 smoke。每个选定平台会先安装请求的基线包,然后在同一个 guest 中运行已安装的 `openclaw update` 命令,并验证已安装版本、更新状态、Gateway 网关就绪状态,以及一次本地智能体回合。 - - 迭代单个 guest 时使用 `--platform macos`、`--platform windows` 或 `--platform linux`。使用 `--json` 获取摘要工件路径和每通道状态。 - - OpenAI 通道默认使用 `openai/gpt-5.5` 进行实时智能体回合验证。若有意验证另一个 OpenAI 模型,请传入 `--model ` 或设置 `OPENCLAW_PARALLELS_OPENAI_MODEL`。 - - 用主机 timeout 包裹长时间本地运行,避免 Parallels 传输卡顿耗尽剩余测试窗口: + - 跨 Parallels guest 运行原生打包安装更新 smoke。每个已选平台会先安装请求的基线包,然后在同一个 guest 中运行已安装的 `openclaw update` 命令,并验证已安装版本、更新状态、Gateway 网关就绪情况,以及一个本地智能体回合。 + - 在迭代单个 guest 时使用 `--platform macos`、`--platform windows` 或 `--platform linux`。使用 `--json` 获取摘要构件路径和每条通道状态。 + - OpenAI 通道默认使用 `openai/gpt-5.5` 进行实时智能体回合验证。有意验证另一个 OpenAI 模型时,传入 `--model ` 或设置 `OPENCLAW_PARALLELS_OPENAI_MODEL`。 + - 用主机 timeout 包裹较长的本地运行,避免 Parallels 传输停滞耗尽剩余测试窗口: ```bash timeout --foreground 150m pnpm test:parallels:npm-update -- --json timeout --foreground 90m pnpm test:parallels:npm-update -- --platform windows --json ``` - - 该脚本会在 `/tmp/openclaw-parallels-npm-update.*` 下写入嵌套通道日志。在假定外层 wrapper 卡住之前,请先检查 `windows-update.log`、`macos-update.log` 或 `linux-update.log`。 - - 在冷 guest 上,Windows 更新可能会在更新后 Doctor 和包更新工作中花费 10 到 15 分钟;只要嵌套 npm debug 日志仍在推进,这仍属正常。 + - 该脚本会在 `/tmp/openclaw-parallels-npm-update.*` 下写入嵌套通道日志。在假设外层 wrapper 挂起之前,先检查 `windows-update.log`、`macos-update.log` 或 `linux-update.log`。 + - 在冷 guest 上,Windows 更新可能在更新后 Doctor 和包更新工作中花费 10 到 15 分钟;只要嵌套 npm debug 日志仍在推进,这仍然是健康状态。 - 不要将此聚合 wrapper 与单独的 Parallels macOS、Windows 或 Linux smoke 通道并行运行。它们共享 VM 状态,可能在快照恢复、包服务或 guest Gateway 网关状态上发生冲突。 - - 更新后验证会运行常规内置插件表面,因为 speech、image generation 和 media understanding 等能力 facade 会通过内置运行时 API 加载,即使智能体回合本身只检查简单文本响应。 + - 更新后验证会运行常规内置插件表面,因为 speech、图像生成和媒体理解等能力 facade 会通过内置运行时 API 加载,即使智能体回合本身只检查简单文本响应。 - `pnpm openclaw qa aimock` - 仅启动本地 AIMock 提供商服务器,用于直接协议 smoke 测试。 - `pnpm openclaw qa matrix` - - 针对一次性的 Docker 支撑 Tuwunel homeserver 运行 Matrix 实时 QA 通道。仅限源码检出,打包安装不会随附 `qa-lab`。 - - 完整 CLI、profile/场景目录、环境变量和工件布局:[Matrix QA](/zh-CN/concepts/qa-matrix)。 + - 针对一次性 Docker 支持的 Tuwunel homeserver 运行 Matrix 实时 QA 通道。仅源代码检出可用 — 打包安装不会发布 `qa-lab`。 + - 完整 CLI、profile/场景目录、环境变量和构件布局:[Matrix QA](/zh-CN/concepts/qa-matrix)。 - `pnpm openclaw qa telegram` - - 使用来自环境变量的 driver 和 SUT bot token,针对真实私有群组运行 Telegram 实时 QA 通道。 + - 使用来自环境的 driver 和 SUT bot token,针对真实私有群组运行 Telegram 实时 QA 通道。 - 需要 `OPENCLAW_QA_TELEGRAM_GROUP_ID`、`OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKEN` 和 `OPENCLAW_QA_TELEGRAM_SUT_BOT_TOKEN`。群组 id 必须是数字 Telegram chat id。 - - 支持 `--credential-source convex` 以使用共享池化凭证。默认使用环境变量模式,或设置 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex` 选择池化租约。 - - 任何场景失败时以非零状态退出。如果你想获取工件但不希望退出码失败,请使用 `--allow-failures`。 - - 需要同一私有群组中的两个不同 bot,且 SUT bot 需公开 Telegram username。 - - 为了获得稳定的 bot 对 bot 观测,请在 `@BotFather` 中为两个 bot 启用 Bot-to-Bot Communication Mode,并确保 driver bot 可以观测群组 bot 流量。 - - 在 `.artifacts/qa-e2e/...` 下写入 Telegram QA 报告、摘要和 observed-messages 工件。回复场景包含从 driver 发送请求到观测到 SUT 回复的 RTT。 + - 支持用于共享池化凭证的 `--credential-source convex`。默认使用环境模式,或设置 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex` 以启用池化租约。 + - 任何场景失败时以非零状态退出。当你想获取构件但不希望失败退出码时,使用 `--allow-failures`。 + - 需要同一私有群组中的两个不同 bot,并且 SUT bot 需要暴露 Telegram 用户名。 + - 为了获得稳定的 bot 到 bot 观察,请在 `@BotFather` 中为两个 bot 启用 Bot-to-Bot Communication Mode,并确保 driver bot 可以观察群组 bot 流量。 + - 在 `.artifacts/qa-e2e/...` 下写入 Telegram QA 报告、摘要和 observed-messages 构件。回复场景包含从 driver 发送请求到观察到 SUT 回复的 RTT。 -实时传输通道共享一个标准契约,确保新传输不会漂移;每通道覆盖矩阵位于 [QA overview → 实时传输覆盖](/zh-CN/concepts/qa-e2e-automation#live-transport-coverage)。`qa-channel` 是广泛的合成套件,不属于该矩阵。 +实时传输通道共享一个标准契约,以防新传输发生偏移;每通道覆盖矩阵位于 [QA overview → 实时传输覆盖](/zh-CN/concepts/qa-e2e-automation#live-transport-coverage)。`qa-channel` 是广泛的合成套件,不属于该矩阵。 ### 通过 Convex 共享 Telegram 凭证(v1) -当为 `openclaw qa telegram` 启用 `--credential-source convex`(或 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex`)时,QA lab 会从 Convex 支撑的池中获取一个独占租约,在通道运行期间对该租约发送 Heartbeat,并在关闭时释放租约。 +当为 `openclaw qa telegram` 启用 `--credential-source convex`(或 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex`)时,QA lab 会从 Convex 支持的池中获取独占租约,在通道运行期间对该租约发送 Heartbeat,并在关闭时释放租约。 参考 Convex 项目脚手架: @@ -231,12 +232,12 @@ gh workflow run package-acceptance.yml --ref main \ 必需环境变量: - `OPENCLAW_QA_CONVEX_SITE_URL`(例如 `https://your-deployment.convex.site`) -- 所选角色的一个 secret: +- 所选角色的一个密钥: - `OPENCLAW_QA_CONVEX_SECRET_MAINTAINER` 用于 `maintainer` - `OPENCLAW_QA_CONVEX_SECRET_CI` 用于 `ci` - 凭证角色选择: - CLI:`--credential-role maintainer|ci` - - 环境变量默认值:`OPENCLAW_QA_CREDENTIAL_ROLE`(在 CI 中默认为 `ci`,否则为 `maintainer`) + - 环境默认值:`OPENCLAW_QA_CREDENTIAL_ROLE`(CI 中默认为 `ci`,否则为 `maintainer`) 可选环境变量: @@ -248,11 +249,11 @@ gh workflow run package-acceptance.yml --ref main \ - `OPENCLAW_QA_CREDENTIAL_OWNER_ID`(可选 trace id) - `OPENCLAW_QA_ALLOW_INSECURE_HTTP=1` 允许仅用于本地开发的 loopback `http://` Convex URL。 -`OPENCLAW_QA_CONVEX_SITE_URL` 在正常操作中应使用 `https://`。 +正常运行时,`OPENCLAW_QA_CONVEX_SITE_URL` 应使用 `https://`。 -Maintainer 管理命令(池 add/remove/list)特别需要 `OPENCLAW_QA_CONVEX_SECRET_MAINTAINER`。 +维护者管理员命令(池 add/remove/list)需要专门使用 `OPENCLAW_QA_CONVEX_SECRET_MAINTAINER`。 -供 maintainer 使用的 CLI helper: +维护者 CLI helper: ```bash pnpm openclaw qa credentials doctor @@ -261,153 +262,124 @@ pnpm openclaw qa credentials list --kind telegram pnpm openclaw qa credentials remove --credential-id ``` -在实时运行前使用 `doctor` 检查 Convex 站点 URL、broker secret、端点前缀、HTTP timeout,以及 admin/list 可达性,并且不会打印 secret 值。在脚本和 CI 工具中使用 `--json` 获取机器可读输出。 +在实时运行前使用 `doctor` 检查 Convex site URL、broker 密钥、endpoint prefix、HTTP timeout 和 admin/list 可达性,且不会打印密钥值。在脚本和 CI 工具中使用 `--json` 获取机器可读输出。 默认端点契约(`OPENCLAW_QA_CONVEX_SITE_URL` + `/qa-credentials/v1`): - `POST /acquire` - 请求:`{ kind, ownerId, actorRole, leaseTtlMs, heartbeatIntervalMs }` - 成功:`{ status: "ok", credentialId, leaseToken, payload, leaseTtlMs?, heartbeatIntervalMs? }` - - 已耗尽/可重试:`{ status: "error", code: "POOL_EXHAUSTED" | "NO_CREDENTIAL_AVAILABLE", ... }` + - 耗尽/可重试:`{ status: "error", code: "POOL_EXHAUSTED" | "NO_CREDENTIAL_AVAILABLE", ... }` - `POST /heartbeat` - 请求:`{ kind, ownerId, actorRole, credentialId, leaseToken, leaseTtlMs }` - - 成功:`{ status: "ok" }`(或空 `2xx`) + - 成功:`{ status: "ok" }`(或空的 `2xx`) - `POST /release` - 请求:`{ kind, ownerId, actorRole, credentialId, leaseToken }` - - 成功:`{ status: "ok" }`(或空 `2xx`) + - 成功:`{ status: "ok" }`(或空的 `2xx`) - `POST /admin/add`(仅维护者密钥) - 请求:`{ kind, actorId, payload, note?, status? }` - 成功:`{ status: "ok", credential }` - `POST /admin/remove`(仅维护者密钥) - 请求:`{ credentialId, actorId }` - 成功:`{ status: "ok", changed, credential }` - - 活动租约保护:`{ status: "error", code: "LEASE_ACTIVE", ... }` + - 活跃租约保护:`{ status: "error", code: "LEASE_ACTIVE", ... }` - `POST /admin/list`(仅维护者密钥) - 请求:`{ kind?, status?, includePayload?, limit? }` - 成功:`{ status: "ok", credentials, count }` -Telegram 类型的载荷结构: +Telegram 类型的载荷形状: - `{ groupId: string, driverToken: string, sutToken: string }` - `groupId` 必须是数字形式的 Telegram 聊天 ID 字符串。 -- `admin/add` 会为 `kind: "telegram"` 验证此结构,并拒绝格式错误的载荷。 +- `admin/add` 会对 `kind: "telegram"` 校验此形状,并拒绝格式错误的载荷。 -### 将渠道添加到 QA +### 向 QA 添加渠道 -新渠道适配器的架构和场景辅助工具名称位于 [QA overview → 添加渠道](/zh-CN/concepts/qa-e2e-automation#adding-a-channel)。最低要求:在共享的 `qa-lab` 主机衔接层上实现传输运行器,在插件清单中声明 `qaRunners`,挂载为 `openclaw qa `,并在 `qa/scenarios/` 下编写场景。 +新渠道适配器的架构和场景辅助函数名称位于 [QA overview → 添加渠道](/zh-CN/concepts/qa-e2e-automation#adding-a-channel)。最低要求:在共享 `qa-lab` 主机接缝上实现传输运行器,在插件清单中声明 `qaRunners`,挂载为 `openclaw qa `,并在 `qa/scenarios/` 下编写场景。 -## 测试套件(在哪运行什么) +## 测试套件(哪里运行什么) -可以把这些套件理解为“真实度逐步提高”(不稳定性/成本也逐步提高): +可以把这些套件理解为“真实度逐步提高”(同时脆弱性/成本也逐步提高): ### 单元 / 集成(默认) - 命令:`pnpm test` -- 配置:非定向运行使用 `vitest.full-*.config.ts` 分片集,并且可能会将多项目分片展开成按项目配置,以便并行调度 -- 文件:`src/**/*.test.ts`、`packages/**/*.test.ts` 和 `test/**/*.test.ts` 下的核心/单元清单;UI 单元测试在专用的 `unit-ui` 分片中运行 +- 配置:未定向运行使用 `vitest.full-*.config.ts` 分片集合,并且可能会将多项目分片展开为按项目划分的配置,以便并行调度 +- 文件:`src/**/*.test.ts`、`packages/**/*.test.ts` 和 `test/**/*.test.ts` 下的核心/单元清单;UI 单元测试在专用 `unit-ui` 分片中运行 - 范围: - 纯单元测试 - 进程内集成测试(Gateway 网关认证、路由、工具、解析、配置) - - 已知错误的确定性回归测试 + - 已知 bug 的确定性回归测试 - 预期: - 在 CI 中运行 - 不需要真实密钥 - - 应当快速且稳定 - - 解析器和公开表面加载器测试必须用生成的极小插件测试夹具证明宽泛 `api.js` 和 - `runtime-api.js` 的回退行为,而不是使用真实内置插件源码 API。真实插件 API 加载应放在 - 插件拥有的契约/集成套件中。 + - 应该快速且稳定 + - 解析器和公共表面加载器测试必须使用生成的微型插件夹具来证明宽泛的 `api.js` 和 + `runtime-api.js` 回退行为,而不是使用真实内置插件源 API。真实插件 API 加载应放在 + 插件自有的契约/集成套件中。 - + - - 非定向 `pnpm test` 会运行十二个更小的分片配置(`core-unit-fast`、`core-unit-src`、`core-unit-security`、`core-unit-ui`、`core-unit-support`、`core-support-boundary`、`core-contracts`、`core-bundled`、`core-runtime`、`agentic`、`auto-reply`、`extensions`),而不是一个巨大的原生根项目进程。这会降低负载较高机器上的 RSS 峰值,并避免 auto-reply/插件工作挤占无关套件。 - - `pnpm test --watch` 仍然使用原生根 `vitest.config.ts` 项目图,因为多分片 watch 循环不实用。 - - `pnpm test`、`pnpm test:watch` 和 `pnpm test:perf:imports` 会先将显式文件/目录目标通过作用域通道路由,因此 `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` 可避免承担完整根项目启动开销。 - - `pnpm test:changed` 默认会将变更的 git 路径展开成低成本作用域通道:直接的测试编辑、同级 `*.test.ts` 文件、显式源映射,以及本地导入图依赖方。配置/设置/package 编辑不会广泛运行测试,除非你显式使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`。 - - `pnpm check:changed` 是窄范围工作的常规智能本地检查门禁。它会将 diff 分类为核心、核心测试、插件、插件测试、应用、文档、发布元数据、live Docker 工具和工具链,然后运行匹配的类型检查、lint 和保护命令。它不会运行 Vitest 测试;如需测试证明,请调用 `pnpm test:changed` 或显式的 `pnpm test `。仅涉及发布元数据的版本提升会运行定向版本/配置/根依赖检查,并带有一个保护检查,拒绝顶层 version 字段之外的 package 变更。 - - Live Docker ACP harness 编辑会运行聚焦检查:live Docker 认证脚本的 shell 语法和 live Docker 调度器演练。只有当 diff 限于 `scripts["test:docker:live-*"]` 时,才会包含 `package.json` 变更;依赖、导出、版本以及其他 package 表面编辑仍然使用更广泛的保护检查。 - - 来自智能体、命令、插件、auto-reply 辅助工具、`plugin-sdk` 和类似纯工具区域的导入较轻单元测试会通过 `unit-fast` 通道路由,该通道会跳过 `test/setup-openclaw-runtime.ts`;有状态/运行时较重的文件保留在现有通道上。 - - 选定的 `plugin-sdk` 和 `commands` 辅助源文件也会把变更模式运行映射到这些轻量通道中的显式同级测试,因此辅助工具编辑不必为该目录重新运行完整的重型套件。 - - `auto-reply` 为顶层核心辅助工具、顶层 `reply.*` 集成测试和 `src/auto-reply/reply/**` 子树设置了专用桶。CI 还会把 reply 子树进一步拆分为 agent-runner、dispatch 和 commands/state-routing 分片,因此一个导入较重的桶不会独占完整 Node 尾部开销。 - - 常规 PR/main CI 会有意跳过插件批量扫测和仅发布时运行的 `agentic-plugins` 分片。完整发布验证会为发布候选版本上的这些插件较重套件调度单独的插件预发布子工作流。 + - 未定向的 `pnpm test` 会运行十二个更小的分片配置(`core-unit-fast`、`core-unit-src`、`core-unit-security`、`core-unit-ui`、`core-unit-support`、`core-support-boundary`、`core-contracts`、`core-bundled`、`core-runtime`、`agentic`、`auto-reply`、`extensions`),而不是一个巨大的原生根项目进程。这会降低高负载机器上的峰值 RSS,并避免 auto-reply/插件工作让无关套件资源不足。 + - `pnpm test --watch` 仍使用原生根 `vitest.config.ts` 项目图,因为多分片 watch 循环并不实用。 + - `pnpm test`、`pnpm test:watch` 和 `pnpm test:perf:imports` 会先通过范围化通道路由显式文件/目录目标,因此 `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` 可避免支付完整根项目启动成本。 + - `pnpm test:changed` 默认会把已变更的 git 路径展开为廉价的范围化通道:直接测试编辑、同级 `*.test.ts` 文件、显式源映射和本地导入图依赖项。配置/设置/包编辑不会广泛运行测试,除非你显式使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`。 + - `pnpm check:changed` 是窄范围工作的常规智能本地检查门禁。它会把差异分类为核心、核心测试、插件、插件测试、应用、文档、发布元数据、实时 Docker 工具和工具链,然后运行匹配的类型检查、lint 和保护命令。它不会运行 Vitest 测试;要获得测试证明,请调用 `pnpm test:changed` 或显式的 `pnpm test `。仅发布元数据的版本升级会运行定向版本/配置/根依赖检查,并带有一个保护,用于拒绝顶层版本字段之外的包变更。 + - 实时 Docker ACP harness 编辑会运行聚焦检查:实时 Docker 认证脚本的 shell 语法,以及实时 Docker 调度器 dry-run。只有当差异限定在 `scripts["test:docker:live-*"]` 时才包含 `package.json` 变更;依赖、导出、版本和其他包表面编辑仍使用更广泛的保护。 + - 来自 agents、commands、plugins、auto-reply 辅助函数、`plugin-sdk` 和类似纯工具区域的轻导入单元测试会通过 `unit-fast` 通道,该通道跳过 `test/setup-openclaw-runtime.ts`;有状态/运行时较重的文件仍保留在现有通道上。 + - 选定的 `plugin-sdk` 和 `commands` 辅助源文件也会在 changed 模式运行时映射到这些轻量通道中的显式同级测试,因此辅助函数编辑无需重新运行该目录的完整重型套件。 + - `auto-reply` 为顶层核心辅助函数、顶层 `reply.*` 集成测试和 `src/auto-reply/reply/**` 子树提供了专用分组。CI 还会将 reply 子树进一步拆分为 agent-runner、dispatch 和 commands/state-routing 分片,避免某个导入繁重的分组独占完整 Node 尾部时间。 + - 普通 PR/main CI 会有意跳过插件批量扫测和仅发布使用的 `agentic-plugins` 分片。完整发布验证会为发布候选触发单独的 `Plugin Prerelease` 子工作流,用于这些插件/插件密集型套件。 - - 当你更改消息工具发现输入或压缩运行时 - 上下文时,请保留两层覆盖。 - - 为纯路由和规范化 - 边界添加聚焦的辅助函数回归测试。 + - 当你更改消息工具发现输入或压缩运行时上下文时,请保留两层覆盖。 + - 为纯路由和规范化边界添加聚焦的辅助函数回归测试。 - 保持嵌入式运行器集成套件健康: `src/agents/pi-embedded-runner/compact.hooks.test.ts`、 `src/agents/pi-embedded-runner/run.overflow-compaction.test.ts` 和 `src/agents/pi-embedded-runner/run.overflow-compaction.loop.test.ts`。 - - 这些套件会验证作用域 ID 和压缩行为仍然流经 - 真实 `run.ts` / `compact.ts` 路径;仅辅助函数测试 - 不足以替代这些集成路径。 + - 这些套件会验证范围化 ID 和压缩行为仍通过真实的 `run.ts` / `compact.ts` 路径流动;仅辅助函数测试并不足以替代这些集成路径。 - 基础 Vitest 配置默认使用 `threads`。 - - 共享 Vitest 配置固定 `isolate: false`,并在根项目、E2E 和 live 配置中使用 - 非隔离运行器。 - - 根 UI 通道保留其 `jsdom` 设置和优化器,但也运行在 - 共享的非隔离运行器上。 - - 每个 `pnpm test` 分片都会从共享 Vitest 配置继承相同的 `threads` + `isolate: false` - 默认值。 - - `scripts/run-vitest.mjs` 默认会为 Vitest 子 Node - 进程添加 `--no-maglev`,以减少大型本地运行期间的 V8 编译抖动。 - 设置 `OPENCLAW_VITEST_ENABLE_MAGLEV=1` 可与原生 V8 - 行为进行比较。 + - 共享 Vitest 配置固定 `isolate: false`,并在根项目、e2e 和实时配置中使用非隔离运行器。 + - 根 UI 通道保留其 `jsdom` 设置和优化器,但也运行在共享的非隔离运行器上。 + - 每个 `pnpm test` 分片都从共享 Vitest 配置继承相同的 `threads` + `isolate: false` 默认值。 + - `scripts/run-vitest.mjs` 默认会为 Vitest 子 Node 进程添加 `--no-maglev`,以降低大型本地运行期间的 V8 编译抖动。设置 `OPENCLAW_VITEST_ENABLE_MAGLEV=1` 可与原版 V8 行为比较。 - - `pnpm changed:lanes` 会显示一个 diff 触发哪些架构通道。 - - pre-commit 钩子仅处理格式化。它会重新暂存格式化后的文件, - 不运行 lint、类型检查或测试。 - - 在交接或 push 前需要智能本地检查门禁时,请显式运行 `pnpm check:changed`。 - - `pnpm test:changed` 默认会通过低成本作用域通道路由。仅当智能体 - 判断 harness、配置、package 或契约编辑确实需要更广泛的 - Vitest 覆盖时,才使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`。 - - `pnpm test:max` 和 `pnpm test:changed:max` 保持相同的路由 - 行为,只是使用更高的 worker 上限。 - - 本地 worker 自动扩缩有意保持保守,并会在主机负载均值已经较高时 - 回退,因此多个并发 Vitest 运行默认造成的影响更小。 - - 基础 Vitest 配置会将项目/配置文件标记为 - `forceRerunTriggers`,因此当测试布线发生变化时,变更模式重新运行仍然正确。 - - 配置会在受支持的主机上保持启用 `OPENCLAW_VITEST_FS_MODULE_CACHE`; - 如果你想为直接剖析使用一个显式缓存位置,请设置 `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path`。 + - `pnpm changed:lanes` 会显示某个差异触发哪些架构通道。 + - pre-commit 钩子只做格式化。它会重新暂存已格式化的文件,不会运行 lint、类型检查或测试。 + - 当你需要智能本地检查门禁时,请在交接或推送前显式运行 `pnpm check:changed`。 + - `pnpm test:changed` 默认会通过廉价的范围化通道路由。仅当智能体判断某个 harness、配置、包或契约编辑确实需要更广泛的 Vitest 覆盖时,才使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`。 + - `pnpm test:max` 和 `pnpm test:changed:max` 保持相同的路由行为,只是 worker 上限更高。 + - 本地 worker 自动扩缩容有意保持保守,并会在主机平均负载已经很高时退避,因此多个并发 Vitest 运行默认会造成更少损害。 + - 基础 Vitest 配置将项目/配置文件标记为 `forceRerunTriggers`,因此测试接线变化时 changed 模式重新运行仍保持正确。 + - 配置会在受支持主机上保持启用 `OPENCLAW_VITEST_FS_MODULE_CACHE`;如果你希望为直接性能分析使用一个显式缓存位置,请设置 `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path`。 - - `pnpm test:perf:imports` 会启用 Vitest 导入耗时报告以及 - 导入分解输出。 - - `pnpm test:perf:imports:changed` 会将同一剖析视图限定到 - 自 `origin/main` 以来变更的文件。 + - `pnpm test:perf:imports` 会启用 Vitest 导入耗时报告以及导入分解输出。 + - `pnpm test:perf:imports:changed` 会将同一性能分析视图限定到自 `origin/main` 以来变更的文件。 - 分片计时数据会写入 `.artifacts/vitest-shard-timings.json`。 - 整配置运行使用配置路径作为键;include-pattern CI - 分片会追加分片名称,以便单独跟踪过滤后的分片。 - - 当某个热点测试仍然把大部分时间花在启动导入上时, - 请把重依赖放在狭窄本地 `*.runtime.ts` 衔接层后面,并 - 直接 mock 该衔接层,而不是仅为传给 `vi.mock(...)` - 而深度导入运行时辅助函数。 - - `pnpm test:perf:changed:bench -- --ref ` 会对该已提交 - diff 比较路由后的 `test:changed` 与原生根项目路径, - 并打印墙钟时间以及 macOS 最大 RSS。 - - `pnpm test:perf:changed:bench -- --worktree` 会通过 - `scripts/test-projects.mjs` 和根 Vitest 配置路由变更文件列表, - 对当前脏工作树进行基准测试。 - - `pnpm test:perf:profile:main` 会为 Vitest/Vite 启动和转换开销 - 写入主线程 CPU profile。 - - `pnpm test:perf:profile:runner` 会在禁用文件并行的情况下,为 - 单元套件写入 runner CPU+heap profile。 + 整配置运行使用配置路径作为键;include-pattern CI 分片会追加分片名称,以便单独跟踪过滤后的分片。 + - 当某个热点测试仍把大部分时间花在启动导入上时,请把重型依赖放在窄本地 `*.runtime.ts` 接缝后面,并直接 mock 该接缝,而不是深度导入运行时辅助函数只为把它们传给 `vi.mock(...)`。 + - `pnpm test:perf:changed:bench -- --ref ` 会比较已提交差异对应的已路由 `test:changed` 与原生根项目路径,并打印墙钟时间和 macOS 最大 RSS。 + - `pnpm test:perf:changed:bench -- --worktree` 会通过 `scripts/test-projects.mjs` 和根 Vitest 配置路由已变更文件列表,从而对当前脏工作树做基准测试。 + - `pnpm test:perf:profile:main` 会为 Vitest/Vite 启动和转换开销写入主线程 CPU profile。 + - `pnpm test:perf:profile:runner` 会在禁用文件并行的情况下,为单元套件写入运行器 CPU+堆 profile。 @@ -417,248 +389,211 @@ Telegram 类型的载荷结构: - 命令:`pnpm test:stability:gateway` - 配置:`vitest.gateway.config.ts`,强制使用一个 worker - 范围: - - 启动一个默认启用诊断的真实回环 Gateway 网关 - - 通过诊断事件路径驱动合成 Gateway 网关消息、内存和大载荷变动 + - 启动一个真实的 loopback Gateway 网关,默认启用诊断 + - 通过诊断事件路径驱动合成的 Gateway 网关消息、记忆和大载荷抖动 - 通过 Gateway 网关 WS RPC 查询 `diagnostics.stability` - - 覆盖诊断稳定性 bundle 持久化辅助函数 - - 断言记录器保持有界、合成 RSS 样本保持在压力预算以下,并且每会话队列深度回落到零 + - 覆盖诊断稳定性包持久化辅助函数 + - 断言记录器保持有界、合成 RSS 样本保持在压力预算以内,并且每个会话的队列深度都会排空回零 - 预期: - - 可在 CI 安全运行且无需密钥 - - 用于稳定性回归跟进的窄通道,不能替代完整 Gateway 网关套件 + - CI 安全且无需密钥 + - 用于稳定性回归跟进的窄通道,而不是完整 Gateway 网关套件的替代品 -### E2E(Gateway 网关烟雾测试) +### E2E(Gateway 网关冒烟) - 命令:`pnpm test:e2e` - 配置:`vitest.e2e.config.ts` - 文件:`src/**/*.e2e.test.ts`、`test/**/*.e2e.test.ts`,以及 `extensions/` 下的内置插件 E2E 测试 - 运行时默认值: - - 使用 Vitest `threads` 且 `isolate: false`,与仓库其他部分一致。 - - 使用自适应 worker(CI:最多 2 个,本地:默认 1 个)。 - - 默认以 silent 模式运行,以减少控制台 I/O 开销。 -- 常用覆盖项: + - 使用 Vitest `threads` 和 `isolate: false`,与仓库其余部分一致。 + - 使用自适应 worker(CI:最多 2 个;本地:默认 1 个)。 + - 默认以静默模式运行,以减少控制台 I/O 开销。 +- 有用的覆盖项: - `OPENCLAW_E2E_WORKERS=` 用于强制 worker 数量(上限为 16)。 - `OPENCLAW_E2E_VERBOSE=1` 用于重新启用详细控制台输出。 - 范围: - 多实例 Gateway 网关端到端行为 - - WebSocket/HTTP 表面、节点配对和更重的网络场景 + - WebSocket/HTTP 表面、节点配对和更重的网络 - 预期: - 在 CI 中运行(当流水线启用时) - 不需要真实密钥 - 比单元测试有更多移动部件(可能更慢) -### E2E:OpenShell 后端烟雾测试 +### E2E:OpenShell 后端冒烟 - 命令:`pnpm test:e2e:openshell` - 文件:`extensions/openshell/src/backend.e2e.test.ts` - 范围: - 通过 Docker 在主机上启动一个隔离的 OpenShell Gateway 网关 - 从临时本地 Dockerfile 创建一个沙箱 - - 通过真实的 `sandbox ssh-config` + SSH exec 运行 OpenClaw 的 OpenShell 后端 - - 通过沙箱 fs 桥接验证远程规范化文件系统行为 + - 通过真实的 `sandbox ssh-config` + SSH exec 测试 OpenClaw 的 OpenShell 后端 + - 通过沙箱 fs 桥接验证远程规范文件系统行为 - 预期: - - 仅限主动启用;不是默认 `pnpm test:e2e` 运行的一部分 - - 需要本地 `openshell` CLI 以及可用的 Docker 守护进程 + - 仅按需启用;不属于默认 `pnpm test:e2e` 运行的一部分 + - 需要本地 `openshell` CLI 和可用的 Docker 守护进程 - 使用隔离的 `HOME` / `XDG_CONFIG_HOME`,然后销毁测试 Gateway 网关和沙箱 - 有用的覆盖项: - - `OPENCLAW_E2E_OPENSHELL=1`,在手动运行更广泛的 e2e 套件时启用该测试 - - `OPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshell`,指向非默认 CLI 二进制文件或包装脚本 + - `OPENCLAW_E2E_OPENSHELL=1` 用于在手动运行更广泛的 e2e 套件时启用该测试 + - `OPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshell` 用于指向非默认 CLI 二进制文件或包装脚本 -### 现场测试(真实提供商 + 真实模型) +### 实时(真实提供商 + 真实模型) - 命令:`pnpm test:live` - 配置:`vitest.live.config.ts` -- 文件:`src/**/*.live.test.ts`、`test/**/*.live.test.ts`,以及 `extensions/` 下的内置插件现场测试 -- 默认值:由 `pnpm test:live` **启用**(设置 `OPENCLAW_LIVE_TEST=1`) +- 文件:`src/**/*.live.test.ts`、`test/**/*.live.test.ts`,以及 `extensions/` 下的内置插件实时测试 +- 默认:通过 `pnpm test:live` **启用**(设置 `OPENCLAW_LIVE_TEST=1`) - 范围: - - “这个提供商/模型在 _今天_ 使用真实凭证是否真的可用?” - - 捕获提供商格式变化、工具调用差异、认证问题和速率限制行为 + - “这个提供商/模型在_今天_使用真实凭证时是否真的可用?” + - 捕获提供商格式变化、工具调用细节、认证问题和速率限制行为 - 预期: - - 按设计并非 CI 稳定(真实网络、真实提供商策略、配额、故障) - - 会产生成本 / 使用速率限制 - - 优先运行缩小范围的子集,而不是“全部” -- 现场运行会 source `~/.profile` 以获取缺失的 API key。 -- 默认情况下,现场运行仍会隔离 `HOME`,并将配置/认证材料复制到临时测试 home 中,以免单元测试夹具修改你真实的 `~/.openclaw`。 -- 仅在你有意需要现场测试使用真实 home 目录时,才设置 `OPENCLAW_LIVE_USE_REAL_HOME=1`。 -- `pnpm test:live` 现在默认使用更安静的模式:它保留 `[live] ...` 进度输出,但抑制额外的 `~/.profile` 提示,并静默 Gateway 网关引导日志/Bonjour 噪声。如果你希望恢复完整启动日志,请设置 `OPENCLAW_LIVE_TEST_QUIET=0`。 -- API key 轮换(按提供商):设置带逗号/分号格式的 `*_API_KEYS`,或设置 `*_API_KEY_1`、`*_API_KEY_2`(例如 `OPENAI_API_KEYS`、`ANTHROPIC_API_KEYS`、`GEMINI_API_KEYS`),也可以通过 `OPENCLAW_LIVE_*_KEY` 为单次现场运行覆盖;测试会在速率限制响应时重试。 + - 设计上不保证 CI 稳定(真实网络、真实提供商策略、配额、故障) + - 会产生费用 / 使用速率限制额度 + - 优先运行缩小后的子集,而不是“所有内容” +- 实时运行会 source `~/.profile` 以获取缺失的 API key。 +- 默认情况下,实时运行仍会隔离 `HOME`,并将配置/认证材料复制到临时测试主目录中,这样单元夹具就无法修改你真实的 `~/.openclaw`。 +- 只有在你有意需要实时测试使用真实主目录时,才设置 `OPENCLAW_LIVE_USE_REAL_HOME=1`。 +- `pnpm test:live` 现在默认使用更安静的模式:它保留 `[live] ...` 进度输出,但会抑制额外的 `~/.profile` 提示,并静默 Gateway 网关启动日志/Bonjour 噪声。如果你想恢复完整启动日志,请设置 `OPENCLAW_LIVE_TEST_QUIET=0`。 +- API key 轮换(按提供商区分):设置带逗号/分号格式的 `*_API_KEYS`,或 `*_API_KEY_1`、`*_API_KEY_2`(例如 `OPENAI_API_KEYS`、`ANTHROPIC_API_KEYS`、`GEMINI_API_KEYS`),也可以通过 `OPENCLAW_LIVE_*_KEY` 做单次实时覆盖;测试会在收到速率限制响应时重试。 - 进度/Heartbeat 输出: - - 现场套件现在会向 stderr 发出进度行,因此即使 Vitest 控制台捕获较安静,长时间的提供商调用也能显示为活跃状态。 - - `vitest.live.config.ts` 禁用 Vitest 控制台拦截,因此在现场运行期间,提供商/Gateway 网关进度行会立即流式输出。 - - 使用 `OPENCLAW_LIVE_HEARTBEAT_MS` 调整直连模型 Heartbeat。 + - 实时套件现在会向 stderr 发出进度行,因此即使 Vitest 控制台捕获很安静,长时间的提供商调用也能明显看到仍在活动。 + - `vitest.live.config.ts` 禁用 Vitest 控制台拦截,因此提供商/Gateway 网关进度行会在实时运行期间立即流式输出。 + - 使用 `OPENCLAW_LIVE_HEARTBEAT_MS` 调整直接模型 Heartbeat。 - 使用 `OPENCLAW_LIVE_GATEWAY_HEARTBEAT_MS` 调整 Gateway 网关/探测 Heartbeat。 ## 我应该运行哪个套件? -使用这张决策表: +使用此决策表: -- 编辑逻辑/测试:运行 `pnpm test`(如果你改动很多,也运行 `pnpm test:coverage`) +- 编辑逻辑/测试:运行 `pnpm test`(如果改动很多,也运行 `pnpm test:coverage`) - 触及 Gateway 网关网络 / WS 协议 / 配对:添加 `pnpm test:e2e` -- 调试“我的 bot 挂了” / 提供商特定故障 / 工具调用:运行缩小范围的 `pnpm test:live` +- 调试“我的机器人宕机了” / 提供商特定故障 / 工具调用:运行缩小后的 `pnpm test:live` -## 现场(触网)测试 +## 实时(触网)测试 -关于现场模型矩阵、CLI 后端 smoke、ACP smoke、Codex app-server -harness,以及所有媒体提供商现场测试(Deepgram、BytePlus、ComfyUI、image、 -music、video、media harness),以及现场运行的凭证处理,请参阅 -[现场套件测试](/zh-CN/help/testing-live)。关于专用更新和 +关于实时模型矩阵、CLI 后端冒烟、ACP 冒烟、Codex 应用服务器 +harness,以及所有媒体提供商实时测试(Deepgram、BytePlus、ComfyUI、图像、 +音乐、视频、媒体 harness),再加上实时运行的凭证处理,请参阅 +[实时套件测试](/zh-CN/help/testing-live)。关于专用的更新和 插件验证清单,请参阅 [更新和插件测试](/zh-CN/help/testing-updates-plugins)。 -## Docker 运行器(可选的“在 Linux 中可用”检查) +## Docker 运行器(可选的“在 Linux 中工作”检查) 这些 Docker 运行器分为两类: -- 现场模型运行器:`test:docker:live-models` 和 `test:docker:live-gateway` 只在仓库 Docker 镜像内运行它们匹配 profile-key 的现场文件(`src/agents/models.profiles.live.test.ts` 和 `src/gateway/gateway-models.profiles.live.test.ts`),挂载你的本地配置目录和工作区(如果已挂载,也会 source `~/.profile`)。匹配的本地入口点是 `test:live:models-profiles` 和 `test:live:gateway-profiles`。 -- Docker 现场运行器默认使用较小的 smoke 上限,以便完整 Docker 扫描保持实用: +- 实时模型运行器:`test:docker:live-models` 和 `test:docker:live-gateway` 只会在仓库 Docker 镜像内运行与其匹配的 profile-key 实时文件(`src/agents/models.profiles.live.test.ts` 和 `src/gateway/gateway-models.profiles.live.test.ts`),并挂载你的本地配置目录和工作区(如果已挂载,也会 source `~/.profile`)。匹配的本地入口点是 `test:live:models-profiles` 和 `test:live:gateway-profiles`。 +- Docker 实时运行器默认使用较小的冒烟上限,让完整 Docker 扫描保持实用: `test:docker:live-models` 默认使用 `OPENCLAW_LIVE_MAX_MODELS=12`,并且 `test:docker:live-gateway` 默认使用 `OPENCLAW_LIVE_GATEWAY_SMOKE=1`、 `OPENCLAW_LIVE_GATEWAY_MAX_MODELS=8`、 `OPENCLAW_LIVE_GATEWAY_STEP_TIMEOUT_MS=45000` 和 - `OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=90000`。只有在你明确希望进行更大的穷尽扫描时,才覆盖这些环境变量。 -- `test:docker:all` 通过 `test:docker:live-build` 构建一次现场 Docker 镜像,通过 `scripts/package-openclaw-for-docker.mjs` 将 OpenClaw 打包一次为 npm tarball,然后构建/复用两个 `scripts/e2e/Dockerfile` 镜像。裸镜像只是用于安装/更新/插件依赖 lane 的 Node/Git 运行器;这些 lane 会挂载预构建的 tarball。功能镜像会将同一个 tarball 安装到 `/app`,用于已构建应用功能 lane。Docker lane 定义位于 `scripts/lib/docker-e2e-scenarios.mjs`;规划器逻辑位于 `scripts/lib/docker-e2e-plan.mjs`;`scripts/test-docker-all.mjs` 执行选定计划。聚合运行使用加权本地调度器:`OPENCLAW_DOCKER_ALL_PARALLELISM` 控制进程槽位,而资源上限防止繁重的现场、npm-install 和多服务 lane 同时全部启动。如果单个 lane 比活动上限更重,调度器仍可在池为空时启动它,然后让它单独运行,直到容量再次可用。默认值为 10 个槽位、`OPENCLAW_DOCKER_ALL_LIVE_LIMIT=9`、`OPENCLAW_DOCKER_ALL_NPM_LIMIT=10` 和 `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7`;只有当 Docker 主机有更多余量时,才调整 `OPENCLAW_DOCKER_ALL_WEIGHT_LIMIT` 或 `OPENCLAW_DOCKER_ALL_DOCKER_LIMIT`。运行器默认执行 Docker 预检,移除陈旧的 OpenClaw E2E 容器,每 30 秒打印一次状态,将成功 lane 的耗时存储在 `.artifacts/docker-tests/lane-timings.json`,并在后续运行中使用这些耗时优先启动更长的 lane。使用 `OPENCLAW_DOCKER_ALL_DRY_RUN=1` 打印加权 lane 清单而不构建或运行 Docker,或使用 `node scripts/test-docker-all.mjs --plan-json` 打印所选 lane、package/image 需求和凭证的 CI 计划。 -- `Package Acceptance` 是 GitHub 原生的 package 门禁,用来验证“这个可安装 tarball 是否能作为产品工作?”它会从 `source=npm`、`source=ref`、`source=url` 或 `source=artifact` 解析一个候选 package,将其上传为 `package-under-test`,然后针对这个精确 tarball 运行可复用 Docker E2E lane,而不是重新打包所选 ref。Profile 按覆盖范围排序:`smoke`、`package`、`product` 和 `full`。关于 package/update/plugin 合约、已发布升级存活矩阵、发布默认值和故障分流,请参阅[更新和插件测试](/zh-CN/help/testing-updates-plugins)。 -- 构建和发布检查会在 tsdown 之后运行 `scripts/check-cli-bootstrap-imports.mjs`。该守卫会从 `dist/entry.js` 和 `dist/cli/run-main.js` 遍历静态构建图,如果命令分派前的启动阶段导入了 Commander、prompt UI、undici 或 logging 等 package 依赖,就会失败;它还会让内置 Gateway 网关运行 chunk 保持在预算内,并拒绝已知冷 Gateway 网关路径的静态导入。打包后的 CLI smoke 还覆盖根帮助、onboard 帮助、doctor 帮助、status、配置 schema 和一个模型列表命令。 -- Package Acceptance 旧版兼容性上限为 `2026.4.25`(包含 `2026.4.25-beta.*`)。在该截止点之前,harness 只容忍已发布 package 的元数据缺口:省略的私有 QA inventory 条目、缺失的 `gateway install --wrapper`、tarball 派生 git 夹具中缺失的 patch 文件、缺失的持久化 `update.channel`、旧版插件安装记录位置、缺失的 marketplace 安装记录持久化,以及 `plugins update` 期间的配置元数据迁移。对于 `2026.4.25` 之后的 package,这些路径都是严格失败。 -- 容器 smoke 运行器:`test:docker:openwebui`、`test:docker:onboard`、`test:docker:npm-onboard-channel-agent`、`test:docker:update-channel-switch`、`test:docker:upgrade-survivor`、`test:docker:published-upgrade-survivor`、`test:docker:session-runtime-context`、`test:docker:agents-delete-shared-workspace`、`test:docker:gateway-network`、`test:docker:browser-cdp-snapshot`、`test:docker:mcp-channels`、`test:docker:pi-bundle-mcp-tools`、`test:docker:cron-mcp-cleanup`、`test:docker:plugins`、`test:docker:plugin-update` 和 `test:docker:config-reload` 会启动一个或多个真实容器,并验证更高层级的集成路径。 + `OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=90000`。只有在你明确需要更大的穷尽扫描时,才覆盖这些环境变量。 +- `test:docker:all` 通过 `test:docker:live-build` 构建一次实时 Docker 镜像,通过 `scripts/package-openclaw-for-docker.mjs` 将 OpenClaw 打包一次为 npm tarball,然后构建/复用两个 `scripts/e2e/Dockerfile` 镜像。裸镜像只是用于安装/更新/插件依赖通道的 Node/Git 运行器;这些通道会挂载预构建 tarball。功能镜像会将同一个 tarball 安装到 `/app`,用于已构建应用的功能通道。Docker 通道定义位于 `scripts/lib/docker-e2e-scenarios.mjs`;规划器逻辑位于 `scripts/lib/docker-e2e-plan.mjs`;`scripts/test-docker-all.mjs` 执行选定计划。聚合运行使用加权本地调度器:`OPENCLAW_DOCKER_ALL_PARALLELISM` 控制进程槽位,而资源上限会避免重型实时、npm-install 和多服务通道同时全部启动。如果单个通道比当前上限更重,调度器仍可在池为空时启动它,然后让它单独运行,直到再次有容量可用。默认值为 10 个槽位、`OPENCLAW_DOCKER_ALL_LIVE_LIMIT=9`、`OPENCLAW_DOCKER_ALL_NPM_LIMIT=10` 和 `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7`;只有在 Docker 主机有更多余量时,才调整 `OPENCLAW_DOCKER_ALL_WEIGHT_LIMIT` 或 `OPENCLAW_DOCKER_ALL_DOCKER_LIMIT`。运行器默认执行 Docker 预检,移除陈旧的 OpenClaw E2E 容器,每 30 秒打印一次状态,将成功通道耗时存储在 `.artifacts/docker-tests/lane-timings.json` 中,并在后续运行中使用这些耗时优先启动更长的通道。使用 `OPENCLAW_DOCKER_ALL_DRY_RUN=1` 可在不构建或运行 Docker 的情况下打印加权通道清单,或者使用 `node scripts/test-docker-all.mjs --plan-json` 打印所选通道、包/镜像需求和凭证的 CI 计划。 +- `Package Acceptance` 是 GitHub 原生的包门禁,用于验证“这个可安装 tarball 是否作为产品可用?”它会从 `source=npm`、`source=ref`、`source=url` 或 `source=artifact` 解析一个候选包,将其上传为 `package-under-test`,然后针对这个精确 tarball 运行可复用的 Docker E2E 通道,而不是重新打包所选 ref。Profile 按覆盖广度排序:`smoke`、`package`、`product` 和 `full`。关于包/更新/插件契约、已发布升级幸存矩阵、发布默认值和失败分诊,请参阅[更新和插件测试](/zh-CN/help/testing-updates-plugins)。 +- 构建和发布检查会在 tsdown 之后运行 `scripts/check-cli-bootstrap-imports.mjs`。该防护会从 `dist/entry.js` 和 `dist/cli/run-main.js` 遍历静态构建图,如果命令分发前的启动导入了 Commander、提示 UI、undici 或日志等包依赖,就会失败;它还会确保打包的 Gateway 网关运行 chunk 保持在预算内,并拒绝已知冷 Gateway 网关路径的静态导入。打包后的 CLI 冒烟还覆盖根帮助、新手引导帮助、Doctor 帮助、Status、配置 schema 和模型列表命令。 +- Package Acceptance 旧版兼容性上限为 `2026.4.25`(包含 `2026.4.25-beta.*`)。在该截止点之前,harness 仅容忍已发布包的元数据缺口:省略的私有 QA 清单条目、缺失的 `gateway install --wrapper`、tarball 派生 git 夹具中缺失的补丁文件、缺失的持久化 `update.channel`、旧版插件安装记录位置、缺失的 marketplace 安装记录持久化,以及 `plugins update` 期间的配置元数据迁移。对于 `2026.4.25` 之后的包,这些路径都是严格失败。 +- 容器冒烟运行器:`test:docker:openwebui`、`test:docker:onboard`、`test:docker:npm-onboard-channel-agent`、`test:docker:update-channel-switch`、`test:docker:upgrade-survivor`、`test:docker:published-upgrade-survivor`、`test:docker:session-runtime-context`、`test:docker:agents-delete-shared-workspace`、`test:docker:gateway-network`、`test:docker:browser-cdp-snapshot`、`test:docker:mcp-channels`、`test:docker:pi-bundle-mcp-tools`、`test:docker:cron-mcp-cleanup`、`test:docker:plugins`、`test:docker:plugin-update` 和 `test:docker:config-reload` 会启动一个或多个真实容器,并验证更高层级的集成路径。 -现场模型 Docker 运行器还只会 bind-mount 所需的 CLI 认证 home(或在运行未缩小时挂载所有受支持的 home),然后在运行前将它们复制到容器 home 中,使外部 CLI OAuth 可以刷新 token,而不修改主机认证存储: +实时模型 Docker 运行器还只会绑定挂载所需的 CLI 认证主目录(或者在运行未缩小时挂载所有支持的主目录),然后在运行前将它们复制到容器主目录中,这样外部 CLI OAuth 就可以刷新令牌,而不会修改主机认证存储: - 直接模型:`pnpm test:docker:live-models`(脚本:`scripts/test-live-models-docker.sh`) -- ACP 绑定冒烟测试:`pnpm test:docker:live-acp-bind`(脚本:`scripts/test-live-acp-bind-docker.sh`;默认覆盖 Claude、Codex 和 Gemini,并通过 `pnpm test:docker:live-acp-bind:droid` 和 `pnpm test:docker:live-acp-bind:opencode` 严格覆盖 Droid/OpenCode) +- ACP 绑定冒烟测试:`pnpm test:docker:live-acp-bind`(脚本:`scripts/test-live-acp-bind-docker.sh`;默认覆盖 Claude、Codex 和 Gemini,并通过 `pnpm test:docker:live-acp-bind:droid` 与 `pnpm test:docker:live-acp-bind:opencode` 严格覆盖 Droid/OpenCode) - CLI 后端冒烟测试:`pnpm test:docker:live-cli-backend`(脚本:`scripts/test-live-cli-backend-docker.sh`) - Codex app-server harness 冒烟测试:`pnpm test:docker:live-codex-harness`(脚本:`scripts/test-live-codex-harness-docker.sh`) - Gateway 网关 + 开发智能体:`pnpm test:docker:live-gateway`(脚本:`scripts/test-live-gateway-models-docker.sh`) -- 可观测性冒烟测试:`pnpm qa:otel:smoke` 是私有 QA 源码检出通道。它有意不属于包 Docker 发布通道,因为 npm tarball 会省略 QA Lab。 -- Open WebUI 实时冒烟测试:`pnpm test:docker:openwebui`(脚本:`scripts/e2e/openwebui-docker.sh`) +- 可观测性冒烟测试:`pnpm qa:otel:smoke` 是一个私有 QA 源码检出通道。它有意不属于 package Docker 发布通道,因为 npm tarball 省略了 QA Lab。 +- Open WebUI 在线冒烟测试:`pnpm test:docker:openwebui`(脚本:`scripts/e2e/openwebui-docker.sh`) - 新手引导向导(TTY,完整脚手架):`pnpm test:docker:onboard`(脚本:`scripts/e2e/onboard-docker.sh`) -- Npm tarball 新手引导/渠道/智能体冒烟测试:`pnpm test:docker:npm-onboard-channel-agent` 会在 Docker 中全局安装打包好的 OpenClaw tarball,通过 env-ref 新手引导配置 OpenAI,并默认配置 Telegram,运行 doctor,然后运行一次模拟的 OpenAI 智能体轮次。可用 `OPENCLAW_CURRENT_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 复用预构建 tarball,用 `OPENCLAW_NPM_ONBOARD_HOST_BUILD=0` 跳过主机重新构建,或用 `OPENCLAW_NPM_ONBOARD_CHANNEL=discord` 切换渠道。 -- 更新渠道切换冒烟测试:`pnpm test:docker:update-channel-switch` 会在 Docker 中全局安装打包好的 OpenClaw tarball,从包 `stable` 切换到 git `dev`,验证持久化的渠道和插件更新后工作正常,然后切回包 `stable` 并检查更新状态。 -- 升级存活冒烟测试:`pnpm test:docker:upgrade-survivor` 会把打包好的 OpenClaw tarball 安装到一个带有智能体、渠道配置、插件 allowlist、陈旧插件依赖状态以及既有工作区/会话文件的脏旧用户夹具上。它会在没有实时提供商或渠道密钥的情况下运行包更新和非交互式 doctor,然后启动一个 loopback Gateway 网关,并检查配置/状态保留以及启动/状态预算。 -- 已发布版本升级存活冒烟测试:`pnpm test:docker:published-upgrade-survivor` 默认安装 `openclaw@latest`,播种真实的既有用户文件,用内置命令配方配置该基线,验证生成的配置,将该已发布安装更新到候选 tarball,运行非交互式 doctor,写入 `.artifacts/upgrade-survivor/summary.json`,然后启动一个 loopback Gateway 网关,并检查已配置意图、状态保留、启动、`/healthz`、`/readyz` 和 RPC 状态预算。可用 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPEC` 覆盖单个基线,让聚合调度器用 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPECS` 展开精确基线,例如 `all-since-2026.4.23`,并用 `OPENCLAW_UPGRADE_SURVIVOR_SCENARIOS` 展开问题形态的夹具,例如 `reported-issues`;reported-issues 集包含 `configured-plugin-installs`,用于自动修复外部 OpenClaw 插件安装。Package Acceptance 将它们公开为 `published_upgrade_survivor_baseline`、`published_upgrade_survivor_baselines` 和 `published_upgrade_survivor_scenarios`。 -- 会话运行时上下文冒烟测试:`pnpm test:docker:session-runtime-context` 会验证隐藏运行时上下文转录持久化,以及 doctor 对受影响的重复 prompt-rewrite 分支的修复。 -- Bun 全局安装冒烟测试:`bash scripts/e2e/bun-global-install-smoke.sh` 会打包当前树,在隔离的 home 中用 `bun install -g` 安装,并验证 `openclaw infer image providers --json` 返回内置图像提供商而不是挂起。可用 `OPENCLAW_BUN_GLOBAL_SMOKE_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 复用预构建 tarball,用 `OPENCLAW_BUN_GLOBAL_SMOKE_HOST_BUILD=0` 跳过主机构建,或用 `OPENCLAW_BUN_GLOBAL_SMOKE_DIST_IMAGE=openclaw-dockerfile-smoke:local` 从已构建的 Docker 镜像复制 `dist/`。 -- 安装器 Docker 冒烟测试:`bash scripts/test-install-sh-docker.sh` 会在它的 root、update 和 direct-npm 容器之间共享一个 npm 缓存。更新冒烟测试默认使用 npm `latest` 作为稳定基线,然后升级到候选 tarball。在本地用 `OPENCLAW_INSTALL_SMOKE_UPDATE_BASELINE=2026.4.22` 覆盖,或在 GitHub 上用 Install Smoke workflow 的 `update_baseline_version` 输入覆盖。非 root 安装器检查会保留隔离的 npm 缓存,确保 root 拥有的缓存条目不会掩盖用户本地安装行为。设置 `OPENCLAW_INSTALL_SMOKE_NPM_CACHE_DIR=/path/to/cache` 可在本地重跑之间复用 root/update/direct-npm 缓存。 -- Install Smoke CI 会用 `OPENCLAW_INSTALL_SMOKE_SKIP_NPM_GLOBAL=1` 跳过重复的 direct-npm 全局更新;需要覆盖直接 `npm install -g` 时,请在本地不带该环境变量运行脚本。 -- 智能体删除共享工作区 CLI 冒烟测试:`pnpm test:docker:agents-delete-shared-workspace`(脚本:`scripts/e2e/agents-delete-shared-workspace-docker.sh`)默认构建根 Dockerfile 镜像,在隔离的容器 home 中播种两个智能体和一个工作区,运行 `agents delete --json`,并验证有效 JSON 以及保留工作区行为。可用 `OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_IMAGE=openclaw-dockerfile-smoke:local OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_SKIP_BUILD=1` 复用 install-smoke 镜像。 -- Gateway 网关联网(两个容器,WS 认证 + health):`pnpm test:docker:gateway-network`(脚本:`scripts/e2e/gateway-network-docker.sh`) -- Browser CDP 快照冒烟测试:`pnpm test:docker:browser-cdp-snapshot`(脚本:`scripts/e2e/browser-cdp-snapshot-docker.sh`)会构建源码 E2E 镜像和一个 Chromium 层,用原始 CDP 启动 Chromium,运行 `browser doctor --deep`,并验证 CDP 角色快照覆盖链接 URL、游标提升的可点击项、iframe refs 和 frame 元数据。 -- OpenAI Responses web_search 最小推理回归测试:`pnpm test:docker:openai-web-search-minimal`(脚本:`scripts/e2e/openai-web-search-minimal-docker.sh`)会通过 Gateway 网关运行模拟的 OpenAI 服务器,验证 `web_search` 将 `reasoning.effort` 从 `minimal` 提升到 `low`,然后强制提供商 schema 拒绝,并检查原始详情出现在 Gateway 网关日志中。 +- Npm tarball 新手引导/渠道/智能体冒烟测试:`pnpm test:docker:npm-onboard-channel-agent` 会在 Docker 中全局安装打包后的 OpenClaw tarball,通过 env-ref 新手引导配置 OpenAI,并默认配置 Telegram,运行 Doctor,然后运行一次模拟的 OpenAI 智能体轮次。使用 `OPENCLAW_CURRENT_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 复用预构建 tarball,使用 `OPENCLAW_NPM_ONBOARD_HOST_BUILD=0` 跳过主机重建,或使用 `OPENCLAW_NPM_ONBOARD_CHANNEL=discord` 切换渠道。 +- 更新渠道切换冒烟测试:`pnpm test:docker:update-channel-switch` 会在 Docker 中全局安装打包后的 OpenClaw tarball,从 package `stable` 切换到 git `dev`,验证持久化的渠道和插件更新后工作正常,然后切回 package `stable` 并检查更新状态。 +- 升级幸存者冒烟测试:`pnpm test:docker:upgrade-survivor` 会把打包后的 OpenClaw tarball 安装到一个脏的旧用户 fixture 上,该 fixture 包含 agents、渠道配置、插件 allowlists、过期插件依赖状态,以及现有工作区/会话文件。它会在没有在线提供商或渠道密钥的情况下运行 package update 和非交互式 Doctor,然后启动一个 loopback Gateway 网关,并检查配置/状态保留以及启动/状态预算。 +- 已发布版本升级幸存者冒烟测试:`pnpm test:docker:published-upgrade-survivor` 默认安装 `openclaw@latest`,播种真实的现有用户文件,使用内置命令配方配置该基线,验证生成的配置,将该已发布安装更新到候选 tarball,运行非交互式 Doctor,写入 `.artifacts/upgrade-survivor/summary.json`,然后启动一个 loopback Gateway 网关,并检查配置的 intents、状态保留、启动、`/healthz`、`/readyz` 和 RPC 状态预算。使用 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPEC` 覆盖一个基线,使用 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPECS` 让聚合调度器展开精确基线,例如 `all-since-2026.4.23`,并使用 `OPENCLAW_UPGRADE_SURVIVOR_SCENARIOS` 展开 issue 形状的 fixtures,例如 `reported-issues`;reported-issues 集合包含 `configured-plugin-installs`,用于自动修复外部 OpenClaw 插件安装。Package Acceptance 将这些暴露为 `published_upgrade_survivor_baseline`、`published_upgrade_survivor_baselines` 和 `published_upgrade_survivor_scenarios`。 +- 会话运行时上下文冒烟测试:`pnpm test:docker:session-runtime-context` 会验证隐藏运行时上下文 transcript 持久化,以及 Doctor 对受影响的重复 prompt-rewrite 分支的修复。 +- Bun 全局安装冒烟测试:`bash scripts/e2e/bun-global-install-smoke.sh` 会打包当前目录树,在隔离 home 中用 `bun install -g` 安装它,并验证 `openclaw infer image providers --json` 返回内置图像提供商而不是挂起。使用 `OPENCLAW_BUN_GLOBAL_SMOKE_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 复用预构建 tarball,使用 `OPENCLAW_BUN_GLOBAL_SMOKE_HOST_BUILD=0` 跳过主机构建,或使用 `OPENCLAW_BUN_GLOBAL_SMOKE_DIST_IMAGE=openclaw-dockerfile-smoke:local` 从已构建的 Docker 镜像复制 `dist/`。 +- 安装器 Docker 冒烟测试:`bash scripts/test-install-sh-docker.sh` 会在其 root、update 和 direct-npm 容器之间共享一个 npm 缓存。update 冒烟测试默认使用 npm `latest` 作为升级到候选 tarball 前的 stable 基线。在本地用 `OPENCLAW_INSTALL_SMOKE_UPDATE_BASELINE=2026.4.22` 覆盖,或在 GitHub 上用 Install Smoke workflow 的 `update_baseline_version` 输入覆盖。非 root 安装器检查会保留隔离的 npm 缓存,避免 root 拥有的缓存条目掩盖用户本地安装行为。设置 `OPENCLAW_INSTALL_SMOKE_NPM_CACHE_DIR=/path/to/cache` 可在本地重复运行时复用 root/update/direct-npm 缓存。 +- Install Smoke CI 使用 `OPENCLAW_INSTALL_SMOKE_SKIP_NPM_GLOBAL=1` 跳过重复的 direct-npm 全局更新;当需要直接 `npm install -g` 覆盖时,请在本地运行脚本且不要设置该环境变量。 +- Agents 删除共享工作区 CLI 冒烟测试:`pnpm test:docker:agents-delete-shared-workspace`(脚本:`scripts/e2e/agents-delete-shared-workspace-docker.sh`)默认构建根 Dockerfile 镜像,在隔离容器 home 中播种两个共享一个工作区的 agents,运行 `agents delete --json`,并验证有效 JSON 与保留工作区行为。使用 `OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_IMAGE=openclaw-dockerfile-smoke:local OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_SKIP_BUILD=1` 复用 install-smoke 镜像。 +- Gateway 网关网络(两个容器,WS auth + 健康检查):`pnpm test:docker:gateway-network`(脚本:`scripts/e2e/gateway-network-docker.sh`) +- 浏览器 CDP 快照冒烟测试:`pnpm test:docker:browser-cdp-snapshot`(脚本:`scripts/e2e/browser-cdp-snapshot-docker.sh`)会构建源码 E2E 镜像和 Chromium 层,使用原始 CDP 启动 Chromium,运行 `browser doctor --deep`,并验证 CDP 角色快照覆盖链接 URL、由光标提升的可点击项、iframe 引用和 frame 元数据。 +- OpenAI Responses web_search 最小推理回归测试:`pnpm test:docker:openai-web-search-minimal`(脚本:`scripts/e2e/openai-web-search-minimal-docker.sh`)会通过 Gateway 网关运行一个模拟的 OpenAI server,验证 `web_search` 将 `reasoning.effort` 从 `minimal` 提升到 `low`,然后强制 provider schema 拒绝并检查原始详情出现在 Gateway 网关日志中。 - MCP 渠道桥接(播种的 Gateway 网关 + stdio bridge + 原始 Claude notification-frame 冒烟测试):`pnpm test:docker:mcp-channels`(脚本:`scripts/e2e/mcp-channels-docker.sh`) - Pi bundle MCP 工具(真实 stdio MCP server + 嵌入式 Pi profile allow/deny 冒烟测试):`pnpm test:docker:pi-bundle-mcp-tools`(脚本:`scripts/e2e/pi-bundle-mcp-tools-docker.sh`) -- Cron/subagent MCP 清理(真实 Gateway 网关 + 在隔离 cron 和一次性 subagent 运行后拆除 stdio MCP 子进程):`pnpm test:docker:cron-mcp-cleanup`(脚本:`scripts/e2e/cron-mcp-cleanup-docker.sh`) -- 插件(local path、`file:`、带提升依赖的 npm registry、git moving refs、ClawHub kitchen-sink、marketplace 更新,以及 Claude-bundle 启用/检查的安装/更新冒烟测试):`pnpm test:docker:plugins`(脚本:`scripts/e2e/plugins-docker.sh`) - 设置 `OPENCLAW_PLUGINS_E2E_CLAWHUB=0` 可跳过 ClawHub 块,或用 `OPENCLAW_PLUGINS_E2E_CLAWHUB_SPEC` 和 `OPENCLAW_PLUGINS_E2E_CLAWHUB_ID` 覆盖默认的 kitchen-sink 包/运行时对。如果没有 `OPENCLAW_CLAWHUB_URL`/`CLAWHUB_URL`,测试会使用 hermetic 本地 ClawHub 夹具服务器。 +- Cron/subagent MCP 清理(真实 Gateway 网关 + stdio MCP 子进程在隔离 cron 和一次性 subagent 运行后的拆除):`pnpm test:docker:cron-mcp-cleanup`(脚本:`scripts/e2e/cron-mcp-cleanup-docker.sh`) +- 插件(本地路径、`file:`、带 hoisted 依赖的 npm registry、git moving refs、ClawHub kitchen-sink、marketplace updates,以及 Claude-bundle enable/inspect 的安装/更新冒烟测试):`pnpm test:docker:plugins`(脚本:`scripts/e2e/plugins-docker.sh`) + 设置 `OPENCLAW_PLUGINS_E2E_CLAWHUB=0` 可跳过 ClawHub 块,或使用 `OPENCLAW_PLUGINS_E2E_CLAWHUB_SPEC` 和 `OPENCLAW_PLUGINS_E2E_CLAWHUB_ID` 覆盖默认的 kitchen-sink package/runtime 对。如果没有 `OPENCLAW_CLAWHUB_URL`/`CLAWHUB_URL`,测试会使用 hermetic 本地 ClawHub fixture server。 - 插件更新无变化冒烟测试:`pnpm test:docker:plugin-update`(脚本:`scripts/e2e/plugin-update-unchanged-docker.sh`) -- 配置重载元数据冒烟测试:`pnpm test:docker:config-reload`(脚本:`scripts/e2e/config-reload-source-docker.sh`) -- 插件:`pnpm test:docker:plugins` 覆盖 local path、`file:`、带提升依赖的 npm registry、git moving refs、ClawHub 夹具、marketplace 更新,以及 Claude-bundle 启用/检查的安装/更新冒烟测试。`pnpm test:docker:plugin-update` 覆盖已安装插件的无变化更新行为。 +- 配置重新加载元数据冒烟测试:`pnpm test:docker:config-reload`(脚本:`scripts/e2e/config-reload-source-docker.sh`) +- 插件:`pnpm test:docker:plugins` 覆盖本地路径、`file:`、带 hoisted 依赖的 npm registry、git moving refs、ClawHub fixtures、marketplace updates,以及 Claude-bundle enable/inspect 的安装/更新冒烟测试。`pnpm test:docker:plugin-update` 覆盖已安装插件的无变化更新行为。 -要手动预构建并复用共享功能镜像: +要手动预构建并复用共享 functional 镜像: ```bash OPENCLAW_DOCKER_E2E_IMAGE=openclaw-docker-e2e-functional:local pnpm test:docker:e2e-build OPENCLAW_DOCKER_E2E_IMAGE=openclaw-docker-e2e-functional:local OPENCLAW_SKIP_DOCKER_BUILD=1 pnpm test:docker:mcp-channels ``` -设置后,像 `OPENCLAW_GATEWAY_NETWORK_E2E_IMAGE` 这样的套件专用镜像覆盖项仍然优先生效。当 `OPENCLAW_SKIP_DOCKER_BUILD=1` 指向远程共享镜像时,如果本地尚不存在,脚本会拉取它。QR 和安装器 Docker 测试保留自己的 Dockerfile,因为它们验证的是包/安装行为,而不是共享的已构建应用运行时。 +设置了 `OPENCLAW_GATEWAY_NETWORK_E2E_IMAGE` 等特定于 suite 的镜像覆盖时,它们仍然优先。当 `OPENCLAW_SKIP_DOCKER_BUILD=1` 指向远程共享镜像时,如果该镜像尚不在本地,脚本会拉取它。QR 和安装器 Docker 测试保留各自的 Dockerfile,因为它们验证的是 package/install 行为,而不是共享的已构建应用运行时。 -实时模型 Docker runner 还会以只读方式 bind-mount 当前检出, -并在容器内将其暂存到临时工作目录。这样可让运行时 -镜像保持精简,同时仍能针对你的精确本地源码/配置运行 Vitest。 -暂存步骤会跳过大型本地专用缓存和应用构建输出,例如 -`.pnpm-store`、`.worktrees`、`__openclaw_vitest__`,以及应用本地 `.build` 或 -Gradle 输出目录,因此 Docker 实时运行不会花数分钟复制 -机器专用工件。 -它们还会设置 `OPENCLAW_SKIP_CHANNELS=1`,使 Gateway 网关实时探测不会在容器内启动 -真实的 Telegram/Discord 等渠道 worker。 -`test:docker:live-models` 仍会运行 `pnpm test:live`,因此当你需要缩小或排除该 Docker 通道中的 Gateway 网关实时覆盖范围时, -也要传入 `OPENCLAW_LIVE_GATEWAY_*`。 -`test:docker:openwebui` 是更高层级的兼容性冒烟测试:它会启动一个 -启用 OpenAI 兼容 HTTP 端点的 OpenClaw Gateway 网关容器, -再启动一个固定版本的 Open WebUI 容器连接该 Gateway 网关,通过 -Open WebUI 登录,验证 `/api/models` 暴露 `openclaw/default`,然后通过 -Open WebUI 的 `/api/chat/completions` 代理发送一个真实聊天请求。 -首次运行可能明显更慢,因为 Docker 可能需要拉取 -Open WebUI 镜像,而 Open WebUI 可能也需要完成自己的冷启动设置。 -该通道需要可用的实时模型密钥,`OPENCLAW_PROFILE_FILE` -(默认 `~/.profile`)是在 Docker 化运行中提供它的主要方式。 -成功运行会打印一个小型 JSON payload,例如 `{ "ok": true, "model": -"openclaw/default", ... }`。 -`test:docker:mcp-channels` 有意保持确定性,不需要 -真实 Telegram、Discord 或 iMessage 账号。它会启动一个播种的 Gateway 网关 -容器,启动第二个容器来生成 `openclaw mcp serve`,然后 -验证路由会话发现、转录读取、附件元数据、 -实时事件队列行为、出站发送路由,以及通过真实 stdio MCP bridge 发送的 Claude 风格渠道 + -权限通知。通知检查会直接检查原始 stdio MCP frame,因此该冒烟测试验证的是 -bridge 实际发出的内容,而不只是某个特定客户端 SDK 恰好暴露的内容。 -`test:docker:pi-bundle-mcp-tools` 是确定性的,不需要实时 -模型密钥。它会构建 repo Docker 镜像,在容器内启动真实 stdio MCP 探测服务器, -通过嵌入式 Pi bundle -MCP 运行时物化该服务器,执行该工具,然后验证 `coding` 和 `messaging` 保留 -`bundle-mcp` 工具,而 `minimal` 和 `tools.deny: ["bundle-mcp"]` 会过滤它们。 -`test:docker:cron-mcp-cleanup` 是确定性的,不需要实时模型 -密钥。它会启动带真实 stdio MCP 探测服务器的播种 Gateway 网关,运行一个 -隔离 cron 轮次和一次 `/subagents spawn` 一次性子轮次,然后验证 -MCP 子进程在每次运行后退出。 +live-model Docker runners 还会以只读方式 bind-mount 当前 checkout,并在容器内将其 staging 到临时 workdir。这样可以保持运行时镜像精简,同时仍然针对你的精确本地 source/config 运行 Vitest。staging 步骤会跳过大型本地专用缓存和应用构建输出,例如 `.pnpm-store`、`.worktrees`、`__openclaw_vitest__`,以及应用本地 `.build` 或 Gradle 输出目录,这样 Docker 在线运行不会花费数分钟复制特定机器的 artifacts。它们还会设置 `OPENCLAW_SKIP_CHANNELS=1`,这样 Gateway 网关在线探针不会在容器内启动真实 Telegram/Discord 等渠道 worker。`test:docker:live-models` 仍然会运行 `pnpm test:live`,因此当你需要从该 Docker 通道缩小或排除 Gateway 网关在线覆盖范围时,也要透传 `OPENCLAW_LIVE_GATEWAY_*`。`test:docker:openwebui` 是更高层的兼容性冒烟测试:它会启动启用了 OpenAI 兼容 HTTP 端点的 OpenClaw gateway 容器,启动一个指向该 gateway 的固定版本 Open WebUI 容器,通过 Open WebUI 登录,验证 `/api/models` 暴露 `openclaw/default`,然后通过 Open WebUI 的 `/api/chat/completions` 代理发送真实聊天请求。首次运行可能明显更慢,因为 Docker 可能需要拉取 Open WebUI 镜像,Open WebUI 也可能需要完成自己的冷启动设置。该通道需要可用的在线模型密钥,而 `OPENCLAW_PROFILE_FILE`(默认 `~/.profile`)是在 Docker 化运行中提供它的主要方式。成功运行会打印一个小 JSON 负载,例如 `{ "ok": true, "model": "openclaw/default", ... }`。`test:docker:mcp-channels` 有意保持确定性,不需要真实 Telegram、Discord 或 iMessage 账号。它会启动一个已播种的 Gateway 网关容器,再启动第二个容器来生成 `openclaw mcp serve`,然后验证路由后的会话发现、transcript 读取、附件元数据、在线事件队列行为、出站发送路由,以及通过真实 stdio MCP bridge 发送的 Claude 风格渠道 + 权限通知。通知检查会直接检查原始 stdio MCP frames,因此冒烟测试验证的是 bridge 实际发出的内容,而不只是某个特定 client SDK 恰好暴露的内容。`test:docker:pi-bundle-mcp-tools` 是确定性的,不需要在线模型密钥。它会构建 repo Docker 镜像,在容器内启动真实 stdio MCP probe server,通过嵌入式 Pi bundle MCP runtime 实体化该 server,执行工具,然后验证 `coding` 和 `messaging` 保留 `bundle-mcp` 工具,而 `minimal` 和 `tools.deny: ["bundle-mcp"]` 会过滤它们。`test:docker:cron-mcp-cleanup` 是确定性的,不需要在线模型密钥。它会启动一个带真实 stdio MCP probe server 的已播种 Gateway 网关,运行一次隔离 cron 轮次和一次 `/subagents spawn` 一次性子轮次,然后验证 MCP 子进程在每次运行后退出。 -手动 ACP 自然语言 thread 冒烟测试(不在 CI 中): +手动 ACP 自然语言线程冒烟测试(非 CI): - `bun scripts/dev/discord-acp-plain-language-smoke.ts --channel ...` -- 保留此脚本用于回归/调试工作流。ACP thread 路由验证将来可能还会需要它,因此不要删除。 +- 保留此脚本用于回归/调试工作流。ACP 线程路由验证以后可能还会需要它,因此不要删除它。 有用的环境变量: -- `OPENCLAW_CONFIG_DIR=...`(默认值:`~/.openclaw`)挂载到 `/home/node/.openclaw` -- `OPENCLAW_WORKSPACE_DIR=...`(默认值:`~/.openclaw/workspace`)挂载到 `/home/node/.openclaw/workspace` -- `OPENCLAW_PROFILE_FILE=...`(默认值:`~/.profile`)挂载到 `/home/node/.profile`,并在运行测试前 source -- `OPENCLAW_DOCKER_PROFILE_ENV_ONLY=1` 仅验证从 `OPENCLAW_PROFILE_FILE` source 得到的环境变量,使用临时配置/工作区目录,且不挂载外部 CLI 认证 -- `OPENCLAW_DOCKER_CLI_TOOLS_DIR=...`(默认值:`~/.cache/openclaw/docker-cli-tools`)挂载到 `/home/node/.npm-global`,用于 Docker 内缓存的 CLI 安装 -- `$HOME` 下的外部 CLI 认证目录/文件会以只读方式挂载到 `/host-auth...` 下,然后在测试开始前复制到 `/home/node/...` +- `OPENCLAW_CONFIG_DIR=...`(默认:`~/.openclaw`)挂载到 `/home/node/.openclaw` +- `OPENCLAW_WORKSPACE_DIR=...`(默认:`~/.openclaw/workspace`)挂载到 `/home/node/.openclaw/workspace` +- `OPENCLAW_PROFILE_FILE=...`(默认:`~/.profile`)挂载到 `/home/node/.profile`,并在运行测试前加载 +- `OPENCLAW_DOCKER_PROFILE_ENV_ONLY=1` 仅验证从 `OPENCLAW_PROFILE_FILE` 加载的环境变量,使用临时配置/工作区目录,并且不挂载外部 CLI 凭证 +- `OPENCLAW_DOCKER_CLI_TOOLS_DIR=...`(默认:`~/.cache/openclaw/docker-cli-tools`)挂载到 `/home/node/.npm-global`,用于在 Docker 内缓存 CLI 安装 +- `$HOME` 下的外部 CLI 凭证目录/文件会以只读方式挂载到 `/host-auth...` 下,然后在测试开始前复制到 `/home/node/...` - 默认目录:`.minimax` - 默认文件:`~/.codex/auth.json`、`~/.codex/config.toml`、`.claude.json`、`~/.claude/.credentials.json`、`~/.claude/settings.json`、`~/.claude/settings.local.json` - - 缩小范围的提供商运行只会挂载从 `OPENCLAW_LIVE_PROVIDERS` / `OPENCLAW_LIVE_GATEWAY_PROVIDERS` 推断出的所需目录/文件 - - 可用 `OPENCLAW_DOCKER_AUTH_DIRS=all`、`OPENCLAW_DOCKER_AUTH_DIRS=none` 或类似 `OPENCLAW_DOCKER_AUTH_DIRS=.claude,.codex` 的逗号列表手动覆盖 -- `OPENCLAW_LIVE_GATEWAY_MODELS=...` / `OPENCLAW_LIVE_MODELS=...` 用于缩小运行范围 + - 收窄范围的提供商运行只会挂载根据 `OPENCLAW_LIVE_PROVIDERS` / `OPENCLAW_LIVE_GATEWAY_PROVIDERS` 推断出的所需目录/文件 + - 使用 `OPENCLAW_DOCKER_AUTH_DIRS=all`、`OPENCLAW_DOCKER_AUTH_DIRS=none`,或类似 `OPENCLAW_DOCKER_AUTH_DIRS=.claude,.codex` 的逗号列表手动覆盖 +- `OPENCLAW_LIVE_GATEWAY_MODELS=...` / `OPENCLAW_LIVE_MODELS=...` 用于收窄运行范围 - `OPENCLAW_LIVE_GATEWAY_PROVIDERS=...` / `OPENCLAW_LIVE_PROVIDERS=...` 用于在容器内筛选提供商 -- `OPENCLAW_SKIP_DOCKER_BUILD=1` 用于在不需要重新构建的重复运行中复用已有的 `openclaw:local-live` 镜像 -- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 用于确保凭据来自 profile 存储(而不是环境变量) -- `OPENCLAW_OPENWEBUI_MODEL=...` 用于选择 Gateway 网关为 Open WebUI smoke 暴露的模型 -- `OPENCLAW_OPENWEBUI_PROMPT=...` 用于覆盖 Open WebUI smoke 使用的 nonce 检查提示词 +- `OPENCLAW_SKIP_DOCKER_BUILD=1` 用于在无需重新构建的重复运行中复用现有 `openclaw:local-live` 镜像 +- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 用于确保凭据来自配置文件存储(而不是环境) +- `OPENCLAW_OPENWEBUI_MODEL=...` 用于选择 Gateway 网关为 Open WebUI 冒烟测试暴露的模型 +- `OPENCLAW_OPENWEBUI_PROMPT=...` 用于覆盖 Open WebUI 冒烟测试使用的 nonce 检查提示 - `OPENWEBUI_IMAGE=...` 用于覆盖固定的 Open WebUI 镜像标签 ## 文档完整性检查 文档编辑后运行文档检查:`pnpm check:docs`。 -当你还需要页内标题检查时,运行完整的 Mintlify 锚点验证:`pnpm docs:check-links:anchors`。 +当你还需要检查页内标题时,运行完整的 Mintlify 锚点验证:`pnpm docs:check-links:anchors`。 ## 离线回归(CI 安全) 这些是不使用真实提供商的“真实流水线”回归: -- Gateway 网关工具调用(模拟 OpenAI,真实 Gateway 网关 + Agent loop):`src/gateway/gateway.test.ts`(用例:"runs a mock OpenAI tool call end-to-end via gateway agent loop") -- Gateway 网关向导(WS `wizard.start`/`wizard.next`,写入配置 + 强制认证):`src/gateway/gateway.test.ts`(用例:"runs wizard over ws and writes auth token config") +- Gateway 网关工具调用(模拟 OpenAI,真实 Gateway 网关 + Agent loop):`src/gateway/gateway.test.ts`(用例:“通过 Gateway 网关 Agent loop 端到端运行模拟 OpenAI 工具调用”) +- Gateway 网关向导(WS `wizard.start`/`wizard.next`,写入配置 + 强制执行凭证):`src/gateway/gateway.test.ts`(用例:“通过 ws 运行向导并写入凭证令牌配置”) ## 智能体可靠性评估(Skills) -我们已经有一些行为类似“智能体可靠性评估”的 CI 安全测试: +我们已经有一些 CI 安全测试,其行为类似“智能体可靠性评估”: - 通过真实 Gateway 网关 + Agent loop 进行模拟工具调用(`src/gateway/gateway.test.ts`)。 -- 验证会话接线和配置效果的端到端向导流程(`src/gateway/gateway.test.ts`)。 +- 验证会话连线和配置效果的端到端向导流程(`src/gateway/gateway.test.ts`)。 -Skills 仍缺少的内容(见 [Skills](/zh-CN/tools/skills)): +Skills 仍缺失的内容(参见 [Skills](/zh-CN/tools/skills)): -- **决策:** 当提示词中列出 Skills 时,智能体是否会选择正确的 Skills(或避开无关 Skills)? -- **合规:** 智能体是否会在使用前读取 `SKILL.md`,并遵循所需步骤/参数? +- **决策:** 当提示中列出 Skills 时,智能体是否选择正确的 Skill(或避免不相关的 Skill)? +- **合规性:** 智能体是否在使用前读取 `SKILL.md` 并遵循所需步骤/参数? - **工作流契约:** 断言工具顺序、会话历史延续和沙箱边界的多轮场景。 -未来评估应优先保持确定性: +未来评估应首先保持确定性: -- 一个使用模拟提供商的场景运行器,用于断言工具调用 + 顺序、Skills 文件读取和会话接线。 -- 一小组聚焦 Skills 的场景(使用与避开、门控、提示注入)。 -- 可选的实时评估(选择加入、由环境变量门控)仅在 CI 安全套件就位后再添加。 +- 使用模拟提供商的场景运行器,用于断言工具调用 + 顺序、Skill 文件读取和会话连线。 +- 一小组聚焦 Skill 的场景(使用与避免、门控、提示注入)。 +- 可选的实时评估(选择加入、通过环境变量门控)仅在 CI 安全套件就位后添加。 -## 契约测试(插件和渠道形态) +## 契约测试(插件和渠道形状) -契约测试会验证每个已注册的插件和渠道是否符合其接口契约。它们会遍历所有发现的插件,并运行一套形态和行为断言。默认的 `pnpm test` 单元测试通道有意跳过这些共享边界和 smoke 文件;当你触及共享渠道或提供商表面时,请显式运行契约命令。 +契约测试验证每个已注册的插件和渠道都符合其接口契约。它们会遍历所有发现的插件,并运行一组形状和行为断言。默认的 `pnpm test` 单元测试通道会有意跳过这些共享连接面和冒烟文件;当你触及共享渠道或提供商表面时,请显式运行契约命令。 ### 命令 @@ -670,56 +605,56 @@ Skills 仍缺少的内容(见 [Skills](/zh-CN/tools/skills)): 位于 `src/channels/plugins/contracts/*.contract.test.ts`: -- **plugin** - 基础插件形态(id、名称、能力) +- **plugin** - 基本插件形状(id、名称、能力) - **setup** - 设置向导契约 - **session-binding** - 会话绑定行为 - **outbound-payload** - 消息载荷结构 - **inbound** - 入站消息处理 - **actions** - 渠道操作处理器 - **threading** - 线程 ID 处理 -- **directory** - 目录/名册 API +- **directory** - 目录/成员名册 API - **group-policy** - 群组策略强制执行 -### 提供商 Status 契约 +### 提供商状态契约 位于 `src/plugins/contracts/*.contract.test.ts`。 -- **status** - 渠道 Status 探测 -- **registry** - 插件注册表形态 +- **status** - 渠道状态探测 +- **registry** - 插件注册表形状 ### 提供商契约 位于 `src/plugins/contracts/*.contract.test.ts`: -- **auth** - 认证流程契约 -- **auth-choice** - 认证选择/选定 +- **auth** - 凭证流程契约 +- **auth-choice** - 凭证选择/选取 - **catalog** - 模型目录 API -- **discovery** - 插件发现 +- **discovery** - 插件设备发现 - **loader** - 插件加载 - **runtime** - 提供商运行时 -- **shape** - 插件形态/接口 +- **shape** - 插件形状/接口 - **wizard** - 设置向导 ### 何时运行 -- 更改插件 SDK 导出或子路径后 +- 更改 plugin-sdk 导出或子路径后 - 添加或修改渠道或提供商插件后 -- 重构插件注册或发现后 +- 重构插件注册或设备发现后 -契约测试在 CI 中运行,不需要真实 API key。 +契约测试会在 CI 中运行,并且不需要真实 API 密钥。 ## 添加回归(指南) -当你修复实时环境中发现的提供商/模型问题时: +当你修复实时发现的提供商/模型问题时: -- 尽可能添加 CI 安全回归(模拟/桩提供商,或捕获精确的请求形态转换) -- 如果它本质上只能实时测试(速率限制、认证策略),请保持实时测试范围狭窄,并通过环境变量选择加入 -- 优先定位能捕获该 bug 的最小层级: - - 提供商请求转换/回放 bug → 直接的模型测试 - - Gateway 网关会话/历史/工具流水线 bug → Gateway 网关实时 smoke 或 CI 安全的 Gateway 网关模拟测试 +- 尽可能添加 CI 安全回归(模拟/存根提供商,或捕获精确的请求形状转换) +- 如果它本质上只能实时测试(速率限制、凭证策略),请保持实时测试范围狭窄,并通过环境变量选择加入 +- 优先针对能捕获该 bug 的最小层: + - 提供商请求转换/重放 bug → 直接模型测试 + - Gateway 网关会话/历史/工具流水线 bug → Gateway 网关实时冒烟测试或 CI 安全的 Gateway 网关模拟测试 - SecretRef 遍历护栏: - - `src/secrets/exec-secret-ref-id-parity.test.ts` 会从注册表元数据(`listSecretTargetRegistryEntries()`)为每个 SecretRef 类派生一个采样目标,然后断言包含遍历片段的 exec id 会被拒绝。 - - 如果你在 `src/secrets/target-registry-data.ts` 中添加新的 `includeInPlan` SecretRef 目标族,请更新该测试中的 `classifyTargetClass`。该测试会有意在未分类的目标 id 上失败,确保新类别不能被静默跳过。 + - `src/secrets/exec-secret-ref-id-parity.test.ts` 从注册表元数据(`listSecretTargetRegistryEntries()`)为每个 SecretRef 类派生一个采样目标,然后断言遍历段 exec id 会被拒绝。 + - 如果你在 `src/secrets/target-registry-data.ts` 中添加新的 `includeInPlan` SecretRef 目标族,请更新该测试中的 `classifyTargetClass`。该测试会有意在未分类目标 id 上失败,以免新类被静默跳过。 ## 相关 diff --git a/docs/zh-CN/reference/RELEASING.md b/docs/zh-CN/reference/RELEASING.md index 8d18504f7..398703607 100644 --- a/docs/zh-CN/reference/RELEASING.md +++ b/docs/zh-CN/reference/RELEASING.md @@ -1,152 +1,153 @@ --- read_when: - - 正在查找公开发布渠道定义 + - 正在查找公共发布渠道定义 - 运行发布验证或包验收 - 查找版本命名和发布节奏 -summary: 发布轨道、操作员检查清单、验证环境、版本命名和节奏 +summary: 发布通道、操作员检查清单、验证盒、版本命名和节奏 title: 发布策略 x-i18n: - generated_at: "2026-05-02T18:56:27Z" + generated_at: "2026-05-02T20:01:29Z" model: gpt-5.5 provider: openai - source_hash: 18cee58dcad91e24c0d76622a9ed1568f93e4e2c51deae9ad06ccc7feb831d3a + source_hash: 493cb8b42f0e15f3bf5f8fb9be7d01fd626f4f16db9ac0a85e6efa747ef12d12 source_path: reference/RELEASING.md workflow: 16 --- -OpenClaw 有四条公开发布线: +OpenClaw 有四条公开发布通道: -- stable:带标签的发布版本,默认发布到 npm `beta`,或在明确请求时发布到 npm `latest` -- alpha:发布到 npm `alpha` 的预发布标签 -- beta:发布到 npm `beta` 的预发布标签 -- dev:`main` 的移动最新提交 +- 稳定版:带标签的发布版本,默认发布到 npm `beta`,或在明确请求时发布到 npm `latest` +- alpha 版:发布到 npm `alpha` 的预发布标签 +- beta 版:发布到 npm `beta` 的预发布标签 +- 开发版:`main` 的移动最新提交 ## 版本命名 - 稳定发布版本:`YYYY.M.D` - Git 标签:`vYYYY.M.D` -- 稳定修正发布版本:`YYYY.M.D-N` +- 稳定修正版发布版本:`YYYY.M.D-N` - Git 标签:`vYYYY.M.D-N` - Alpha 预发布版本:`YYYY.M.D-alpha.N` - Git 标签:`vYYYY.M.D-alpha.N` - Beta 预发布版本:`YYYY.M.D-beta.N` - Git 标签:`vYYYY.M.D-beta.N` -- 月份或日期不要补零 +- 不要为月份或日期补零 - `latest` 表示当前已提升的稳定 npm 发布版本 - `alpha` 表示当前 alpha 安装目标 - `beta` 表示当前 beta 安装目标 -- 稳定和稳定修正发布默认发布到 npm `beta`;发布操作员可以明确指定 `latest`,或稍后提升经过审查的 beta 构建 -- 每个稳定版 OpenClaw 发布都会同时交付 npm 包和 macOS 应用; - beta 发布通常先验证并发布 npm/包路径,除非明确请求,否则 - mac 应用的构建/签名/公证会保留给稳定版 +- 稳定版和稳定修正版默认发布到 npm `beta`;发布操作员可以明确指定 `latest`,也可以稍后提升一个已验证的 beta 构建 +- 每个稳定 OpenClaw 发布版本都会同时交付 npm 包和 macOS 应用; + beta 发布通常先验证并发布 npm/包路径,mac 应用的构建、签名和公证保留给稳定版,除非明确请求 ## 发布节奏 - 发布按 beta 优先推进 -- 只有在最新 beta 完成验证后才会进入稳定版 -- 维护者通常从基于当前 `main` 创建的 `release/YYYY.M.D` 分支发布, +- 只有在最新 beta 通过验证后才进入稳定版 +- 维护者通常从当前 `main` 创建的 `release/YYYY.M.D` 分支切出发布, 因此发布验证和修复不会阻塞 `main` 上的新开发 -- 如果 beta 标签已经推送或发布且需要修复,维护者会发布下一个 - `-beta.N` 标签,而不是删除或重新创建旧的 beta 标签 -- 详细发布流程、审批、凭证和恢复说明仅限维护者查看 +- 如果 beta 标签已经推送或发布后需要修复,维护者会切下一个 `-beta.N` 标签,而不是删除或重建旧的 beta 标签 +- 详细发布流程、审批、凭证和恢复说明仅供维护者使用 ## 发布操作员检查清单 -此检查清单是发布流程的公开形态。私有凭证、签名、公证、dist-tag 恢复和紧急回滚细节保留在仅限维护者查看的发布运行手册中。 +此检查清单是发布流程的公开形态。私有凭证、签名、公证、dist-tag 恢复和紧急回滚详情保留在仅限维护者的发布运行手册中。 1. 从当前 `main` 开始:拉取最新内容,确认目标提交已推送, - 并确认当前 `main` 的 CI 状态足够健康,可以从它创建分支。 + 并确认当前 `main` 的 CI 足够绿色,可以从它创建分支。 2. 使用 `/changelog` 根据真实提交历史重写顶部 `CHANGELOG.md` 章节, - 保持条目面向用户,提交它,推送它,并在创建分支前再次 rebase/pull。 + 保持条目面向用户,提交它、推送它,并在创建分支前再 rebase/pull + 一次。 3. 审查 `src/plugins/compat/registry.ts` 和 - `src/commands/doctor/shared/deprecation-compat.ts` 中的发布兼容性记录。只有在升级路径仍被覆盖时才移除过期兼容性, - 或记录为什么有意继续保留。 -4. 从当前 `main` 创建 `release/YYYY.M.D`;不要直接在 `main` 上执行常规发布工作。 + `src/commands/doctor/shared/deprecation-compat.ts` 中的发布兼容性记录。只有在升级路径仍被覆盖时才移除过期兼容性,或者记录为什么有意继续保留。 +4. 从当前 `main` 创建 `release/YYYY.M.D`;不要直接在 `main` 上做常规发布工作。 5. 为目标标签更新每个必需的版本位置,运行 - `pnpm plugins:sync`,使可发布的插件包共享发布版本和兼容性元数据,然后运行本地确定性预检: + `pnpm plugins:sync`,让可发布的插件包共享发布版本和兼容性元数据,然后运行本地确定性预检: `pnpm check:test-types`、`pnpm check:architecture`、 `pnpm build && pnpm ui:build`、`pnpm plugins:sync:check` 和 `pnpm release:check`。 6. 使用 `preflight_only=true` 运行 `OpenClaw NPM Release`。在标签存在之前, 允许使用完整 40 字符的发布分支 SHA 进行仅验证预检。保存成功的 `preflight_run_id`。 -7. 针对发布分支、标签或完整提交 SHA,使用 `Full Release Validation` 启动所有预发布测试。这是四个大型发布测试箱的唯一手动入口点:Vitest、Docker、QA Lab 和 Package。 -8. 如果验证失败,在发布分支上修复,并重新运行最小的失败文件、发布线、工作流作业、包配置、提供商或模型允许列表,以证明修复有效。只有当变更表面让先前证据过期时,才重新运行完整总括验证。 -9. 对于 alpha 或 beta,标记 `vYYYY.M.D-alpha.N` 或 `vYYYY.M.D-beta.N`,然后从匹配的 `release/YYYY.M.D` 分支运行 `OpenClaw Release Publish`。它会验证 `pnpm plugins:sync:check`,先将所有可发布的插件包发布到 npm,再将同一组包发布到 ClawHub,然后使用匹配的 dist-tag 提升已准备好的 OpenClaw npm 预检产物。发布后,针对已发布的 `openclaw@YYYY.M.D-alpha.N`、`openclaw@alpha`、`openclaw@YYYY.M.D-beta.N` 或 `openclaw@beta` 包运行发布后包验收。如果已推送或已发布的预发布需要修复,请发布下一个匹配的预发布编号; - 不要删除或重写旧预发布。 -10. 对于稳定版,只有在经过审查的 beta 或发布候选版本具备所需验证证据后才继续。稳定版 npm 发布也通过 - `OpenClaw Release Publish` 进行,并通过 - `preflight_run_id` 复用成功的预检产物;稳定版 macOS 发布就绪还要求 - `main` 上存在打包好的 `.zip`、`.dmg`、`.dSYM.zip` 和更新后的 `appcast.xml`。 -11. 发布后,运行 npm 发布后验证器;在需要发布后渠道证明时,可选运行独立的已发布 npm Telegram E2E; - 在需要时执行 dist-tag 提升;根据完整匹配的 `CHANGELOG.md` 章节生成 GitHub 发布/预发布说明;并执行发布公告步骤。 +7. 对发布分支、标签或完整提交 SHA 运行 `Full Release Validation`,启动所有预发布测试。这是四个大型发布测试盒子的唯一手动入口点:Vitest、Docker、QA Lab 和 Package。 +8. 如果验证失败,在发布分支上修复,并重新运行能证明修复的最小失败文件、通道、工作流作业、包配置文件、提供商或模型 allowlist。只有当变更面使先前证据失效时,才重新运行完整总入口。 +9. 对于 alpha 或 beta,打上 `vYYYY.M.D-alpha.N` 或 `vYYYY.M.D-beta.N` 标签,然后从匹配的 `release/YYYY.M.D` 分支运行 `OpenClaw Release Publish`。它会验证 `pnpm plugins:sync:check`, + 先将所有可发布的插件包发布到 npm,再将同一组发布到 ClawHub,然后用匹配的 dist-tag 提升已准备好的 OpenClaw npm 预检产物。发布后,对已发布的 `openclaw@YYYY.M.D-alpha.N`、`openclaw@alpha`、 + `openclaw@YYYY.M.D-beta.N` 或 `openclaw@beta` 包运行发布后包验收。如果已推送或已发布的预发布需要修复,切下一个匹配的预发布编号; + 不要删除或重写旧的预发布版本。 +10. 对于稳定版,只有在已验证的 beta 或发布候选具备所需验证证据后才继续。稳定版 npm 发布也通过 + `OpenClaw Release Publish`,并通过 `preflight_run_id` 复用成功的预检产物;稳定版 macOS 发布就绪还要求 `main` 上有打包好的 `.zip`、`.dmg`、`.dSYM.zip` 和更新后的 `appcast.xml`。 +11. 发布后,运行 npm 发布后验证器、在需要发布后渠道证明时可选运行独立的已发布 npm Telegram E2E、 + 在需要时进行 dist-tag 提升、根据完整匹配的 `CHANGELOG.md` 章节生成 GitHub 发布/预发布说明,并完成发布公告步骤。 ## 发布预检 -- 在发布预检前运行 `pnpm check:test-types`,确保测试 TypeScript 在更快的本地 `pnpm check` 门禁之外也保持覆盖 -- 在发布预检前运行 `pnpm check:architecture`,确保更广泛的导入循环和架构边界检查在更快的本地门禁之外也保持绿色 -- 在 `pnpm release:check` 前运行 `pnpm build && pnpm ui:build`,确保预期的 `dist/*` 发布产物和 Control UI 包已存在,供打包校验步骤使用 -- 在根版本号提升之后、打标签之前运行 `pnpm plugins:sync`。它会更新可发布插件包版本、OpenClaw peer/API 兼容性元数据、构建元数据和插件变更日志桩,使其匹配核心发布版本。`pnpm plugins:sync:check` 是非变更型发布防护;如果忘记此步骤,发布工作流会在任何 registry 变更前失败。 -- 在发布批准前运行手动 `Full Release Validation` 工作流,从一个入口启动所有预发布测试盒。它接受分支、标签或完整提交 SHA,分发手动 `CI`,并分发 `OpenClaw Release Checks`,覆盖安装冒烟、包验收、Docker 发布路径套件、live/E2E、OpenWebUI、QA Lab 对等性、Matrix 和 Telegram 通道。使用 `release_profile=full` 和 `rerun_group=all` 时,它还会针对发布检查中的 `release-package-under-test` 产物运行包 Telegram E2E。发布后,如果同一个 Telegram E2E 也需要证明已发布的 npm 包,请提供 `npm_telegram_package_spec`。发布后,如果 Package Acceptance 应针对已发货的 npm 包而不是 SHA 构建产物运行其包/更新矩阵,请提供 `package_acceptance_package_spec`。如果私有证据报告应证明验证匹配已发布的 npm 包,但不强制运行 Telegram E2E,请提供 `evidence_package_spec`。示例:`gh workflow run full-release-validation.yml --ref main -f ref=release/YYYY.M.D` -- 当你希望在发布工作继续推进时,为包候选项获取旁路证明,请运行手动 `Package Acceptance` 工作流。对 `openclaw@alpha`、`openclaw@beta`、`openclaw@latest` 或精确发布版本使用 `source=npm`;使用 `source=ref` 以当前 `workflow_ref` harness 打包受信任的 `package_ref` 分支/标签/SHA;对带必需 SHA-256 的 HTTPS tarball 使用 `source=url`;或对另一个 GitHub Actions 运行上传的 tarball 使用 `source=artifact`。该工作流会将候选项解析为 `package-under-test`,针对该 tarball 复用 Docker E2E 发布调度器,并可使用 `telegram_mode=mock-openai` 或 `telegram_mode=live-frontier` 针对同一个 tarball 运行 Telegram QA。当所选 Docker 通道包含 `published-upgrade-survivor` 时,包产物就是候选项,而 `published_upgrade_survivor_baseline` 选择已发布的基线。 +- 在发布预检前运行 `pnpm check:test-types`,让测试 TypeScript 在更快的本地 `pnpm check` 门禁之外保持覆盖 +- 在发布预检前运行 `pnpm check:architecture`,让更广泛的导入循环和架构边界检查在更快的本地门禁之外保持通过 +- 在 `pnpm release:check` 前运行 `pnpm build && pnpm ui:build`,确保预期的 `dist/*` 发布产物和 Control UI 包存在,可用于打包验证步骤 +- 在根版本号提升后、打标签前运行 `pnpm plugins:sync`。它会更新可发布插件包版本、OpenClaw 对等/API 兼容性元数据、构建元数据和插件变更日志存根,使其匹配核心发布版本。`pnpm plugins:sync:check` 是非变更式发布防护;如果忘记此步骤,发布工作流会在任何注册表变更前失败。 +- 在发布批准前运行手动 `Full Release Validation` 工作流,以便从一个入口点启动所有发布前测试箱。它接受分支、标签或完整提交 SHA,分发手动 `CI`,并为安装冒烟、包验收、Docker 发布路径套件、live/E2E、OpenWebUI、QA Lab parity、Matrix 和 Telegram 线路分发 `OpenClaw Release Checks`。使用 `release_profile=full` 和 `rerun_group=all` 时,它还会针对发布检查中的 `release-package-under-test` 产物运行包 Telegram E2E。发布后,如果同一个 Telegram E2E 也应验证已发布的 npm 包,请提供 `npm_telegram_package_spec`。发布后,如果 Package Acceptance 应该针对已交付的 npm 包而不是 SHA 构建产物运行其包/更新矩阵,请提供 `package_acceptance_package_spec`。当私有证据报告应证明验证结果匹配已发布的 npm 包、但不强制运行 Telegram E2E 时,请提供 `evidence_package_spec`。 + 示例: + `gh workflow run full-release-validation.yml --ref main -f ref=release/YYYY.M.D` +- 当你希望在发布工作继续进行时,为包候选版本获取旁路证明,请运行手动 `Package Acceptance` 工作流。对 `openclaw@alpha`、`openclaw@beta`、`openclaw@latest` 或精确发布版本使用 `source=npm`;使用 `source=ref` 通过当前 `workflow_ref` harness 打包可信的 `package_ref` 分支/标签/SHA;对带有必需 SHA-256 的 HTTPS tarball 使用 `source=url`;或对另一个 GitHub Actions 运行上传的 tarball 使用 `source=artifact`。该工作流会将候选版本解析为 `package-under-test`,针对该 tarball 复用 Docker E2E 发布调度器,并可通过 `telegram_mode=mock-openai` 或 `telegram_mode=live-frontier` 针对同一 tarball 运行 Telegram QA。当所选 Docker 线路包含 `published-upgrade-survivor` 时,包产物就是候选版本,`published_upgrade_survivor_baseline` 选择已发布基线。 示例:`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 published_upgrade_survivor_baseline=openclaw@2026.4.26 -f telegram_mode=mock-openai` 常用配置: - - `smoke`:安装/渠道/智能体、Gateway 网关网络和配置重载通道 - - `package`:产物原生包/更新/插件通道,不包含 OpenWebUI 或 live ClawHub - - `product`:包配置加上 MCP 渠道、cron/子智能体清理、OpenAI Web 搜索和 OpenWebUI + - `smoke`:安装/渠道/智能体、Gateway 网关网络和配置重载线路 + - `package`:不含 OpenWebUI 或 live ClawHub 的产物原生包/更新/插件线路 + - `product`:包配置加 MCP 渠道、cron/子智能体清理、OpenAI web search 和 OpenWebUI - `full`:带 OpenWebUI 的 Docker 发布路径分块 - `custom`:用于聚焦重跑的精确 `docker_lanes` 选择 -- 当你只需要发布候选版本的完整普通 CI 覆盖时,直接运行手动 `CI` 工作流。手动 CI 分发会绕过变更范围限定,并强制运行 Linux Node 分片、内置插件分片、渠道合约、Node 22 兼容性、`check`、`check-additional`、构建冒烟、文档检查、Python skills、Windows、macOS、Android 和 Control UI i18n 通道。 +- 当你只需要发布候选版本的完整常规 CI 覆盖时,直接运行手动 `CI` 工作流。手动 CI 分发会绕过变更范围限定,并强制运行 Linux Node 分片、内置插件分片、渠道契约、Node 22 兼容性、`check`、`check-additional`、构建冒烟、文档检查、Python skills、Windows、macOS、Android 和 Control UI i18n 线路。 示例:`gh workflow run ci.yml --ref release/YYYY.M.D` -- 验证发布遥测时运行 `pnpm qa:otel:smoke`。它通过本地 OTLP/HTTP 接收器执行 QA-lab,并验证导出的 trace span 名称、有界属性以及内容/标识符脱敏,无需 Opik、Langfuse 或其他外部收集器。 +- 验证发布遥测时运行 `pnpm qa:otel:smoke`。它会通过本地 OTLP/HTTP 接收器执行 QA-lab,并验证导出的 trace span 名称、有界属性以及内容/标识符脱敏,无需 Opik、Langfuse 或其他外部收集器。 - 每次打标签发布前运行 `pnpm release:check` -- 标签存在后,运行 `OpenClaw Release Publish` 执行会变更状态的发布序列。从 `release/YYYY.M.D`(或发布 main 可达标签时从 `main`)分发它,传入发布标签和成功的 OpenClaw npm `preflight_run_id`,并保持默认插件发布范围 `all-publishable`,除非你有意执行聚焦修复。该工作流会串行执行插件 npm 发布、插件 ClawHub 发布和 OpenClaw npm 发布,确保核心包不会早于其外置插件发布。 -- 发布检查现在运行在单独的手动工作流中:`OpenClaw Release Checks` -- `OpenClaw Release Checks` 还会在发布批准前运行 QA Lab 模拟对等性门禁、快速 live Matrix 配置和 Telegram QA 通道。live 通道使用 `qa-live-shared` 环境;Telegram 还使用 Convex CI 凭据租约。当你需要并行获取完整 Matrix 传输、媒体和 E2EE 清单时,使用 `matrix_profile=all` 和 `matrix_shards=true` 运行手动 `QA-Lab - All Lanes` 工作流。 -- 跨操作系统安装和升级运行时验证是公开 `OpenClaw Release Checks` 和 `Full Release Validation` 的一部分,它们会直接调用可复用工作流 `.github/workflows/openclaw-cross-os-release-checks-reusable.yml` -- 这种拆分是有意的:保持真实 npm 发布路径短、确定且以产物为中心,同时较慢的 live 检查保留在自己的通道中,避免拖慢或阻塞发布 -- 携带 secret 的发布检查应通过 `Full Release Validation` 分发,或从 `main`/发布工作流 ref 分发,以确保工作流逻辑和 secret 保持受控 +- 标签存在后,为变更式发布序列运行 `OpenClaw Release Publish`。从 `release/YYYY.M.D` 分发它(或在发布 main 可达标签时从 `main` 分发),传入发布标签和成功的 OpenClaw npm `preflight_run_id`,并保持默认插件发布范围 `all-publishable`,除非你在有意运行聚焦修复。该工作流会串行化插件 npm 发布、插件 ClawHub 发布和 OpenClaw npm 发布,确保核心包不会早于其外部化插件发布。 +- 发布检查现在在单独的手动工作流中运行: + `OpenClaw Release Checks` +- `OpenClaw Release Checks` 还会在发布批准前运行 QA Lab mock parity 线路,以及快速 live Matrix 配置和 Telegram QA 线路。live 线路使用 `qa-live-shared` 环境;Telegram 还使用 Convex CI 凭证租约。当你想并行获取完整 Matrix 传输、媒体和 E2EE 清单时,请使用 `matrix_profile=all` 和 `matrix_shards=true` 运行手动 `QA-Lab - All Lanes` 工作流。 +- 跨 OS 安装和升级运行时验证是公开 `OpenClaw Release Checks` 和 `Full Release Validation` 的一部分,它们会直接调用可复用工作流 `.github/workflows/openclaw-cross-os-release-checks-reusable.yml` +- 这种拆分是有意为之:让真实 npm 发布路径保持简短、确定且聚焦产物,同时让较慢的 live 检查留在自己的线路中,避免拖慢或阻塞发布 +- 携带密钥的发布检查应通过 `Full Release Validation` 分发,或从 `main`/发布工作流 ref 分发,使工作流逻辑和密钥保持受控 - `OpenClaw Release Checks` 接受分支、标签或完整提交 SHA,只要解析出的提交可从 OpenClaw 分支或发布标签到达 -- `OpenClaw NPM Release` 仅验证预检也接受当前完整 40 字符工作流分支提交 SHA,不要求已推送标签 +- `OpenClaw NPM Release` 仅验证预检也接受当前完整 40 字符工作流分支提交 SHA,无需推送标签 - 该 SHA 路径仅用于验证,不能提升为真实发布 -- 在 SHA 模式下,工作流仅为包元数据检查合成 `v`;真实发布仍需要真实发布标签 -- 两个工作流都将真实发布和提升路径保留在 GitHub 托管 runner 上,而非变更型验证路径可以使用更大的 Blacksmith Linux runner -- 该工作流运行 `OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_CACHE_TEST=1 pnpm test:live:cache`,并使用 `OPENAI_API_KEY` 和 `ANTHROPIC_API_KEY` 两个工作流 secret -- npm 发布预检不再等待单独的发布检查通道 +- 在 SHA 模式下,工作流仅为包元数据检查合成 `v`;真实发布仍然需要真实发布标签 +- 两个工作流都让真实发布和提升路径保留在 GitHub 托管 runner 上,而非变更式验证路径可以使用更大的 Blacksmith Linux runner +- 该工作流使用 `OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_CACHE_TEST=1 pnpm test:live:cache` 运行,并使用 `OPENAI_API_KEY` 和 `ANTHROPIC_API_KEY` 两个工作流密钥 +- npm 发布预检不再等待单独的发布检查线路 - 批准前运行 `RELEASE_TAG=vYYYY.M.D node --import tsx scripts/openclaw-npm-release-check.ts`(或匹配的 beta/修正标签) -- npm 发布后,运行 `node --import tsx scripts/openclaw-npm-postpublish-verify.ts YYYY.M.D`(或匹配的 beta/修正版本),在全新的临时前缀中验证已发布 registry 的安装路径 -- beta 发布后,运行 `OPENCLAW_NPM_TELEGRAM_PACKAGE_SPEC=openclaw@YYYY.M.D-beta.N OPENCLAW_NPM_TELEGRAM_CREDENTIAL_SOURCE=convex OPENCLAW_NPM_TELEGRAM_CREDENTIAL_ROLE=ci pnpm test:docker:npm-telegram-live`,使用共享租约 Telegram 凭据池,针对已发布的 npm 包验证已安装包的新手引导、Telegram 设置和真实 Telegram E2E。本地维护者一次性运行可以省略 Convex 变量,并直接传入三个 `OPENCLAW_QA_TELEGRAM_*` 环境变量凭据。 -- 维护者可以通过手动 `NPM Telegram Beta E2E` 工作流,从 GitHub Actions 运行同一个发布后检查。它有意仅支持手动运行,不会在每次合并时运行。 -- 维护者发布自动化现在使用先预检再提升: +- npm 发布后,运行 `node --import tsx scripts/openclaw-npm-postpublish-verify.ts YYYY.M.D`(或匹配的 beta/修正版本),在全新的临时前缀中验证已发布注册表安装路径 +- beta 发布后,运行 `OPENCLAW_NPM_TELEGRAM_PACKAGE_SPEC=openclaw@YYYY.M.D-beta.N OPENCLAW_NPM_TELEGRAM_CREDENTIAL_SOURCE=convex OPENCLAW_NPM_TELEGRAM_CREDENTIAL_ROLE=ci pnpm test:docker:npm-telegram-live`,使用共享租约式 Telegram 凭证池,针对已发布的 npm 包验证已安装包的新手引导、Telegram 设置和真实 Telegram E2E。本地维护者的一次性运行可以省略 Convex 变量,并直接传入三个 `OPENCLAW_QA_TELEGRAM_*` 环境凭证。 +- 维护者可以通过手动 `NPM Telegram Beta E2E` 工作流从 GitHub Actions 运行同一个发布后检查。它有意仅手动运行,不会在每次合并时运行。 +- 维护者发布自动化现在使用预检后提升: - 真实 npm 发布必须通过成功的 npm `preflight_run_id` - 真实 npm 发布必须从与成功预检运行相同的 `main` 或 `release/YYYY.M.D` 分支分发 - - 稳定 npm 发布默认使用 `beta` - - 稳定 npm 发布可以通过工作流输入显式目标为 `latest` - - 基于令牌的 npm dist-tag 变更现在位于 `openclaw/releases-private/.github/workflows/openclaw-npm-dist-tags.yml`,出于安全原因,因为 `npm dist-tag add` 仍需要 `NPM_TOKEN`,而公开 repo 保持仅 OIDC 发布 - - 公开 `macOS Release` 仅用于验证;当标签只存在于发布分支上,但工作流从 `main` 分发时,设置 `public_release_branch=release/YYYY.M.D` + - 稳定版 npm 发布默认使用 `beta` + - 稳定版 npm 发布可以通过工作流输入显式目标到 `latest` + - 基于 token 的 npm dist-tag 变更现在位于 `openclaw/releases-private/.github/workflows/openclaw-npm-dist-tags.yml`,这是出于安全考虑,因为 `npm dist-tag add` 仍需要 `NPM_TOKEN`,而公开仓库保持仅 OIDC 发布 + - 公开 `macOS Release` 仅用于验证;当标签只存在于发布分支、但工作流从 `main` 分发时,设置 `public_release_branch=release/YYYY.M.D` - 真实私有 mac 发布必须通过成功的私有 mac `preflight_run_id` 和 `validate_run_id` - - 真实发布路径会提升已准备好的产物,而不是再次重新构建它们 -- 对于 `YYYY.M.D-N` 这类稳定修正发布,发布后验证器还会检查从 `YYYY.M.D` 到 `YYYY.M.D-N` 的同一临时前缀升级路径,确保发布修正不会静默地让较旧的全局安装停留在基础稳定 payload 上 -- npm 发布预检默认失败,除非 tarball 同时包含 `dist/control-ui/index.html` 和非空的 `dist/control-ui/assets/` payload,避免再次发布空的浏览器仪表板 -- 发布后验证还会检查已发布插件入口点和包元数据是否存在于已安装 registry 布局中。若某次发布缺少插件运行时 payload,发布后验证器会失败,并且该版本不能提升为 `latest`。 -- `pnpm test:install:smoke` 还会对候选更新 tarball 强制执行 npm pack `unpackedSize` 预算,因此安装器 e2e 能在发布路径发布前捕获意外的打包膨胀 -- 如果发布工作触及 CI 规划、插件计时 manifest 或插件测试矩阵,请在批准前重新生成并审查规划器拥有的 `plugin-prerelease-extension-shard` 矩阵输出(来自 `.github/workflows/plugin-prerelease.yml`),确保发布说明不会描述过期的 CI 布局 -- 稳定 macOS 发布就绪性还包括更新器表面: - - GitHub 发布最终必须包含已打包的 `.zip`、`.dmg` 和 `.dSYM.zip` - - 发布后,`main` 上的 `appcast.xml` 必须指向新的稳定 zip - - 已打包应用必须保持非调试 bundle id、非空 Sparkle feed URL,以及等于或高于该发布版本规范 Sparkle 构建下限的 `CFBundleVersion` + - 真实发布路径会提升已准备好的产物,而不是再次重建它们 +- 对于像 `YYYY.M.D-N` 这样的稳定版修正发布,发布后验证器还会检查同一临时前缀从 `YYYY.M.D` 到 `YYYY.M.D-N` 的升级路径,确保发布修正不会静默地让较旧全局安装停留在基础稳定版载荷上 +- npm 发布预检默认失败关闭,除非 tarball 同时包含 `dist/control-ui/index.html` 和非空的 `dist/control-ui/assets/` 载荷,确保我们不再发布空的浏览器仪表盘 +- 发布后验证还会检查已发布插件入口点和包元数据是否存在于已安装的注册表布局中。缺少插件运行时载荷的发布会导致 postpublish 验证器失败,并且不能提升为 `latest`。 +- `pnpm test:install:smoke` 还会对候选更新 tarball 强制执行 npm pack `unpackedSize` 预算,因此安装器 e2e 会在发布发布路径前捕获意外的包体积膨胀 +- 如果发布工作触及 CI 规划、插件计时清单或插件测试矩阵,请在批准前重新生成并审查 planner 拥有的 `plugin-prerelease-extension-shard` 矩阵输出,来源为 `.github/workflows/plugin-prerelease.yml`,确保发布说明不会描述过时的 CI 布局 +- 稳定版 macOS 发布就绪性还包括更新器表面: + - GitHub 发布最终必须包含打包后的 `.zip`、`.dmg` 和 `.dSYM.zip` + - 发布后,`main` 上的 `appcast.xml` 必须指向新的稳定版 zip + - 打包后的应用必须保留非 debug bundle id、非空 Sparkle feed URL,以及达到或高于该发布版本规范 Sparkle 构建下限的 `CFBundleVersion` -## 发布测试盒 +## 发布测试箱 -`Full Release Validation` 是操作员从一个入口启动所有预发布测试的方式。对于快速移动分支上的固定提交证明,使用该辅助工具,确保每个子工作流都从固定在目标 SHA 的临时分支运行: +`Full Release Validation` 是操作员从一个入口点启动所有发布前测试的方式。对于快速变化分支上的固定提交证明,请使用 helper,确保每个子工作流都从固定在目标 SHA 的临时分支运行: ```bash pnpm ci:full-release --sha ``` -该辅助工具会推送 `release-ci/-...`,从该分支分发 `Full Release Validation` 并传入 `ref=`,验证每个子工作流的 `headSha` 都匹配目标,然后删除临时分支。这避免了意外证明较新的 `main` 子运行。 +该 helper 会推送 `release-ci/-...`,从该分支分发 `Full Release Validation` 并传入 `ref=`,验证每个子工作流的 `headSha` 都匹配目标,然后删除临时分支。这样可以避免意外证明更新的 `main` 子运行。 -对于发布分支或标签验证,请从受信任的 `main` 工作流 ref 运行它,并将发布分支或标签作为 `ref` 传入: +对于发布分支或标签验证,请从可信的 `main` 工作流 ref 运行,并将发布分支或标签作为 `ref` 传入: ```bash gh workflow run full-release-validation.yml \ @@ -158,19 +159,19 @@ gh workflow run full-release-validation.yml \ -f evidence_package_spec=openclaw@YYYY.M.D-beta.N ``` -该工作流会解析目标 ref,使用 `target_ref=` 触发手动 `CI`,触发 `OpenClaw Release Checks`,并在 `release_profile=full` 且 `rerun_group=all` 时,或设置了 `npm_telegram_package_spec` 时,触发独立的 Telegram 包 E2E。随后 `OpenClaw Release Checks` 会扩展运行安装冒烟、跨 OS 发布检查、live/E2E Docker 发布路径覆盖、带 Telegram 包 QA 的 Package Acceptance、QA Lab parity、live Matrix 和 live Telegram。完整运行只有在 `Full Release Validation` 摘要显示 `normal_ci` 和 `release_checks` 成功时才可接受。在 full/all 模式下,`npm_telegram` 子项也必须成功;在 full/all 之外,除非提供了已发布的 `npm_telegram_package_spec`,否则会跳过它。最终验证器摘要会包含每个子运行的最慢作业表,因此发布经理无需下载日志即可看到当前关键路径。 -请参阅[完整发布验证](/zh-CN/reference/full-release-validation),了解完整阶段矩阵、精确工作流作业名称、stable 与 full 配置差异、产物以及聚焦重跑句柄。 -子工作流从运行 `Full Release Validation` 的受信任 ref 触发,通常是 `--ref main`,即使目标 `ref` 指向较旧的发布分支或标签也是如此。没有单独的完整发布验证 workflow-ref 输入;通过选择工作流运行 ref 来选择受信任的 harness。 -不要在移动的 `main` 上使用 `--ref main -f ref=` 来证明精确提交;原始提交 SHA 不能作为工作流 dispatch ref,因此请使用 `pnpm ci:full-release --sha ` 创建固定的临时分支。 +该工作流会解析目标 ref,以 `target_ref=` 分派手动 `CI`,分派 `OpenClaw Release Checks`,并在 `release_profile=full` 且 `rerun_group=all` 时,或设置了 `npm_telegram_package_spec` 时,分派独立 package Telegram E2E。随后,`OpenClaw Release Checks` 会展开安装 smoke、跨 OS 发布检查、live/E2E Docker 发布路径覆盖、带 Telegram package QA 的 Package Acceptance、QA Lab parity、live Matrix 和 live Telegram。只有当 `Full Release Validation` 摘要显示 `normal_ci` 和 `release_checks` 均成功时,完整运行才可接受。在 full/all 模式下,`npm_telegram` 子项也必须成功;在 full/all 之外,除非提供了已发布的 `npm_telegram_package_spec`,否则它会被跳过。最终验证器摘要会包含每个子运行的最慢 job 表,因此发布经理无需下载日志即可查看当前关键路径。 +请参阅 [Full release validation](/zh-CN/reference/full-release-validation),了解完整阶段矩阵、精确工作流 job 名称、stable 与 full 配置差异、工件和聚焦重跑句柄。 +子工作流会从运行 `Full Release Validation` 的可信 ref 分派,通常是 `--ref main`,即使目标 `ref` 指向较旧的发布分支或标签也是如此。没有单独的 Full Release Validation workflow-ref 输入;通过选择工作流运行 ref 来选择可信 harness。 +不要在移动的 `main` 上使用 `--ref main -f ref=` 来证明精确 commit;原始 commit SHA 不能作为工作流分派 ref,因此请使用 `pnpm ci:full-release --sha ` 创建固定的临时分支。 -使用 `release_profile` 选择 live/provider 覆盖范围: +使用 `release_profile` 选择 live/提供商覆盖范围: - `minimum`:最快的发布关键 OpenAI/core live 和 Docker 路径 -- `stable`:minimum 加上用于发布批准的稳定提供商/后端覆盖 -- `full`:stable 加上广泛的 advisory 提供商/媒体覆盖 +- `stable`:minimum 加上用于发布批准的稳定提供商/backend 覆盖 +- `full`:stable 加上广泛的 advisory 提供商/media 覆盖 -`OpenClaw Release Checks` 使用受信任的工作流 ref 将目标 ref 解析一次为 `release-package-under-test`,并在发布路径 Docker 检查和 Package Acceptance 中复用该产物。这会让所有面向包的 box 使用相同字节,并避免重复构建包。 -当设置了 repo/org 变量时,跨 OS OpenAI 安装冒烟使用 `OPENCLAW_CROSS_OS_OPENAI_MODEL`,否则使用 `openai/gpt-5.4`,因为该 lane 证明的是包安装、新手引导、Gateway 网关启动,以及一次 live 智能体轮次,而不是基准测试最慢的默认模型。更广泛的 live 提供商矩阵仍然是模型特定覆盖的位置。 +`OpenClaw Release Checks` 使用可信工作流 ref 将目标 ref 解析一次为 `release-package-under-test`,并在发布路径 Docker 检查和 Package Acceptance 中复用该工件。这会让所有面向 package 的 boxes 使用相同字节,并避免重复构建 package。 +跨 OS OpenAI 安装 smoke 在设置了 repo/org 变量时使用 `OPENCLAW_CROSS_OS_OPENAI_MODEL`,否则使用 `openai/gpt-5.4`,因为该 lane 证明的是 package 安装、新手引导、Gateway 网关启动和一次 live 智能体回合,而不是基准测试最慢的默认模型。更广泛的 live 提供商矩阵仍然是模型特定覆盖的位置。 根据发布阶段使用这些变体: @@ -202,23 +203,23 @@ gh workflow run full-release-validation.yml \ -f npm_telegram_provider_mode=mock-openai ``` -不要把完整 umbrella 用作聚焦修复后的第一次重跑。如果一个 box 失败,请使用失败的子工作流、作业、Docker lane、包配置、模型提供商或 QA lane 作为下一次证明。只有当修复更改了共享发布编排,或让先前的全 box 证据过期时,才再次运行完整 umbrella。umbrella 的最终验证器会重新检查记录的子工作流运行 id,因此在子工作流成功重跑后,只需重跑失败的 `Verify full validation` 父作业。 +不要把完整 umbrella 作为聚焦修复后的首次重跑。如果某个 box 失败,请使用失败的子工作流、job、Docker lane、package profile、模型提供商或 QA lane 作为下一次证明。只有当修复更改了共享发布编排,或让之前的 all-box 证据过期时,才再次运行完整 umbrella。umbrella 的最终验证器会重新检查记录的子工作流运行 ID,因此在子工作流成功重跑后,只需重跑失败的 `Verify full validation` 父 job。 -对于有界恢复,将 `rerun_group` 传给 umbrella。`all` 是真正的发布候选运行,`ci` 仅运行正常 CI 子项,`plugin-prerelease` 仅运行仅发布插件子项,`release-checks` 运行每个发布 box,更窄的发布组是 `install-smoke`、`cross-os`、`live-e2e`、`package`、`qa`、`qa-parity`、`qa-live` 和 `npm-telegram`。 -聚焦的 `npm-telegram` 重跑需要 `npm_telegram_package_spec`;带 `release_profile=full` 的 full/all 运行使用 release-checks 包产物。 +对于有界恢复,请向 umbrella 传入 `rerun_group`。`all` 是真正的候选发布运行,`ci` 只运行普通 CI 子项,`plugin-prerelease` 只运行仅发布插件子项,`release-checks` 运行每个发布 box,更窄的发布组是 `install-smoke`、`cross-os`、`live-e2e`、`package`、`qa`、`qa-parity`、`qa-live` 和 `npm-telegram`。 +聚焦 `npm-telegram` 重跑需要 `npm_telegram_package_spec`;使用 `release_profile=full` 的 full/all 运行会使用 release-checks package 工件。 ### Vitest -Vitest box 是手动 `CI` 子工作流。手动 CI 会有意绕过 changed 作用域,并为发布候选强制运行正常测试图:Linux Node 分片、内置插件分片、渠道契约、Node 22 兼容性、`check`、`check-additional`、构建冒烟、文档检查、Python Skills、Windows、macOS、Android 和 Control UI i18n。 +Vitest box 是手动 `CI` 子工作流。手动 CI 会有意绕过 changed 范围界定,并为候选发布强制运行普通测试图:Linux Node 分片、内置插件分片、渠道契约、Node 22 兼容性、`check`、`check-additional`、构建 smoke、文档检查、Python skills、Windows、macOS、Android 和 Control UI i18n。 -用这个 box 回答“源代码树是否通过了完整的正常测试套件?”它不同于发布路径产品验证。需要保留的证据: +使用这个 box 回答“源代码树是否通过了完整的普通测试套件?”它不同于发布路径产品验证。需要保留的证据: -- `Full Release Validation` 摘要,显示触发的 `CI` 运行 URL -- `CI` 在精确目标 SHA 上为绿色 -- 调查回归时来自 CI 作业的失败或慢速分片名称 -- 当运行需要性能分析时,Vitest 时间产物,例如 `.artifacts/vitest-shard-timings.json` +- `Full Release Validation` 摘要,显示已分派的 `CI` 运行 URL +- 精确目标 SHA 上的 `CI` 运行为绿色 +- 调查回归时来自 CI jobs 的失败或缓慢分片名称 +- 当运行需要性能分析时,保留 Vitest timing 工件,例如 `.artifacts/vitest-shard-timings.json` -只有当发布需要确定性的正常 CI,但不需要 Docker、QA Lab、live、跨 OS 或包 box 时,才直接运行手动 CI: +仅当发布需要确定性的普通 CI,但不需要 Docker、QA Lab、live、跨 OS 或 package boxes 时,才直接运行手动 CI: ```bash gh workflow run ci.yml --ref main -f target_ref=release/YYYY.M.D @@ -226,52 +227,52 @@ gh workflow run ci.yml --ref main -f target_ref=release/YYYY.M.D ### Docker -Docker box 位于 `OpenClaw Release Checks` 中,通过 `openclaw-live-and-e2e-checks-reusable.yml`,再加上发布模式的 `install-smoke` 工作流。它通过打包的 Docker 环境验证发布候选,而不是仅验证源码级测试。 +Docker box 位于 `OpenClaw Release Checks` 中,通过 `openclaw-live-and-e2e-checks-reusable.yml` 以及发布模式的 `install-smoke` 工作流运行。它通过打包的 Docker 环境验证候选发布,而不只是源代码层面的测试。 发布 Docker 覆盖包括: -- 启用慢速 Bun 全局安装冒烟的完整安装冒烟 -- 按目标 SHA 准备/复用根 Dockerfile 冒烟镜像,QR、root/gateway 和 installer/Bun 冒烟作业作为单独的 install-smoke 分片运行 +- 启用慢速 Bun 全局安装 smoke 的完整安装 smoke +- 按目标 SHA 准备/复用根 Dockerfile smoke 镜像,并让 QR、root/gateway 和 installer/Bun smoke jobs 作为独立 install-smoke 分片运行 - 仓库 E2E lanes - 发布路径 Docker chunks:`core`、`package-update-openai`、`package-update-anthropic`、`package-update-core`、`plugins-runtime-plugins`、`plugins-runtime-services`、`plugins-runtime-install-a`、`plugins-runtime-install-b`、`plugins-runtime-install-c`、`plugins-runtime-install-d`、`plugins-runtime-install-e`、`plugins-runtime-install-f`、`plugins-runtime-install-g` 和 `plugins-runtime-install-h` -- 请求时在 `plugins-runtime-services` chunk 内的 OpenWebUI 覆盖 -- 拆分的内置插件安装/卸载 lanes,从 `bundled-plugin-install-uninstall-0` 到 `bundled-plugin-install-uninstall-23` -- 当发布检查包含 live 套件时,live/E2E 提供商套件和 Docker live 模型覆盖 +- 在请求时,`plugins-runtime-services` chunk 内的 OpenWebUI 覆盖 +- 拆分的内置插件安装/卸载 lanes:从 `bundled-plugin-install-uninstall-0` 到 `bundled-plugin-install-uninstall-23` +- 当发布检查包含 live suites 时,live/E2E 提供商套件和 Docker live 模型覆盖 -重跑前先使用 Docker 产物。发布路径调度器会上传 `.artifacts/docker-tests/`,其中包含 lane 日志、`summary.json`、`failures.json`、阶段耗时、调度器计划 JSON 和重跑命令。对于聚焦恢复,在可复用 live/E2E 工作流上使用 `docker_lanes=`,而不是重跑所有发布 chunks。生成的重跑命令会在可用时包含先前的 `package_artifact_run_id` 和已准备的 Docker 镜像输入,因此失败的 lane 可以复用同一个 tarball 和 GHCR 镜像。 +重跑前先使用 Docker 工件。发布路径 scheduler 会上传 `.artifacts/docker-tests/`,其中包含 lane 日志、`summary.json`、`failures.json`、阶段 timing、scheduler plan JSON 和重跑命令。对于聚焦恢复,请在可复用 live/E2E 工作流上使用 `docker_lanes=`,而不是重跑所有发布 chunks。生成的重跑命令会在可用时包含之前的 `package_artifact_run_id` 和已准备的 Docker 镜像输入,因此失败的 lane 可以复用同一个 tarball 和 GHCR 镜像。 ### QA Lab -QA Lab box 也是 `OpenClaw Release Checks` 的一部分。它是智能体行为和渠道级发布门禁,独立于 Vitest 和 Docker 包机制。 +QA Lab box 也是 `OpenClaw Release Checks` 的一部分。它是 agentic 行为和渠道级发布门禁,独立于 Vitest 和 Docker package 机制。 发布 QA Lab 覆盖包括: -- 使用 agentic parity pack 将 OpenAI 候选 lane 与 Opus 4.6 baseline 对比的 mock parity gate -- 使用 `qa-live-shared` 环境的快速 live Matrix QA 配置 +- mock parity lane,使用 agentic parity pack 将 OpenAI candidate lane 与 Opus 4.6 baseline 进行比较 +- 使用 `qa-live-shared` 环境的快速 live Matrix QA profile - 使用 Convex CI 凭证租约的 live Telegram QA lane -- 当发布 telemetry 需要明确本地证明时运行 `pnpm qa:otel:smoke` +- 当发布遥测需要显式本地证明时运行 `pnpm qa:otel:smoke` -用这个 box 回答“该发布在 QA 场景和 live 渠道流程中行为是否正确?”批准发布时请保留 parity、Matrix 和 Telegram lanes 的产物 URL。完整 Matrix 覆盖仍可作为手动分片 QA-Lab 运行,而不是默认发布关键 lane。 +使用这个 box 回答“该发布在 QA 场景和 live 渠道流程中的行为是否正确?”批准发布时保留 parity、Matrix 和 Telegram lanes 的工件 URL。完整 Matrix 覆盖仍然可作为手动分片 QA-Lab 运行使用,而不是默认的发布关键 lane。 ### Package -Package box 是可安装产品门禁。它由 `Package Acceptance` 和解析器 `scripts/resolve-openclaw-package-candidate.mjs` 支撑。解析器会将候选规范化为 Docker E2E 使用的 `package-under-test` tarball,验证包清单,记录包版本和 SHA-256,并让工作流 harness ref 与包源码 ref 分离。 +Package box 是可安装产品门禁。它由 `Package Acceptance` 和 resolver `scripts/resolve-openclaw-package-candidate.mjs` 支撑。resolver 会将候选项规范化为 Docker E2E 使用的 `package-under-test` tarball,验证 package inventory,记录 package 版本和 SHA-256,并将工作流 harness ref 与 package source ref 分开。 支持的候选来源: -- `source=npm`:`openclaw@beta`、`openclaw@latest` 或精确的 OpenClaw 发布版本 -- `source=ref`:使用选定的 `workflow_ref` harness 打包受信任的 `package_ref` 分支、标签或完整提交 SHA +- `source=npm`:`openclaw@beta`、`openclaw@latest`,或精确的 OpenClaw 发布版本 +- `source=ref`:使用选定的 `workflow_ref` harness 打包可信 `package_ref` 分支、标签或完整 commit SHA - `source=url`:下载需要 `package_sha256` 的 HTTPS `.tgz` - `source=artifact`:复用另一个 GitHub Actions 运行上传的 `.tgz` -`OpenClaw Release Checks` 使用 `source=artifact`、已准备的发布包产物、`suite_profile=custom`、`docker_lanes=doctor-switch update-channel-switch upgrade-survivor published-upgrade-survivor plugins-offline plugin-update`、`published_upgrade_survivor_baselines=all-since-2026.4.23`、`published_upgrade_survivor_scenarios=reported-issues` 和 `telegram_mode=mock-openai` 运行 Package Acceptance。Package Acceptance 会针对同一个已解析的 tarball 保持迁移、更新、陈旧插件依赖清理、离线插件 fixtures、插件更新和 Telegram 包 QA。升级矩阵覆盖从 `2026.4.23` 到 `latest` 的每个已由 npm 发布的稳定 baseline;对于已发货的候选,请使用带 `source=npm` 的 Package Acceptance;对于发布前有 SHA 支撑的本地 npm tarball,请使用 `source=ref`/`source=artifact`。它是大多数过去需要 Parallels 的包/更新覆盖的 GitHub 原生替代方案。跨 OS 发布检查对于 OS 特定的新手引导、安装器和平台行为仍然重要,但包/更新产品验证应优先使用 Package Acceptance。 +`OpenClaw Release Checks` 运行 Package Acceptance 时会使用 `source=artifact`、已准备的 release package 工件、`suite_profile=custom`、`docker_lanes=doctor-switch update-channel-switch upgrade-survivor published-upgrade-survivor plugins-offline plugin-update`、`published_upgrade_survivor_baselines=all-since-2026.4.23`、`published_upgrade_survivor_scenarios=reported-issues` 和 `telegram_mode=mock-openai`。Package Acceptance 会让迁移、更新、陈旧插件依赖清理、离线插件 fixtures、插件更新和 Telegram package QA 针对同一个已解析 tarball 运行。升级矩阵覆盖从 `2026.4.23` 到 `latest` 的每个稳定 npm 已发布 baseline;对于已经发布的候选项,请使用带 `source=npm` 的 Package Acceptance;对于发布前有 SHA 支撑的本地 npm tarball,请使用 `source=ref`/`source=artifact`。它是大多数 package/update 覆盖的 GitHub-native 替代方案,这些覆盖以前需要 Parallels。跨 OS 发布检查对于特定 OS 的新手引导、installer 和平台行为仍然重要,但 package/update 产品验证应优先使用 Package Acceptance。 -更新和插件验证的规范清单是[更新和插件测试](/zh-CN/help/testing-updates-plugins)。在判断哪个本地、Docker、Package Acceptance 或 release-check lane 能证明插件安装/更新、Doctor 清理或已发布包迁移变更时,请使用它。 -从每个稳定 `2026.4.23+` 包进行穷尽的已发布更新迁移,是单独的手动 `Update Migration` 工作流,不属于完整发布 CI。 +更新和插件验证的规范清单是 [更新和插件测试](/zh-CN/help/testing-updates-plugins)。在决定哪个本地、Docker、Package Acceptance 或 release-check lane 能证明插件安装/更新、Doctor 清理或已发布 package 迁移变更时使用它。 +从每个稳定 `2026.4.23+` package 进行的穷尽式已发布更新迁移,是单独的手动 `Update Migration` 工作流,不属于 Full Release CI。 -旧版 package-acceptance 宽容性是有意限时的。直到 `2026.4.25` 的包可以对已经发布到 npm 的元数据缺口使用兼容路径:tarball 中缺失的私有 QA 清单条目、缺失的 `gateway install --wrapper`、tarball 派生 git fixture 中缺失的补丁文件、缺失的持久化 `update.channel`、旧版插件安装记录位置、缺失的 marketplace 安装记录持久化,以及 `plugins update` 期间的配置元数据迁移。已发布的 `2026.4.26` 包可以对已经发货的本地构建元数据 stamp 文件发出警告。后续包必须满足现代包契约;这些相同缺口会导致发布验证失败。 +旧版 package-acceptance 宽容路径有意设置了时间边界。截至 `2026.4.25` 的 package 可以对已经发布到 npm 的元数据缺口使用兼容路径:tarball 中缺少私有 QA inventory entries、缺少 `gateway install --wrapper`、从 tarball 派生的 git fixture 中缺少 patch 文件、缺少已持久化的 `update.channel`、旧版插件安装记录位置、缺少 marketplace 安装记录持久化,以及 `plugins update` 期间的配置元数据迁移。已发布的 `2026.4.26` package 可以对已经发布的本地构建元数据 stamp 文件发出警告。之后的 package 必须满足现代 package 契约;这些相同缺口会导致发布验证失败。 -当发布问题涉及实际可安装包时,使用更广的 Package Acceptance 配置: +当发布问题与实际可安装 package 相关时,使用更广的 Package Acceptance profiles: ```bash gh workflow run package-acceptance.yml \ @@ -283,31 +284,29 @@ gh workflow run package-acceptance.yml \ -f published_upgrade_survivor_baseline=openclaw@2026.4.26 ``` -常用包配置: +常见 package profiles: -- `smoke`:快速包安装/渠道/智能体、Gateway 网关网络和配置重载 lanes -- `package`:不带 live ClawHub 的安装/更新/插件包契约;这是 release-check 默认值 -- `product`:`package` 加上 MCP 渠道、cron/subagent 清理、OpenAI Web 搜索和 OpenWebUI +- `smoke`:快速 package 安装/渠道/智能体、Gateway 网关网络和配置 reload lanes +- `package`:不包含 live ClawHub 的安装/更新/插件 package 契约;这是 release-check 默认值 +- `product`:`package` 加上 MCP 渠道、cron/subagent 清理、OpenAI web 搜索和 OpenWebUI - `full`:带 OpenWebUI 的 Docker 发布路径 chunks - `custom`:用于聚焦重跑的精确 `docker_lanes` 列表 -对于候选包的 Telegram 验证,请在 Package Acceptance 上启用 `telegram_mode=mock-openai` 或 +对于包候选版的 Telegram 验证,请在 Package Acceptance 上启用 `telegram_mode=mock-openai` 或 `telegram_mode=live-frontier`。该工作流会将解析后的 `package-under-test` tarball 传入 Telegram 通道;独立的 Telegram 工作流仍接受已发布的 npm 规范,用于发布后检查。 -## 发布发布自动化 +## 发布自动化 `OpenClaw Release Publish` 是常规的变更型发布入口点。它会按发布所需的顺序编排可信发布者工作流: 1. 检出发布标签并解析其提交 SHA。 2. 验证该标签可从 `main` 或 `release/*` 访问。 3. 运行 `pnpm plugins:sync:check`。 -4. 调度 `Plugin NPM Release`,并使用 `publish_scope=all-publishable` 和 - `ref=`。 +4. 使用 `publish_scope=all-publishable` 和 `ref=` 调度 `Plugin NPM Release`。 5. 使用相同的范围和 SHA 调度 `Plugin ClawHub Release`。 -6. 使用发布标签、npm dist-tag 和已保存的 `preflight_run_id` 调度 - `OpenClaw NPM Release`。 +6. 使用发布标签、npm dist-tag 和保存的 `preflight_run_id` 调度 `OpenClaw NPM Release`。 Beta 发布示例: @@ -329,7 +328,7 @@ gh workflow run openclaw-release-publish.yml \ -f npm_dist_tag=alpha ``` -将稳定版发布到默认的 beta dist-tag: +稳定版发布到默认的 beta dist-tag: ```bash gh workflow run openclaw-release-publish.yml \ @@ -339,7 +338,7 @@ gh workflow run openclaw-release-publish.yml \ -f npm_dist_tag=beta ``` -直接将稳定版提升到 `latest` 是显式操作: +直接提升稳定版到 `latest` 需要显式执行: ```bash gh workflow run openclaw-release-publish.yml \ @@ -349,9 +348,7 @@ gh workflow run openclaw-release-publish.yml \ -f npm_dist_tag=latest ``` -仅在聚焦修复或重新发布工作中使用较低层级的 `Plugin NPM Release` 和 `Plugin ClawHub Release` 工作流。对于选定的插件修复,请向 -`OpenClaw Release Publish` 传入 `plugin_publish_scope=selected` 和 -`plugins=@openclaw/name`;或者在不得发布 OpenClaw 包时,直接调度子工作流。 +仅在聚焦修复或重新发布工作时使用较底层的 `Plugin NPM Release` 和 `Plugin ClawHub Release` 工作流。对于选定的插件修复,将 `plugin_publish_scope=selected` 和 `plugins=@openclaw/name` 传给 `OpenClaw Release Publish`,或者在不得发布 OpenClaw 包时直接调度子工作流。 ## NPM 工作流输入 @@ -360,55 +357,52 @@ gh workflow run openclaw-release-publish.yml \ - `tag`:必需的发布标签,例如 `v2026.4.2`、`v2026.4.2-1`,或 `v2026.4.2-alpha.1` 或 `v2026.4.2-beta.1`;当 `preflight_only=true` 时,它也可以是当前完整的 40 字符工作流分支提交 SHA,用于仅验证的预检 - `preflight_only`:`true` 表示仅验证/构建/打包,`false` 表示真实发布路径 -- `preflight_run_id`:真实发布路径必需,这样工作流会复用成功预检运行准备好的 tarball +- `preflight_run_id`:真实发布路径必需,以便工作流复用成功预检运行中准备好的 tarball - `npm_dist_tag`:发布路径的 npm 目标标签;默认为 `beta` `OpenClaw Release Publish` 接受这些由操作员控制的输入: -- `tag`:必需的发布标签;必须已存在 -- `preflight_run_id`:成功的 `OpenClaw NPM Release` 预检运行 id; - 当 `publish_openclaw_npm=true` 时必需 +- `tag`:必需的发布标签;必须已经存在 +- `preflight_run_id`:成功的 `OpenClaw NPM Release` 预检运行 ID;当 `publish_openclaw_npm=true` 时必需 - `npm_dist_tag`:OpenClaw 包的 npm 目标标签 -- `plugin_publish_scope`:默认为 `all-publishable`;仅在聚焦修复工作中使用 `selected` -- `plugins`:当 `plugin_publish_scope=selected` 时,以逗号分隔的 `@openclaw/*` 包名 -- `publish_openclaw_npm`:默认为 `true`;仅在将该工作流用作仅插件修复编排器时设置为 `false` +- `plugin_publish_scope`:默认为 `all-publishable`;仅在聚焦修复工作时使用 `selected` +- `plugins`:当 `plugin_publish_scope=selected` 时使用的逗号分隔 `@openclaw/*` 包名 +- `publish_openclaw_npm`:默认为 `true`;仅在将该工作流用作纯插件修复编排器时设为 `false` `OpenClaw Release Checks` 接受这些由操作员控制的输入: -- `ref`:要验证的分支、标签或完整提交 SHA。带密钥的检查要求解析后的提交可从 OpenClaw 分支或发布标签访问。 +- `ref`:要验证的分支、标签或完整提交 SHA。携带密钥的检查要求解析后的提交可从 OpenClaw 分支或发布标签访问。 规则: - 稳定版和修正版标签可以发布到 `beta` 或 `latest` - Alpha 预发布标签只能发布到 `alpha` - Beta 预发布标签只能发布到 `beta` -- 对于 `OpenClaw NPM Release`,仅当 `preflight_only=true` 时才允许完整提交 SHA 输入 +- 对于 `OpenClaw NPM Release`,仅当 `preflight_only=true` 时才允许输入完整提交 SHA - `OpenClaw Release Checks` 和 `Full Release Validation` 始终仅用于验证 -- 真实发布路径必须使用预检期间使用的同一个 `npm_dist_tag`; - 工作流会在发布继续前验证该元数据 +- 真实发布路径必须使用预检期间使用的同一个 `npm_dist_tag`;工作流会在继续发布前验证该元数据 -## 稳定 npm 发布序列 +## 稳定版 npm 发布流程 -切稳定 npm 发布时: +切稳定版 npm 发布时: 1. 使用 `preflight_only=true` 运行 `OpenClaw NPM Release` - - 在标签存在之前,你可以使用当前完整的工作流分支提交 SHA,对预检工作流执行仅验证的演练 + - 在标签存在之前,你可以使用当前完整的工作流分支提交 SHA,对预检工作流进行仅验证的试运行 2. 对于常规的 beta 优先流程,选择 `npm_dist_tag=beta`;仅当你有意直接发布稳定版时才选择 `latest` -3. 当你希望通过一个手动工作流获得常规 CI 以及实时 prompt cache、Docker、QA Lab、Matrix 和 Telegram 覆盖时,在发布分支、发布标签或完整提交 SHA 上运行 `Full Release Validation` -4. 如果你有意只需要确定性的常规测试图,请改为在发布 ref 上运行手动 `CI` 工作流 +3. 当你希望通过一个手动工作流获得常规 CI 加上实时 prompt cache、Docker、QA Lab、Matrix 和 Telegram 覆盖时,在发布分支、发布标签或完整提交 SHA 上运行 `Full Release Validation` +4. 如果你明确只需要确定性的常规测试图,请改为在发布 ref 上运行手动 `CI` 工作流 5. 保存成功的 `preflight_run_id` -6. 使用相同的 `tag`、相同的 `npm_dist_tag` 和已保存的 `preflight_run_id` 运行 `OpenClaw Release Publish`;它会先将外部化插件发布到 npm 和 ClawHub,再提升 OpenClaw npm 包 -7. 如果发布落在 `beta` 上,请使用私有 +6. 使用相同的 `tag`、相同的 `npm_dist_tag` 和保存的 `preflight_run_id` 运行 `OpenClaw Release Publish`;它会先将外部化插件发布到 npm 和 ClawHub,再提升 OpenClaw npm 包 +7. 如果发布落在 `beta` 上,请使用私有的 `openclaw/releases-private/.github/workflows/openclaw-npm-dist-tags.yml` - 工作流将该稳定版本从 `beta` 提升到 `latest` -8. 如果发布有意直接发布到 `latest`,并且 `beta` - 应立即跟随同一个稳定构建,请使用同一个私有工作流将两个 dist-tag 都指向该稳定版本,或让其定时自愈同步稍后移动 `beta` + 工作流,将该稳定版本从 `beta` 提升到 `latest` +8. 如果发布有意直接发布到 `latest`,并且 `beta` 应立即跟随同一个稳定版构建,请使用同一个私有工作流将两个 dist-tag 都指向该稳定版本,或让其定时自修复同步稍后移动 `beta` -出于安全考虑,dist-tag 变更位于私有仓库中,因为它仍需要 `NPM_TOKEN`,而公共仓库保持仅使用 OIDC 发布。 +出于安全考虑,dist-tag 变更位于私有仓库中,因为它仍然需要 `NPM_TOKEN`,而公共仓库保持仅使用 OIDC 发布。 这让直接发布路径和 beta 优先提升路径都保持有文档记录,并且对操作员可见。 -如果维护者必须回退到本地 npm 身份验证,请仅在专用 tmux 会话内运行任何 1Password CLI(`op`)命令。不要直接从主 agent shell 调用 `op`;将其限制在 tmux 内可以让提示、警报和 OTP 处理可观察,并防止反复触发主机警报。 +如果维护者必须回退到本地 npm 认证,请仅在专用 tmux 会话中运行任何 1Password CLI(`op`)命令。不要从主 agent shell 直接调用 `op`;将其保留在 tmux 内可让提示、告警和 OTP 处理可观察,并防止重复的主机告警。 ## 公共参考