diff --git a/docs/zh-CN/ci.md b/docs/zh-CN/ci.md index f93047e33..d4d8e52a0 100644 --- a/docs/zh-CN/ci.md +++ b/docs/zh-CN/ci.md @@ -1,94 +1,94 @@ --- read_when: - - 你需要了解为什么某个 CI 作业运行了或没有运行 - - 你正在调试一个失败的 GitHub Actions 检查 - - 你正在协调发布验证的运行或重新运行 - - 你正在更改 ClawSweeper 分发或 GitHub 活动转发 -summary: CI 作业图、范围门禁、发布总括流程和本地命令等价项 + - 你需要了解某个 CI 作业为什么运行或没有运行 + - 你正在调试一项失败的 GitHub Actions 检查 + - 你正在协调一次发布验证运行或重新运行 + - 你正在更改 ClawSweeper 调度或 GitHub 活动转发 +summary: 持续集成作业图、范围门禁、发布总括项和本地等效命令 title: CI 流水线 x-i18n: - generated_at: "2026-05-04T04:57:41Z" + generated_at: "2026-05-04T22:29:55Z" model: gpt-5.5 provider: openai - source_hash: 72959d0feaf1339f01c9da263153fd89cc4727da6f928933819931991222714d + source_hash: 88d0f7f6cd61d550ec399e8250f685929637cd28638e77aa5a5558775767cac6 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 上运行 | +| `preflight` | 检测仅文档变更、变更作用域、变更扩展,并构建 CI 清单 | 始终在非草稿推送和 PR 上运行 | | `security-scm-fast` | 通过 `zizmor` 进行私钥检测和工作流审计 | 始终在非草稿推送和 PR 上运行 | -| `security-dependency-audit` | 针对 npm advisories 执行无依赖的生产 lockfile 审计 | 始终在非草稿推送和 PR 上运行 | -| `security-fast` | 快速安全作业的必需聚合项 | 始终在非草稿推送和 PR 上运行 | -| `check-dependencies` | 生产 Knip 仅依赖检查,加上未使用文件 allowlist 守卫 | Node 相关变更 | +| `security-dependency-audit` | 针对 npm 安全公告进行无依赖的生产 lockfile 审计 | 始终在非草稿推送和 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、守卫、测试类型和严格 smoke | Node 相关变更 | -| `check-additional` | 架构、分片边界/提示漂移、插件守卫、包边界和 Gateway 网关 watch | Node 相关变更 | -| `build-smoke` | 已构建 CLI smoke 测试和启动内存 smoke | 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 兼容性构建和 smoke 通道 | 发布的手动 CI 调度 | -| `check-docs` | 文档格式化、lint 和断链检查 | 文档已变更 | -| `skills-python` | 针对 Python 支持的 Skills 运行 Ruff + pytest | Python 技能相关变更 | -| `checks-windows` | Windows 特定的进程/路径测试,以及共享运行时导入说明符回归检查 | Windows 相关变更 | -| `macos-node` | 使用共享已构建产物的 macOS TypeScript 测试通道 | macOS 相关变更 | +| `checks-node-compat-node22` | Node 22 兼容性构建和冒烟通道 | 用于发布的手动 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` | 使用 mock provider、deep-profile 和 GPT 5.4 实时通道的每日/按需 Kova 运行时性能报告 | 定时和手动调度 | +| `android` | 两种 flavor 的 Android 单元测试,以及一次 debug APK 构建 | Android 相关变更 | +| `test-performance-agent` | 受信活动后的每日 Codex 慢测试优化 | 主 CI 成功或手动分发 | +| `openclaw-performance` | 按日/按需生成 Kova 运行时性能报告,包含 mock provider、深度 profile 和 GPT 5.4 live 通道 | 定时和手动分发 | ## 快速失败顺序 -1. `preflight` 决定哪些通道实际存在。`docs-scope` 和 `changed-scope` 逻辑是此作业中的步骤,不是独立作业。 +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 通道重叠运行,因此下游消费者可以在共享构建就绪后立即开始。 +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` 引用上时,GitHub 可能会将被取代的作业标记为 `cancelled`。除非同一引用的最新运行也失败,否则将其视为 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` 中的单元测试覆盖。手动调度会跳过变更范围检测,并让 preflight 清单表现得像每个已限定范围的区域都发生了变更。 +作用域逻辑位于 `scripts/ci-changed-scope.mjs`,并由 `src/scripts/ci-changed-scope.test.ts` 中的单元测试覆盖。手动分发会跳过变更作用域检测,并使 preflight 清单表现得像每个有作用域的区域都已变更。 -- **CI 工作流编辑**会验证 Node CI 图和工作流 lint,但不会单独强制 Windows、Android 或 macOS 原生构建;这些平台通道仍限定于平台源代码变更。 -- **仅 CI 路由编辑、选定的低成本核心测试 fixture 编辑,以及窄范围插件契约 helper/测试路由编辑**使用快速的仅 Node 清单路径:`preflight`、安全检查和单个 `checks-fast-core` 任务。当变更仅限于该快速任务直接覆盖的路由或 helper 表面时,该路径会跳过构建产物、Node 22 兼容性、渠道契约、完整核心分片、内置插件分片和额外守卫矩阵。 -- **Windows Node 检查**限定于 Windows 特定的进程/路径包装器、npm/pnpm/UI runner helper、包管理器配置,以及执行该通道的 CI 工作流表面;无关源代码、插件、安装 smoke 和仅测试变更仍留在 Linux Node 通道上。 +- **CI 工作流编辑**会验证 Node CI 图和工作流 lint,但其本身不会强制 Windows、Android 或 macOS 原生构建;这些平台通道仍限定于平台源码变更。 +- **仅 CI 路由编辑、选定的廉价核心测试 fixture 编辑,以及范围较窄的插件契约 helper/测试路由编辑**会使用快速 Node 专用清单路径:`preflight`、security,以及单个 `checks-fast-core` 任务。当变更仅限于该快速任务直接覆盖的路由或 helper 表面时,该路径会跳过构建产物、Node 22 兼容性、渠道契约、完整核心分片、内置插件分片和额外守卫矩阵。 +- **Windows Node 检查**限定于 Windows 专用进程/路径包装器、npm/pnpm/UI runner helper、包管理器配置,以及执行该通道的 CI 工作流表面;无关源码、插件、安装冒烟和仅测试变更仍停留在 Linux Node 通道上。 -最慢的 Node 测试族被拆分或平衡,以便每个作业保持较小规模而不超额预留 runner:渠道契约作为三个加权分片运行,核心单元 fast/support 通道单独运行,核心运行时基础设施拆分为 state 和 process/config 分片,auto-reply 作为平衡 worker 运行(reply 子树拆分为 agent-runner、dispatch 和 commands/state-routing 分片),agentic Gateway 网关/服务器配置拆分到 chat/auth/model/http-plugin/runtime/startup 通道,而不是等待已构建产物。广泛的浏览器、QA、媒体和杂项插件测试使用各自专用的 Vitest 配置,而不是共享的插件 catch-all。包含模式分片使用 CI 分片名称记录计时条目,因此 `.artifacts/vitest-shard-timings.json` 可以区分完整配置和过滤后的分片。`check-additional` 将包边界编译/canary 工作保持在一起,并将运行时拓扑架构与 Gateway 网关 watch 覆盖分开;边界守卫列表被条带化到四个矩阵分片中,每个分片并发运行选定的独立守卫并打印每项检查的计时,包括 `pnpm prompt:snapshots:check`,因此 Codex 运行时 happy-path 提示漂移会被固定到导致它的 PR。Gateway 网关 watch、渠道测试和核心 support-boundary 分片会在 `dist/` 和 `dist-runtime/` 已经构建完成后,在 `build-artifacts` 内并发运行。 +最慢的 Node 测试族会被拆分或平衡,使每个作业保持较小规模而不过度预留 runner:渠道契约作为三个加权分片运行,核心单元 fast/support 通道单独运行,核心运行时基础设施在 state 和 process/config 分片之间拆分,auto-reply 作为平衡 worker 运行(reply 子树拆分为 agent-runner、dispatch 和 commands/state-routing 分片),而 agentic gateway/server 配置会跨 chat/auth/model/http-plugin/runtime/startup 通道拆分,而不是等待构建产物。广泛的浏览器、QA、媒体和杂项插件测试使用各自专用的 Vitest 配置,而不是共享插件 catch-all。include-pattern 分片会使用 CI 分片名称记录计时条目,因此 `.artifacts/vitest-shard-timings.json` 可以区分整个配置和过滤后的分片。`check-additional` 将包边界编译/canary 工作保持在一起,并把运行时拓扑架构与 Gateway 网关 watch 覆盖分离;边界守卫列表按四个矩阵分片条带化,每个分片并发运行选定的独立守卫并打印每项检查的计时,包括 `pnpm prompt:snapshots:check`,这样 Codex 运行时 happy-path 提示词漂移会固定到造成它的 PR。Gateway 网关 watch、渠道测试和核心 support-boundary 分片会在 `dist/` 和 `dist-runtime/` 已构建完成后,在 `build-artifacts` 内并发运行。 -Android CI 会同时运行 `testPlayDebugUnitTest` 和 `testThirdPartyDebugUnitTest`,然后构建 Play debug APK。third-party flavor 没有单独的源集或清单;它的单元测试通道仍会使用 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 添加新的未审查未使用文件或留下过期 allowlist 条目时,未使用文件守卫会失败,同时保留 Knip 无法静态解析的有意动态插件、生成内容、构建、实时测试和包桥接表面。 +`check-dependencies` 分片运行 `pnpm deadcode:dependencies`(一个生产 Knip 依赖专用检查,固定到最新 Knip 版本,并在 `dlx` 安装时禁用 pnpm 的最小发布年龄)和 `pnpm deadcode:unused-files`,后者会将 Knip 的生产未使用文件发现结果与 `scripts/deadcode-unused-files.allowlist.mjs` 比较。当 PR 添加新的未审查未使用文件或留下过期允许列表条目时,未使用文件守卫会失败,同时保留 Knip 无法静态解析的有意动态插件、生成内容、构建、live-test 和包桥接表面。 ## ClawSweeper 活动转发 -`.github/workflows/clawsweeper-dispatch.yml` 是从 OpenClaw 仓库活动到 ClawSweeper 的目标侧桥接。它不会签出或执行不受信任的拉取请求代码。该工作流会从 `CLAWSWEEPER_APP_PRIVATE_KEY` 创建 GitHub App 令牌,然后向 `openclaw/clawsweeper` 调度紧凑的 `repository_dispatch` payload。 +`.github/workflows/clawsweeper-dispatch.yml` 是从 OpenClaw 仓库活动到 ClawSweeper 的目标侧桥接。它不会检出或执行不受信任的拉取请求代码。该工作流会从 `CLAWSWEEPER_APP_PRIVATE_KEY` 创建 GitHub App 令牌,然后向 `openclaw/clawsweeper` 分发紧凑的 `repository_dispatch` payload。 该工作流有四个通道: -- `clawsweeper_item` 用于精确的 issue 和拉取请求 review 请求; -- `clawsweeper_comment` 用于 issue 评论中的显式 ClawSweeper 命令; +- `clawsweeper_item` 用于精确的问题和拉取请求 review 请求; +- `clawsweeper_comment` 用于 issue comments 中的显式 ClawSweeper 命令; - `clawsweeper_commit_review` 用于 `main` 推送上的 commit 级 review 请求; - `github_activity` 用于 ClawSweeper 智能体可能检查的一般 GitHub 活动。 -`github_activity` 通道只转发规范化元数据:事件类型、动作、actor、仓库、item 编号、URL、标题、状态,以及存在评论或 review 时的短摘录。它有意避免转发完整 webhook body。`openclaw/clawsweeper` 中的接收工作流是 `.github/workflows/github-activity.yml`,它会将规范化事件发布到面向 ClawSweeper 智能体的 OpenClaw Gateway 网关 hook。 +`github_activity` 通道仅转发规范化元数据:事件类型、操作、actor、仓库、项目编号、URL、标题、状态,以及存在时评论或 review 的短摘录。它有意避免转发完整 webhook body。`openclaw/clawsweeper` 中的接收工作流是 `.github/workflows/github-activity.yml`,它会把规范化事件发布到用于 ClawSweeper 智能体的 OpenClaw Gateway 网关 hook。 -一般活动是观察,不是默认投递。ClawSweeper 智能体会在提示中接收 Discord 目标,并且只有当事件令人意外、可操作、有风险或对运维有用时,才应发布到 `#clawsweeper`。常规打开、编辑、bot 噪声、重复 webhook 噪声和正常 review 流量应产生 `NO_REPLY`。 +一般活动是观察,而不是默认投递。ClawSweeper 智能体会在提示词中收到 Discord 目标,并且只应在事件令人意外、可操作、有风险或对运维有用时发布到 `#clawsweeper`。常规打开、编辑、机器人 churn、重复 webhook 噪声和正常 review 流量应产生 `NO_REPLY`。 -在整个路径中,将 GitHub 标题、评论、body、review 文本、分支名称和 commit 消息都视为不受信任的数据。它们是用于摘要和分流的输入,不是工作流或智能体运行时的指令。 +在整个路径中,将 GitHub 标题、评论、正文、review 文本、分支名称和 commit 消息视为不受信任的数据。它们是摘要和分诊的输入,不是工作流或智能体运行时的指令。 -## 手动调度 +## 手动分发 -手动 CI 分派运行与普通 CI 相同的作业图,但会强制启用所有非 Android 范围的通道:Linux Node 分片、内置插件分片、渠道契约、Node 22 兼容性、`check`、`check-additional`、构建 smoke、文档检查、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 作用域的通道: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` 工作流时运行。 -手动运行使用唯一的并发组,因此候选发布的完整套件不会被同一 ref 上的另一个推送或 PR 运行取消。可选的 `target_ref` 输入允许受信任的调用方使用所选分派 ref 中的工作流文件,针对某个分支、标签或完整提交 SHA 运行该作业图。 +手动运行使用唯一的并发组,因此发布候选的完整套件不会被同一 ref 上的另一次 push 或 PR 运行取消。可选的 `target_ref` 输入允许受信任的调用方针对某个分支、标签或完整提交 SHA 运行该作业图,同时使用所选调度 ref 中的工作流文件。 ```bash gh workflow run ci.yml --ref release/YYYY.M.D @@ -100,15 +100,15 @@ 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` | +| `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-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` | +| `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,9 +135,9 @@ 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 Performance +## OpenClaw 性能 -`OpenClaw Performance` 是产品/运行时性能工作流。它每天在 `main` 上运行,也可以手动分派: +`OpenClaw Performance` 是产品/运行时性能工作流。它每天在 `main` 上运行,也可以手动调度: ```bash gh workflow run openclaw-performance.yml --ref main -f profile=diagnostic -f repeat=3 @@ -145,25 +145,25 @@ gh workflow run openclaw-performance.yml --ref main -f profile=smoke -f repeat=1 gh workflow run openclaw-performance.yml --ref main -f target_ref=v2026.5.2 -f profile=diagnostic -f repeat=3 ``` -手动分派通常对工作流 ref 进行基准测试。设置 `target_ref` 可用当前工作流实现对发布标签或其他分支进行基准测试。已发布报告路径和 latest 指针按被测试 ref 建键,每个 `index.md` 会记录被测试 ref/SHA、工作流 ref/SHA、Kova ref、profile、通道认证模式、模型、重复次数和场景过滤器。 +手动调度通常会对工作流 ref 进行基准测试。设置 `target_ref` 可使用当前工作流实现对发布标签或其他分支进行基准测试。发布的报告路径和 latest 指针按被测试的 ref 建立键名,每个 `index.md` 都记录被测试的 ref/SHA、工作流 ref/SHA、Kova ref、profile、通道鉴权模式、模型、重复次数和场景过滤器。 -该工作流从固定发布版本安装 OCM,并从 `openclaw/Kova` 按固定的 `kova_ref` 输入安装 Kova,然后运行三个通道: +该工作流会从固定发布版本安装 OCM,并从 `openclaw/Kova` 的固定 `kova_ref` 输入安装 Kova,然后运行三个通道: -- `mock-provider`:使用确定性的假 OpenAI 兼容认证,针对本地构建运行时运行 Kova 诊断场景。 -- `mock-deep-profile`:针对启动、Gateway 网关和智能体回合热点进行 CPU/堆/跟踪剖析。 +- `mock-provider`:针对本地构建运行时运行 Kova 诊断场景,并使用确定性的假 OpenAI 兼容鉴权。 +- `mock-deep-profile`:针对启动、Gateway 网关和智能体回合热点进行 CPU/堆/跟踪分析。 - `live-gpt54`:真实的 OpenAI `openai/gpt-5.4` 智能体回合,在 `OPENAI_API_KEY` 不可用时跳过。 mock-provider 通道还会在 Kova 通过后运行 OpenClaw 原生源码探针:默认、钩子和 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//-//` 下。当前被测试 ref 指针会写入 `openclaw-performance//latest-.json`。 +每个通道都会上传 GitHub artifacts。配置 `CLAWGRIT_REPORTS_TOKEN` 后,该工作流还会将 `report.json`、`report.md`、包、`index.md` 和源码探针 artifacts 提交到 `openclaw/clawgrit-reports` 的 `openclaw-performance//-//` 下。当前被测试 ref 指针会写入为 `openclaw-performance//latest-.json`。 ## 完整发布验证 -`Full Release Validation` 是用于“发布前运行所有内容”的手动伞形工作流。它接受分支、标签或完整提交 SHA,使用该目标分派手动 `CI` 工作流,为仅发布使用的插件/包/静态/Docker 证明分派 `Plugin Prerelease`,并为安装 smoke、包验收、Docker 发布路径套件、live/E2E、OpenWebUI、QA Lab parity、Matrix 和 Telegram 通道分派 `OpenClaw Release Checks`。使用 `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` 工作流,调度 `Plugin Prerelease` 以获得仅发布使用的插件/包/静态/Docker 证明,并调度 `OpenClaw Release Checks` 以执行安装冒烟、包验收、跨 OS 包检查、QA Lab parity、Matrix 和 Telegram 通道。稳定/默认运行会把详尽的 live/E2E 和 Docker 发布路径覆盖保留在 `run_release_soak=true` 后面;`release_profile=full` 会强制启用该 soak 覆盖,以保持广泛的公告验证覆盖范围。当 `rerun_group=all` 且 `release_profile=full` 时,它还会针对来自 release checks 的 `release-package-under-test` artifact 运行 `NPM Telegram Beta E2E`。发布后,传递 `npm_telegram_package_spec` 可针对已发布的 npm 包重新运行同一 Telegram 包通道。 -请参阅[完整发布验证](/zh-CN/reference/full-release-validation),了解阶段矩阵、精确的工作流作业名称、profile 差异、构件以及聚焦重跑句柄。 +请参阅[完整发布验证](/zh-CN/reference/full-release-validation),了解阶段矩阵、精确的工作流作业名称、profile 差异、artifacts 和聚焦重新运行句柄。 -`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 \ @@ -173,35 +173,35 @@ gh workflow run openclaw-release-publish.yml \ -f npm_dist_tag=beta ``` -若要在快速变动的分支上获得固定提交证明,请使用辅助命令,而不是 `gh workflow run ... --ref main -f ref=`: +若要在快速移动的分支上提供固定提交证明,请使用辅助命令,而不是 `gh workflow run ... --ref main -f ref=`: ```bash 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/提供商范围。手动发布 workflow 默认使用 `stable`;只有在你有意需要广泛的建议性提供商/媒体矩阵时,才使用 `full`。 +`release_profile` 控制传递给发布检查的实时/提供商覆盖范围。手动发布工作流默认使用 `stable`;只有在你有意需要广泛的 advisory 提供商/媒体矩阵时,才使用 `full`。`run_release_soak` 控制稳定/默认发布检查是否运行穷尽式实时/E2E 和 Docker 发布路径 soak;`full` 会强制开启 soak。 -- `minimum` 保留最快的 OpenAI/核心发布关键 lane。 +- `minimum` 保留最快的 OpenAI/core 发布关键通道。 - `stable` 添加稳定的提供商/后端集合。 -- `full` 运行广泛的建议性提供商/媒体矩阵。 +- `full` 运行广泛的 advisory 提供商/媒体矩阵。 -总控 workflow 会记录已分派的子运行 ID,最终的 `Verify full validation` job 会重新检查当前子运行结论,并为每个子运行附加最慢 job 表。如果某个子 workflow 重新运行后变绿,只需重新运行父级验证器 job,即可刷新总控结果和耗时摘要。 +总控工作流会记录已分派的子运行 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`。这样,在完成聚焦修复后,可以将失败发布 box 的重新运行范围保持受限。 +对于恢复,`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,然后把该 artifact 同时传递给 live/E2E 发布路径 Docker workflow 和包验收 shard。这样可以让发布 box 之间的包字节保持一致,并避免在多个子 job 中重新打包同一个候选版本。 +`OpenClaw Release Checks` 使用受信任的工作流引用,将选定引用解析一次为 `release-package-under-test` tarball,然后把该产物传递给跨 OS 检查和 Package Acceptance,并在运行 soak 覆盖时传递给实时/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 shard +## 实时和 E2E 分片 -发布 live/E2E 子项保留广泛的原生 `pnpm test:live` 覆盖,但它通过 `scripts/test-live-shard.mjs` 以命名 shard 运行,而不是作为一个串行 job 运行: +发布实时/E2E 子项保留广泛的原生 `pnpm test:live` 覆盖,但它通过 `scripts/test-live-shard.mjs` 以命名分片运行,而不是一个串行作业: - `native-live-src-agents` - `native-live-src-gateway-core` -- 提供商过滤的 `native-live-src-gateway-profiles` job +- 提供商过滤的 `native-live-src-gateway-profiles` 作业 - `native-live-src-gateway-backends` - `native-live-test` - `native-live-extensions-a-k` @@ -209,59 +209,59 @@ GitHub 工作流分派 ref 必须是分支或标签,不能是原始提交 SHA - `native-live-extensions-openai` - `native-live-extensions-o-z-other` - `native-live-extensions-xai` -- 拆分的媒体音频/视频 shard,以及提供商过滤的音乐 shard +- 拆分的媒体音频/视频分片,以及提供商过滤的音乐分片 -这样可以保持相同的文件覆盖,同时让缓慢的 live 提供商失败更容易重新运行和诊断。聚合的 `native-live-extensions-o-z`、`native-live-extensions-media` 和 `native-live-extensions-media-music` shard 名称仍可用于手动一次性重新运行。 +这会保持相同的文件覆盖,同时让缓慢的实时提供商失败更容易重跑和诊断。聚合的 `native-live-extensions-o-z`、`native-live-extensions-media` 和 `native-live-extensions-media-music` 分片名称仍然可用于手动一次性重跑。 -原生 live 媒体 shard 运行在 `ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04` 中,该镜像由 `Live Media Runner Image` workflow 构建。该镜像预装了 `ffmpeg` 和 `ffprobe`;媒体 job 只在设置前验证这些二进制文件。将 Docker 支持的 live 套件保留在普通 Blacksmith runner 上,container job 并不适合启动嵌套 Docker 测试。 +原生实时媒体分片在 `ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04` 中运行,该镜像由 `Live Media Runner Image` 工作流构建。该镜像预装了 `ffmpeg` 和 `ffprobe`;媒体作业只在设置前验证这些二进制文件。将 Docker 支持的实时套件保留在普通 Blacksmith runner 上,容器作业不适合启动嵌套 Docker 测试。 -Docker 支持的 live 模型/后端 shard 会为每个选定提交使用单独的共享 `ghcr.io/openclaw/openclaw-live-test:` 镜像。live 发布 workflow 会构建并推送该镜像一次,然后 Docker live 模型、按提供商分片的 Gateway 网关、CLI 后端、ACP bind 和 Codex harness shard 会使用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行。Gateway 网关 Docker shard 带有显式的脚本级 `timeout` 上限,低于 workflow job 超时时间,因此卡住的容器或清理路径会快速失败,而不会耗尽整个 release-check 预算。如果这些 shard 独立重建完整源 Docker target,则说明发布运行配置错误,并会在重复镜像构建上浪费实际时间。 +Docker 支持的实时模型/后端分片会为每个选定提交使用单独的共享 `ghcr.io/openclaw/openclaw-live-test:` 镜像。实时发布工作流只构建并推送该镜像一次,然后 Docker 实时模型、按提供商分片的 Gateway 网关、CLI 后端、ACP 绑定和 Codex harness 分片会使用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行。Gateway 网关 Docker 分片带有明确的脚本级 `timeout` 上限,低于工作流作业超时,因此卡住的容器或清理路径会快速失败,而不是耗尽整个发布检查预算。如果这些分片独立重建完整源 Docker 目标,则表示发布运行配置错误,并会在重复镜像构建上浪费墙钟时间。 -## 包验收 +## Package Acceptance -当问题是“这个可安装的 OpenClaw 包是否能作为产品工作?”时,使用 `Package Acceptance`。它不同于普通 CI:普通 CI 验证源码树,而包验收会通过用户在安装或更新后使用的同一个 Docker E2E harness 来验证单个 tarball。 +当问题是“这个可安装的 OpenClaw 包作为产品是否可用?”时,使用 `Package Acceptance`。它不同于普通 CI:普通 CI 验证源码树,而包验收会通过用户在安装或更新后实际使用的同一个 Docker E2E harness 验证单个 tarball。 -### Job +### 作业 -1. `resolve_package` 检出 `workflow_ref`,解析一个包候选,写入 `.artifacts/docker-e2e-package/openclaw-current.tgz`,写入 `.artifacts/docker-e2e-package/package-candidate.json`,将二者作为 `package-under-test` artifact 上传,并在 GitHub step summary 中打印来源、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 会下载该 artifact,验证 tarball 清单,在需要时准备 package-digest Docker 镜像,并针对该包运行选定的 Docker lane,而不是打包 workflow checkout。当某个 profile 选择多个目标 `docker_lanes` 时,可复用 workflow 会准备一次包和共享镜像,然后将这些 lane 扇出为带有唯一 artifact 的并行目标 Docker job。 -3. `package_telegram` 可选择调用 `NPM Telegram Beta E2E`。当 `telegram_mode` 不是 `none` 时它会运行;如果 Package Acceptance 已解析出一个包,它会安装同一个 `package-under-test` artifact;独立 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 通道,而不是打包工作流检出内容。当某个配置文件选择多个定向 `docker_lanes` 时,可复用工作流会准备一次包和共享镜像,然后将这些通道扇出为并行的定向 Docker 作业,并使用唯一产物。 +3. `package_telegram` 可选调用 `NPM Telegram Beta E2E`。当 `telegram_mode` 不是 `none` 时运行,并在 Package Acceptance 已解析包时安装同一个 `package-under-test` 产物;独立 Telegram 分派仍可安装已发布的 npm spec。 +4. `summary` 会在包解析、Docker 验收或可选 Telegram 通道失败时使工作流失败。 ### 候选来源 -- `source=npm` 只接受 `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@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` 可选,但对外部共享 artifact 应提供。 +- `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 发布路径 chunk +- `full` — 带 OpenWebUI 的完整 Docker 发布路径分块 - `custom` — 精确的 `docker_lanes`;当 `suite_profile=custom` 时必需 -`package` profile 使用离线插件覆盖,因此已发布包验证不会受制于 live ClawHub 可用性。可选的 Telegram lane 在 `NPM Telegram Beta E2E` 中复用 `package-under-test` artifact,并保留已发布 npm spec 路径用于独立分派。 +`package` 配置文件使用离线插件覆盖,因此已发布包验证不会受实时 ClawHub 可用性影响。可选 Telegram 通道会在 `NPM Telegram Beta E2E` 中复用 `package-under-test` 产物,同时保留已发布 npm spec 路径用于独立分派。 -有关专用的更新和插件测试策略,包括本地命令、Docker lane、Package Acceptance 输入、发布默认值和失败分诊,请参阅[更新和插件测试](/zh-CN/help/testing-updates-plugins)。 +关于专用更新和插件测试策略,包括本地命令、Docker 通道、Package Acceptance 输入、发布默认值和失败分类,请参阅[更新和插件测试](/zh-CN/help/testing-updates-plugins)。 -Release checks 使用 `source=artifact`、准备好的发布包 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。这样可以在同一个已解析包 tarball 上完成包迁移、更新、过期插件依赖清理、已配置插件安装修复、离线插件、插件更新和 Telegram 证明。在 Full Release Validation 或 OpenClaw Release Checks 上设置 `package_acceptance_package_spec`,即可针对已发布的 npm 包运行同一矩阵,而不是针对 SHA 构建的 artifact 运行。Cross-OS 发布检查仍覆盖特定 OS 的新手引导、安装器和平台行为;包/更新产品验证应从 Package Acceptance 开始。`published-upgrade-survivor` Docker lane 每次运行验证一个已发布包基线。在 Package Acceptance 中,已解析的 `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`,可以将相同基线扩展到面向 issue 的 fixture,覆盖 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` 命令配方配置基线,在 `summary.json` 中记录配方步骤,并在 Gateway 网关启动后探测 `/healthz`、`/readyz` 以及 RPC 状态。Windows 打包版和安装器全新安装 lane 还会验证已安装包能否从原始绝对 Windows 路径导入 browser-control override。当设置了 `OPENCLAW_CROSS_OS_OPENAI_MODEL` 时,OpenAI 跨 OS agent-turn smoke 默认使用它,否则使用 `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'` 和 `telegram_mode=mock-openai` 调用 Package Acceptance。这会让包迁移、更新、陈旧插件依赖清理、已配置插件安装修复、离线插件、插件更新和 Telegram 证明都基于同一个已解析的包 tarball。在 Full Release Validation 或 OpenClaw Release Checks 上设置 `package_acceptance_package_spec`,即可针对已发布的 npm 包而不是按 SHA 构建的产物运行同一个矩阵。跨 OS 发布检查仍然覆盖 OS 特定的新手引导、安装器和平台行为;包/更新产品验证应从 Package Acceptance 开始。`published-upgrade-survivor` Docker 通道会在阻塞发布路径中为每次运行验证一个已发布包基线。在 Package Acceptance 中,已解析的 `package-under-test` tarball 始终是候选包,`published_upgrade_survivor_baseline` 选择回退的已发布基线,默认是 `openclaw@latest`;失败通道重跑命令会保留该基线。带 `run_release_soak=true` 或 `release_profile=full` 的 Full Release Validation 会设置 `published_upgrade_survivor_baselines=all-since-2026.4.23` 和 `published_upgrade_survivor_scenarios=reported-issues`,以扩展覆盖从 `2026.4.23` 到 `latest` 的每个稳定 npm 发布,以及针对 Feishu 配置、保留的 bootstrap/persona 文件、已配置的 OpenClaw 插件安装、波浪号日志路径和陈旧旧版插件依赖根的问题形状 fixture。单独的 `Update Migration` 工作流在问题是穷尽式已发布更新清理,而不是普通 Full Release CI 覆盖范围时,使用带 `all-since-2026.4.23` 和 `plugin-deps-cleanup` 的 `update-migration` Docker 通道。本地聚合运行可以通过 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPECS` 传入精确包 spec,通过 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPEC` 保持单个通道,例如 `openclaw@2026.4.15`,或设置 `OPENCLAW_UPGRADE_SURVIVOR_SCENARIOS` 用于场景矩阵。已发布通道会用内置的 `openclaw config set` 命令配方配置基线,在 `summary.json` 中记录配方步骤,并在 Gateway 网关启动后探测 `/healthz`、`/readyz` 以及 RPC Status。Windows 打包和安装器全新通道还会验证已安装包可以从原始绝对 Windows 路径导入浏览器控制覆盖。OpenAI 跨 OS agent turn smoke 在设置时默认使用 `OPENCLAW_CROSS_OS_OPENAI_MODEL`,否则使用 `openai/gpt-5.4`,因此安装和 Gateway 网关证明会保持在 GPT-5 测试模型上,同时避免 GPT-4.x 默认值。 ### 旧版兼容窗口 -Package Acceptance 对已发布包有受限的旧版兼容窗口。到 `2026.4.25` 为止的包,包括 `2026.4.25-beta.*`,可以使用兼容路径: +Package Acceptance 对已发布包有有界的旧版兼容窗口。到 `2026.4.25` 为止的包,包括 `2026.4.25-beta.*`,可以使用兼容路径: -- `dist/postinstall-inventory.json` 中已知的私有 QA 条目可以指向 tarball 省略的文件; -- 当包未公开 `gateway install --wrapper` 按标志时,`doctor-switch` 可以跳过 `gateway install --wrapper` 持久化子用例; -- `update-channel-switch` 可以从 tarball 派生的假 git fixture 中修剪缺失的 `pnpm.patchedDependencies`,并可以记录缺失的持久化 `update.channel`; +- `dist/postinstall-inventory.json` 中已知的私有 QA 条目可能指向 tarball 省略的文件; +- 当包未暴露 `gateway install --wrapper` 标志时,`doctor-switch` 可以跳过 `gateway install --wrapper` 持久化子用例; +- `update-channel-switch` 可以从 tarball 派生的假 git fixture 中剪除缺失的 `pnpm.patchedDependencies`,并可以记录缺失的持久化 `update.channel`; - 插件 smoke 可以读取旧版安装记录位置,或接受缺失的 marketplace 安装记录持久化; -- `plugin-update` 可以允许配置元数据迁移,同时仍要求安装记录和不重新安装行为保持不变。 +- `plugin-update` 可以允许配置元数据迁移,同时仍要求安装记录和无重装行为保持不变。 -已发布的 `2026.4.26` 包也可以对已经发布的本地构建元数据标记文件发出警告。后续包必须满足现代契约;相同条件会失败,而不是警告或跳过。 +已发布的 `2026.4.26` 包也可以对已经发布的本地构建元数据戳文件发出警告。之后的包必须满足现代契约;相同条件会失败,而不是警告或跳过。 ### 示例 @@ -304,60 +304,60 @@ 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`、lane 日志、阶段耗时和重新运行命令。优先重新运行失败的包配置文件或精确的 Docker lane,而不是重新运行完整发布验证。 +调试失败的软件包验收运行时,先查看 `resolve_package` 摘要,确认软件包来源、版本和 SHA-256。然后检查 `docker_acceptance` 子运行及其 Docker 产物:`.artifacts/docker-tests/**/summary.json`、`failures.json`、lane 日志、阶段耗时和重新运行命令。优先重新运行失败的软件包配置文件或精确 Docker lane,而不是重新运行完整发布验证。 ## 安装冒烟测试 -独立的 `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,运行 agents delete 共享工作区 CLI 冒烟测试,运行容器 gateway-network e2e,验证内置扩展构建参数,并在 240 秒聚合命令超时内运行有界的内置插件 Docker 配置文件(每个场景的 Docker 运行单独设置上限)。 -- **完整路径** 将 QR 包安装以及 installer Docker/更新覆盖保留给夜间定时运行、手动分发、workflow-call 发布检查,以及确实触及 installer/包/Docker 表面的拉取请求。在完整模式下,install-smoke 会准备或复用一个目标 SHA 的 GHCR 根 Dockerfile 冒烟镜像,然后将 QR 包安装、根 Dockerfile/Gateway 网关冒烟测试、installer/更新冒烟测试,以及快速内置插件 Docker E2E 作为独立作业运行,这样 installer 工作不会排在根镜像冒烟测试之后等待。 +- **快速路径**会在 pull request 触及 Docker/软件包表面、内置插件软件包/清单变更,或 Docker 冒烟作业会执行的核心插件/渠道/Gateway 网关/插件 SDK 表面时运行。仅源码的内置插件变更、仅测试编辑和仅文档编辑不会占用 Docker worker。快速路径会构建一次根 Dockerfile 镜像,检查 CLI,运行 agents delete 共享工作区 CLI 冒烟测试,运行容器 gateway-network e2e,验证内置插件构建参数,并在 240 秒聚合命令超时内运行有界内置插件 Docker 配置文件(每个场景的 Docker 运行单独设限)。 +- **完整路径**为夜间定时运行、手动派发、workflow-call 发布检查,以及真正触及安装器/软件包/Docker 表面的 pull request 保留 QR 软件包安装和安装器 Docker/更新覆盖。在完整模式下,install-smoke 会准备或复用一个目标 SHA 的 GHCR 根 Dockerfile 冒烟镜像,然后将 QR 软件包安装、根 Dockerfile/Gateway 网关冒烟测试、安装器/更新冒烟测试,以及快速内置插件 Docker E2E 作为单独作业运行,这样安装器工作就不会被根镜像冒烟测试阻塞。 -`main` 推送(包括合并提交)不会强制走完整路径;当变更作用域逻辑会在推送上请求完整覆盖时,工作流会保留快速 Docker 冒烟测试,并将完整安装冒烟测试留给夜间或发布验证。 +`main` 推送(包括合并提交)不会强制走完整路径;当变更范围逻辑会在推送上请求完整覆盖时,工作流会保留快速 Docker 冒烟测试,并将完整安装冒烟测试留给夜间或发布验证。 -较慢的 Bun 全局安装 image-provider 冒烟测试由 `run_bun_global_install_smoke` 单独 gating。它会在夜间计划和发布检查工作流中运行,手动 `Install Smoke` 分发也可以选择启用它,但拉取请求和 `main` 推送不会运行。QR 和 installer Docker 测试保留各自以安装为重点的 Dockerfile。 +较慢的 Bun 全局安装 image-provider 冒烟测试由 `run_bun_global_install_smoke` 单独门控。它会在夜间计划和发布检查工作流中运行,手动 `Install Smoke` 派发也可以选择启用它,但 pull request 和 `main` 推送不会运行。QR 和安装器 Docker 测试保留各自面向安装的 Dockerfile。 ## 本地 Docker E2E -`pnpm test:docker:all` 会预构建一个共享 live-test 镜像,将 OpenClaw 打包一次为 npm tarball,并构建两个共享的 `scripts/e2e/Dockerfile` 镜像: +`pnpm test:docker:all` 会预构建一个共享 live-test 镜像,将 OpenClaw 打包一次为 npm tarball,并构建两个共享 `scripts/e2e/Dockerfile` 镜像: -- 用于 installer/update/plugin-dependency lane 的裸 Node/Git runner; -- 一个功能镜像,会把同一个 tarball 安装到 `/app`,用于正常功能 lane。 +- 用于安装器/更新/插件依赖 lane 的裸 Node/Git runner; +- 将同一个 tarball 安装到 `/app` 的功能镜像,用于常规功能 lane。 -Docker lane 定义位于 `scripts/lib/docker-e2e-scenarios.mjs`,规划器逻辑位于 `scripts/lib/docker-e2e-plan.mjs`,runner 只执行选定的计划。调度器通过 `OPENCLAW_DOCKER_E2E_BARE_IMAGE` 和 `OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE` 为每个 lane 选择镜像,然后使用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行 lane。 +Docker lane 定义位于 `scripts/lib/docker-e2e-scenarios.mjs`,规划器逻辑位于 `scripts/lib/docker-e2e-plan.mjs`,runner 只执行选定计划。调度器用 `OPENCLAW_DOCKER_E2E_BARE_IMAGE` 和 `OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE` 为每条 lane 选择镜像,然后用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行 lane。 -### 可调项 +### 可调参数 | 变量 | 默认值 | 用途 | | -------------------------------------- | ------- | --------------------------------------------------------------------------------------------- | -| `OPENCLAW_DOCKER_ALL_PARALLELISM` | 10 | 普通 lane 的主池 slot 数量。 | -| `OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM` | 10 | 对提供商敏感的尾部池 slot 数量。 | -| `OPENCLAW_DOCKER_ALL_LIVE_LIMIT` | 9 | 并发 live lane 上限,避免提供商限流。 | +| `OPENCLAW_DOCKER_ALL_PARALLELISM` | 10 | 常规 lane 的主池 slot 数量。 | +| `OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM` | 10 | 对提供商敏感的尾池 slot 数量。 | +| `OPENCLAW_DOCKER_ALL_LIVE_LIMIT` | 9 | 并发 live lane 上限,避免提供商限流。 | | `OPENCLAW_DOCKER_ALL_NPM_LIMIT` | 10 | 并发 npm install lane 上限。 | | `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT` | 7 | 并发多服务 lane 上限。 | -| `OPENCLAW_DOCKER_ALL_START_STAGGER_MS` | 2000 | lane 启动之间的错峰时间,用于避免 Docker daemon create 风暴;设为 `0` 表示不做错峰。 | -| `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS` | 7200000 | 每个 lane 的兜底超时(120 分钟);选定的 live/tail lane 使用更严格的上限。 | -| `OPENCLAW_DOCKER_ALL_DRY_RUN` | unset | `1` 会打印调度器计划而不运行 lane。 | -| `OPENCLAW_DOCKER_ALL_LANES` | unset | 逗号分隔的精确 lane 列表;跳过清理冒烟测试,以便 agents 复现某个失败 lane。 | +| `OPENCLAW_DOCKER_ALL_START_STAGGER_MS` | 2000 | lane 启动之间的错峰时间,用于避免 Docker daemon 创建风暴;设为 `0` 表示不做错峰。 | +| `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS` | 7200000 | 每条 lane 的兜底超时(120 分钟);选定的 live/tail lane 使用更严格的上限。 | +| `OPENCLAW_DOCKER_ALL_DRY_RUN` | unset | `1` 会打印调度器计划而不运行 lane。 | +| `OPENCLAW_DOCKER_ALL_LANES` | unset | 逗号分隔的精确 lane 列表;跳过清理冒烟测试,便于智能体复现一个失败 lane。 | -比其有效上限更重的 lane 仍然可以从空池启动,然后独占运行,直到释放容量。本地聚合会预检 Docker、移除陈旧的 OpenClaw E2E 容器、输出活动 lane Status、持久化 lane 耗时以进行 longest-first 排序,并且默认在首次失败后停止调度新的池化 lane。 +比其有效上限更重的 lane 仍可从空池启动,然后单独运行直到释放容量。本地聚合会预检 Docker,移除陈旧的 OpenClaw E2E 容器,输出活跃 lane 状态,持久化 lane 耗时以支持最长优先排序,并默认在第一次失败后停止调度新的池化 lane。 ### 可复用 live/E2E 工作流 -可复用的 live/E2E 工作流会询问 `scripts/test-docker-all.mjs --plan-json` 需要哪种包、镜像类型、live 镜像、lane 和凭证覆盖。随后 `scripts/docker-e2e.mjs` 将该计划转换为 GitHub 输出和摘要。它会通过 `scripts/package-openclaw-for-docker.mjs` 打包 OpenClaw,或下载当前运行的包产物,或从 `package_artifact_run_id` 下载包产物;验证 tarball 清单;当计划需要已安装包的 lane 时,通过 Blacksmith 的 Docker 层缓存构建并推送带有 package-digest 标签的裸/功能 GHCR Docker E2E 镜像;并复用提供的 `docker_e2e_bare_image`/`docker_e2e_functional_image` 输入或现有 package-digest 镜像,而不是重新构建。Docker 镜像拉取会使用有界的每次尝试 180 秒超时进行重试,因此卡住的 registry/cache 流会快速重试,而不是消耗 CI 关键路径的大部分时间。 +可复用 live/E2E 工作流会询问 `scripts/test-docker-all.mjs --plan-json` 需要哪种软件包、镜像类型、live 镜像、lane 和凭证覆盖。随后 `scripts/docker-e2e.mjs` 将该计划转换为 GitHub 输出和摘要。它要么通过 `scripts/package-openclaw-for-docker.mjs` 打包 OpenClaw,要么下载当前运行的软件包产物,要么从 `package_artifact_run_id` 下载软件包产物;验证 tarball 清单;当计划需要已安装软件包的 lane 时,通过 Blacksmith 的 Docker 层缓存构建并推送带有软件包摘要标签的裸/功能 GHCR Docker E2E 镜像;并复用提供的 `docker_e2e_bare_image`/`docker_e2e_functional_image` 输入或现有的软件包摘要镜像,而不是重新构建。Docker 镜像拉取会用每次尝试 180 秒的有界超时进行重试,因此卡住的 registry/cache 流会快速重试,而不是消耗 CI 关键路径的大部分时间。 ### 发布路径分块 -发布 Docker 覆盖使用更小的分块作业并设置 `OPENCLAW_SKIP_DOCKER_BUILD=1`,因此每个分块只拉取自己需要的镜像类型,并通过同一个加权调度器执行多个 lane: +发布 Docker 覆盖会用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行更小的分块作业,因此每个分块只拉取自己需要的镜像类型,并通过同一个加权调度器执行多条 lane: - `OPENCLAW_DOCKER_ALL_PROFILE=release-path` - `OPENCLAW_DOCKER_ALL_CHUNK=core | package-update-openai | package-update-anthropic | package-update-core | plugins-runtime-plugins | plugins-runtime-services | plugins-runtime-install-a..h` -当前发布 Docker 分块为 `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` lane 别名仍然是两个提供商 installer lane 的聚合手动重跑别名。 +当前发布 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` lane 别名仍是两个提供商安装器 lane 的聚合手动重新运行别名。 -当完整 release-path 覆盖请求 OpenWebUI 时,OpenWebUI 会并入 `plugins-runtime-services`;只有 OpenWebUI-only 分发仍保留独立的 `openwebui` 分块。内置渠道更新 lane 会针对瞬时 npm 网络失败重试一次。 +当完整 release-path 覆盖请求 OpenWebUI 时,它会合入 `plugins-runtime-services`,并且只有在仅 OpenWebUI 派发时才保留独立的 `openwebui` 分块。内置渠道更新 lane 会针对瞬时 npm 网络失败重试一次。 -每个分块都会上传 `.artifacts/docker-tests/`,其中包含 lane 日志、耗时、`summary.json`、`failures.json`、阶段耗时、调度器计划 JSON、慢 lane 表格以及每个 lane 的重新运行命令。工作流 `docker_lanes` 输入会针对准备好的镜像运行选定 lane,而不是运行分块作业,这会将失败 lane 调试限制在一个有针对性的 Docker 作业内,并为该运行准备、下载或复用包产物;如果选定 lane 是 live Docker lane,目标作业会为该重跑在本地构建 live-test 镜像。生成的每个 lane GitHub 重跑命令会在这些值存在时包含 `package_artifact_run_id`、`package_artifact_name` 和准备好的镜像输入,因此失败 lane 可以复用失败运行中的精确包和镜像。 +每个分块都会上传 `.artifacts/docker-tests/`,其中包含 lane 日志、耗时、`summary.json`、`failures.json`、阶段耗时、调度器计划 JSON、慢 lane 表,以及每条 lane 的重新运行命令。工作流 `docker_lanes` 输入会在已准备镜像上运行选定 lane,而不是运行分块作业,从而将失败 lane 调试限定在一个目标 Docker 作业内,并为该运行准备、下载或复用软件包产物;如果选定 lane 是 live Docker lane,目标作业会为该次重新运行本地构建 live-test 镜像。生成的逐 lane GitHub 重新运行命令会在这些值存在时包含 `package_artifact_run_id`、`package_artifact_name` 和已准备的镜像输入,因此失败 lane 可以复用失败运行中的精确软件包和镜像。 ```bash pnpm test:docker:rerun # download Docker artifacts and print combined/per-lane targeted rerun commands @@ -368,87 +368,87 @@ pnpm test:docker:timings # slow-lane and phase critical-path summari ## 插件预发布 -`Plugin Prerelease` 是成本更高的产品/包覆盖,因此它是一个独立工作流,由 `Full Release Validation` 或显式操作员分发。普通拉取请求、`main` 推送和独立手动 CI 分发都会关闭该套件。它在八个扩展 worker 之间平衡内置插件测试;这些扩展分片作业一次最多运行两个插件配置组,每组使用一个 Vitest worker,并使用更大的 Node heap,因此导入密集型插件批次不会创建额外 CI 作业。仅发布的 Docker 预发布路径会以小组批量运行目标 Docker lane,避免为一到三分钟的作业预留几十个 runner。 +`Plugin Prerelease` 是成本更高的产品/软件包覆盖,因此它是由 `Full Release Validation` 或显式操作员派发的单独工作流。常规 pull request、`main` 推送和独立手动 CI 派发都会关闭该套件。它会在八个扩展 worker 之间平衡内置插件测试;这些扩展分片作业一次最多运行两个插件配置组,每组使用一个 Vitest worker 和更大的 Node heap,这样 import 密集型插件批次就不会创建额外 CI 作业。仅发布 Docker 预发布路径会将目标 Docker lane 分成小组批处理,以避免为一到三分钟的作业占用数十个 runner。 ## QA Lab -QA Lab 在主智能作用域工作流之外有专用 CI lane。Agentic parity 嵌套在广泛的 QA 和发布 harness 下,而不是一个独立的 PR 工作流。当 parity 应随广泛验证运行一起执行时,使用 `Full Release Validation` 并设置 `rerun_group=qa-parity`。 +QA Lab 在主智能范围工作流之外有专用 CI lane。Agentic parity 嵌套在广泛 QA 和发布 harness 下,而不是独立的 PR 工作流。当 parity 应随广泛验证运行一起执行时,使用带 `rerun_group=qa-parity` 的 `Full Release Validation`。 -- `QA-Lab - All Lanes` 工作流会在 `main` 上每晚运行,并支持手动分发;它会将 mock parity lane、live Matrix lane,以及 live Telegram 和 Discord lane 扇出为并行作业。Live 作业使用 `qa-live-shared` 环境,Telegram/Discord 使用 Convex lease。 +- `QA-Lab - All Lanes` 工作流会在 `main` 上每晚运行,也可手动派发;它将 mock parity lane、live Matrix lane,以及 live Telegram 和 Discord lane 扇出为并行作业。Live 作业使用 `qa-live-shared` 环境,Telegram/Discord 使用 Convex leases。 -发布检查会使用确定性 mock 提供商和 mock-qualified 模型(`mock-openai/gpt-5.5` 和 `mock-openai/gpt-5.5-alt`)运行 Matrix 和 Telegram live 传输 lane,因此渠道契约会与 live 模型延迟和正常提供商插件启动隔离。live 传输 Gateway 网关会禁用记忆搜索,因为 QA parity 会单独覆盖记忆行为;提供商连通性由独立的 live 模型、原生提供商和 Docker 提供商套件覆盖。 +发布检查会用确定性的 mock 提供商和 mock 限定模型(`mock-openai/gpt-5.5` 和 `mock-openai/gpt-5.5-alt`)运行 Matrix 和 Telegram live transport lane,因此渠道契约与 live 模型延迟和常规提供商插件启动隔离。live transport Gateway 网关会禁用记忆搜索,因为 QA parity 会单独覆盖记忆行为;提供商连通性由单独的 live 模型、原生提供商和 Docker 提供商套件覆盖。 -Matrix 会为定时和发布 gate 使用 `--profile fast`,并且仅在检出的 CLI 支持时添加 `--fail-fast`。CLI 默认值和手动工作流输入仍为 `all`;手动 `matrix_profile=all` 分发始终会将完整 Matrix 覆盖分片为 `transport`、`media`、`e2ee-smoke`、`e2ee-deep` 和 `e2ee-cli` 作业。 +Matrix 对定时和发布 gate 使用 `--profile fast`,仅当检出的 CLI 支持时才添加 `--fail-fast`。CLI 默认值和手动工作流输入仍为 `all`;手动 `matrix_profile=all` 派发始终将完整 Matrix 覆盖分片为 `transport`、`media`、`e2ee-smoke`、`e2ee-deep` 和 `e2ee-cli` 作业。 -`OpenClaw Release Checks` 也会在发布批准前运行发布关键的 QA Lab lane;其 QA parity gate 会将候选包和基线包作为并行 lane 作业运行,然后把两个产物都下载到一个小型报告作业中,用于最终 parity 比较。 +`OpenClaw Release Checks` 也会在发布批准前运行发布关键的 QA Lab lane;其 QA parity gate 会将候选包和基线包作为并行 lane 作业运行,然后把两个产物下载到一个小型报告作业中,用于最终 parity 对比。 -对于普通 PR,遵循作用域内的 CI/check 证据,而不是将 parity 视为必需 Status。 +对于常规 PR,请遵循范围化 CI/检查证据,而不要将 parity 视为必需状态。 ## 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/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 Android Critical Security` — 定时 Android 安全分片。为 CodeQL 手动构建 Android 应用,运行在工作流完整性检查接受的最小 Blacksmith Linux 运行器上。上传到 `/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 运行器上,对范围较窄的高价值表面运行错误严重级别、非安全 JavaScript/TypeScript 质量查询。它的拉取请求守卫有意小于定时配置:非草稿 PR 只会在智能体命令/模型/工具执行和回复分发代码、配置 schema/迁移/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 运行器上,针对范围较窄的高价值表面运行错误严重级别、非安全 JavaScript/TypeScript 质量查询。它的拉取请求守卫有意小于定时配置文件:非草稿 PR 只会针对智能体命令/模型/工具执行和回复分发代码、配置 schema/迁移/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 质量分片。 -手动分发接受: +手动调度接受: -``` +```bash 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` | 配置 schema、迁移、规范化和 IO 契约 | -| `/codeql-critical-quality/gateway-runtime-boundary` | Gateway 网关协议 schema 和服务器方法契约 | +| `/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、记忆运行时外观、记忆插件 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/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 入站回复分发、回复载荷/分块/运行时帮助程序、渠道回复选项、投递队列,以及会话/线程绑定帮助程序 | +| `/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 源码和插件包契约帮助程序 | -质量与安全保持分离,这样质量发现就可以在不遮蔽安全信号的情况下进行定时、度量、禁用或扩展。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` 上一次成功的非机器人 push CI 运行可以触发它,手动调度也可以直接运行它。当 `main` 已经前进,或过去一小时内已经创建过另一个未跳过的 Docs Agent 运行时,workflow-run 调用会跳过。运行时,它会审查从上一个未跳过的 Docs Agent 源 SHA 到当前 `main` 的提交范围,因此一次每小时运行可以覆盖自上次文档处理以来积累的所有 main 变更。 ### Test Performance Agent -`Test Performance Agent` 工作流是一条事件驱动的 Codex 慢测试维护通道。它没有纯定时计划:`main` 上成功的非机器人 push CI 运行可以触发它,但如果另一个 workflow-run 调用在该 UTC 日已经运行过或正在运行,它会跳过。手动分发会绕过该每日活动门禁。该通道会构建完整套件分组的 Vitest 性能报告,让 Codex 只做小型、保留覆盖率的测试性能修复,而不是大范围重构,然后重新运行完整套件报告,并拒绝会降低通过基线测试数量的变更。如果基线存在失败测试,Codex 只能修复明显的失败,并且智能体之后的完整套件报告必须通过,才会提交任何内容。当 `main` 在机器人 push 落地前前移时,该通道会对经过验证的补丁执行 rebase,重新运行 `pnpm check:changed`,并重试 push;存在冲突的过期补丁会被跳过。它使用 GitHub 托管的 Ubuntu,因此 Codex action 可以保持与文档智能体相同的 drop-sudo 安全姿态。 +`Test Performance Agent` 工作流是一个事件驱动的 Codex 维护通道,用于处理慢测试。它没有纯定时计划:`main` 上一次成功的非机器人 push CI 运行可以触发它,但如果当天 UTC 已经有另一个 workflow-run 调用运行过或正在运行,它会跳过。手动调度会绕过这个每日活动门控。该通道会构建完整套件分组 Vitest 性能报告,让 Codex 只做小型、保持覆盖率的测试性能修复,而不是大范围重构,然后重新运行完整套件报告,并拒绝会降低通过基线测试数量的变更。如果基线存在失败测试,Codex 只能修复明显失败项,并且 agent 之后的完整套件报告必须通过,才能提交任何内容。当 `main` 在机器人 push 落地前前进时,该通道会变基已验证的补丁,重新运行 `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 \ @@ -457,39 +457,39 @@ gh workflow run duplicate-after-merge.yml \ -f apply=true ``` -## 本地检查门禁和变更路由 +## 本地检查门控和变更路由 -本地 changed-lane 逻辑位于 `scripts/changed-lanes.mjs`,并由 `scripts/check-changed.mjs` 执行。相比宽泛的 CI 平台范围,该本地检查门禁对架构边界更严格: +本地 changed-lane 逻辑位于 `scripts/changed-lanes.mjs`,并由 `scripts/check-changed.mjs` 执行。这个本地检查门控在架构边界方面比宽泛的 CI 平台范围更严格: -- 核心生产变更会运行核心生产和核心测试 typecheck,以及核心 lint/守卫; -- 仅核心测试变更只会运行核心测试 typecheck,以及核心 lint; -- 插件生产变更会运行插件生产和插件测试 typecheck,以及插件 lint; -- 仅插件测试变更会运行插件测试 typecheck,以及插件 lint; -- 公共插件 SDK 或插件契约变更会扩展到插件 typecheck,因为插件依赖这些核心契约(Vitest 插件扫描仍然是显式测试工作); -- 仅发布元数据版本 bump 会运行定向版本/配置/根依赖检查; +- 核心生产变更会运行核心生产和核心测试类型检查,以及核心 lint/guard; +- 仅核心测试变更只运行核心测试类型检查和核心 lint; +- 插件生产变更会运行插件生产和插件测试类型检查,以及插件 lint; +- 仅插件测试变更会运行插件测试类型检查和插件 lint; +- 公开插件 SDK 或插件契约变更会扩展到插件类型检查,因为插件依赖这些核心契约(Vitest 插件扫描仍是显式测试工作); +- 仅发布元数据的版本 bump 会运行有针对性的版本/配置/根依赖检查; - 未知根目录/配置变更会安全失败到所有检查通道。 -本地 changed-test 路由位于 `scripts/test-projects.test-support.mjs`,并且有意比 `check:changed` 更便宜:直接测试编辑会运行自身,源代码编辑优先使用显式映射,然后是同级测试和导入图依赖项。共享群组房间投递配置是显式映射之一:对群组可见回复配置、源回复投递模式或消息工具系统提示词的变更,会路由到核心回复测试以及 Discord 和 Slack 投递回归测试,这样共享默认项变更会在第一次 PR push 之前失败。只有当变更的范围足够覆盖整个 harness,导致廉价映射集合不再是可信代理时,才使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`。 +本地 changed-test 路由位于 `scripts/test-projects.test-support.mjs`,并且有意比 `check:changed` 更便宜:直接测试编辑会运行其自身,源码编辑优先使用显式映射,然后是同级测试和导入图依赖项。共享 group-room 投递配置是显式映射之一:对群组可见回复配置、源回复投递模式或 message-tool 系统提示词的变更,会路由到核心回复测试,以及 Discord 和 Slack 投递回归测试,这样共享默认值变更会在第一次 PR push 前失败。只有当变更范围足够覆盖整个 harness,以至于廉价映射集合不能作为可信代理时,才使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`。 ## Testbox 验证 -从仓库根目录运行 Testbox,并优先使用新预热的 box 来做宽范围证明。在将慢速门禁耗费在一个被复用、已过期,或刚刚报告了异常大规模同步的 box 上之前,先在 box 内运行 `pnpm testbox:sanity`。 +从仓库根目录运行 Testbox,并优先使用新预热的 box 来做广泛证明。在把耗时 gate 花到一个复用过、已过期或刚报告异常大同步量的 box 之前,先在 box 内运行 `pnpm testbox:sanity`。 -当 `pnpm-lock.yaml` 等必需根文件消失,或 `git status --short` 显示至少 200 个已跟踪文件被删除时,完整性检查会快速失败。这通常意味着远程同步状态不是 PR 的可信副本;停止该 box 并预热一个新的,而不是调试产品测试失败。对于有意进行大量删除的 PR,请为该完整性检查运行设置 `OPENCLAW_TESTBOX_ALLOW_MASS_DELETIONS=1`。 +当 `pnpm-lock.yaml` 等必需根文件消失,或 `git status --short` 显示至少 200 个已跟踪删除时,sanity check 会快速失败。这通常意味着远程同步状态不是 PR 的可信副本;停止那个 box,并改为预热一个新的 box,而不是调试产品测试失败。对于有意的大量删除 PR,请为该 sanity 运行设置 `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 使用更大的毫秒值。 -Crabbox 是仓库自有的远程 box 包装器,用于维护者的 Linux 证明。当检查对本地编辑循环来说范围过大、需要 CI 对等性,或证明需要密钥、Docker、包通道、可复用 box 或远程日志时使用它。常规 OpenClaw 后端是 `blacksmith-testbox`;自有 AWS/Hetzner 容量是 Blacksmith 故障、配额问题或明确要求自有容量测试时的后备方案。 +Crabbox 是仓库自有的远程 box 封装器,用于维护者 Linux 证明。当某个检查对本地编辑循环来说过宽、需要 CI 等价性,或证明需要密钥、Docker、package lane、可复用 box 或远程日志时,请使用它。正常的 OpenClaw 后端是 `blacksmith-testbox`;自有 AWS/Hetzner 容量是 Blacksmith 故障、配额问题或显式自有容量测试时的后备方案。 -首次运行前,从仓库根目录检查包装器: +首次运行前,从仓库根目录检查该封装器: ```bash pnpm crabbox:run -- --help | sed -n '1,120p' ``` -如果 Crabbox 二进制文件已过期且未声明 `blacksmith-testbox`,仓库包装器会拒绝运行。即使 `.crabbox.yaml` 有自有云默认值,也要显式传入提供商。 +如果 Crabbox 二进制文件过旧且未声明支持 `blacksmith-testbox`,仓库封装器会拒绝运行。即使 `.crabbox.yaml` 里有自有云默认值,也要显式传入提供商。 -变更门禁: +变更 gate: ```bash pnpm crabbox:run -- --provider blacksmith-testbox \ @@ -504,7 +504,7 @@ pnpm crabbox:run -- --provider blacksmith-testbox \ "env CI=1 NODE_OPTIONS=--max-old-space-size=4096 OPENCLAW_TEST_PROJECTS_PARALLEL=6 OPENCLAW_VITEST_MAX_WORKERS=1 OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS=900000 pnpm check:changed" ``` -聚焦测试重跑: +定向测试重跑: ```bash pnpm crabbox:run -- --provider blacksmith-testbox \ @@ -534,21 +534,21 @@ pnpm crabbox:run -- --provider blacksmith-testbox \ "env CI=1 NODE_OPTIONS=--max-old-space-size=4096 OPENCLAW_TEST_PROJECTS_PARALLEL=6 OPENCLAW_VITEST_MAX_WORKERS=1 OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS=900000 pnpm test" ``` -阅读最终 JSON 摘要。有用字段是 `provider`、`leaseId`、`syncDelegated`、`exitCode`、`commandMs` 和 `totalMs`。由 Blacksmith 支持的一次性 Crabbox 运行应自动停止 Testbox;如果运行被中断或清理状态不明确,请检查存活的 box,并只停止你创建的 box: +读取最终 JSON 摘要。有用的字段是 `provider`、`leaseId`、`syncDelegated`、`exitCode`、`commandMs` 和 `totalMs`。一次性、由 Blacksmith 支撑的 Crabbox 运行应自动停止 Testbox;如果运行被中断或清理状态不明确,请检查在线 box,并只停止你创建的 box: ```bash blacksmith testbox list blacksmith testbox stop --id ``` -仅当你有意需要在同一个已水合的 box 上运行多条命令时才使用复用: +仅当你有意需要在同一个已 hydrate 的 box 上运行多条命令时,才使用复用: ```bash pnpm crabbox:run -- --provider blacksmith-testbox --id --no-sync --timing-json --shell -- "pnpm test " pnpm crabbox:stop -- ``` -如果 Crabbox 是损坏的层,但 Blacksmith 本身可用,请将直接 Blacksmith 作为狭窄后备方案: +如果 Crabbox 是损坏层,但 Blacksmith 本身可用,请将直接使用 Blacksmith 作为窄范围后备方案: ```bash blacksmith testbox warmup ci-check-testbox.yml --ref main --idle-timeout 90 @@ -556,7 +556,7 @@ blacksmith testbox run --id "env CI=1 NODE_OPTIONS=--max-old-space-size blacksmith testbox stop --id ``` -仅当 Blacksmith 宕机、受配额限制、缺少所需环境,或明确目标就是自有容量时,才升级到自有 Crabbox 容量: +只有当 Blacksmith 宕机、受配额限制、缺少所需环境,或自有容量明确是目标时,才升级到自有 Crabbox 容量: ```bash pnpm crabbox:warmup -- --provider aws --class beast --market on-demand --idle-timeout 90m @@ -565,7 +565,7 @@ pnpm crabbox:run -- --id --timing-json --shell -- "env NODE_OPT pnpm crabbox:stop -- ``` -`.crabbox.yaml` 负责自有云通道的提供商、同步和 GitHub Actions 水合默认值。它排除本地 `.git`,使水合后的 Actions checkout 保留自己的远程 Git 元数据,而不是同步维护者本地的 remote 和对象存储;它也排除不应传输的本地运行时/构建产物。`.github/workflows/crabbox-hydrate.yml` 负责 checkout、Node/pnpm 设置、`origin/main` 拉取,以及自有云 `crabbox run --id ` 命令的非密钥环境交接。 +`.crabbox.yaml` 拥有自有云 lane 的提供商、同步和 GitHub Actions hydrate 默认值。它会排除本地 `.git`,使已 hydrate 的 Actions checkout 保留自己的远程 Git 元数据,而不是同步维护者本地的 remote 和 object store;它也会排除绝不应传输的本地运行时/构建产物。`.github/workflows/crabbox-hydrate.yml` 拥有 checkout、Node/pnpm 设置、`origin/main` 拉取,以及自有云 `crabbox run --id ` 命令的非密钥环境交接。 ## 相关内容 diff --git a/docs/zh-CN/help/testing.md b/docs/zh-CN/help/testing.md index 2d0a52035..dcc04b8d5 100644 --- a/docs/zh-CN/help/testing.md +++ b/docs/zh-CN/help/testing.md @@ -3,33 +3,33 @@ read_when: - 在本地或 CI 中运行测试 - 为模型/提供商缺陷添加回归测试 - 调试 Gateway 网关 + 智能体行为 -summary: 测试工具包:unit/e2e/live 测试套件、Docker 运行器,以及每项测试涵盖的内容 +summary: 测试工具包:单元/e2e/实时测试套件、Docker 运行器,以及每项测试覆盖的内容 title: 测试 x-i18n: - generated_at: "2026-05-04T21:15:13Z" + generated_at: "2026-05-04T22:29:49Z" model: gpt-5.5 provider: openai - source_hash: 9fec86c0e3843a3ad0dcc686f2b942c202af7dd23c33cf55ba384a9643702030 + source_hash: 0262d0bc9302671513cec25c8e7ae9c4b4f495ab8d4fd9a01ac3ce0ab94d476b source_path: help/testing.md workflow: 16 --- -OpenClaw 有三套 Vitest 测试套件(单元/集成、e2e、真实环境)和少量 -Docker runner。本文档是一份“我们如何测试”指南: +OpenClaw 有三套 Vitest 测试套件(单元/集成、e2e、live)和一小组 +Docker 运行器。本文档是“我们如何测试”的指南: -- 每个套件覆盖什么(以及它刻意_不_覆盖什么)。 +- 每个套件覆盖什么(以及它有意 _不_ 覆盖什么)。 - 常见工作流(本地、推送前、调试)应运行哪些命令。 -- 真实环境测试如何发现凭证并选择模型/提供商。 +- live 测试如何发现凭证并选择模型/提供商。 - 如何为真实世界中的模型/提供商问题添加回归测试。 -**QA 栈(qa-lab、qa-channel、真实传输通道)**另有单独文档: +**QA 栈(qa-lab、qa-channel、live 传输协议通道)** 单独记录在: -- [QA overview](/zh-CN/concepts/qa-e2e-automation) — 架构、命令面、场景编写。 +- [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) — 由仓库支持的场景使用的合成传输插件。 +- [QA channel](/zh-CN/channels/qa-channel) — 仓库支持场景使用的合成传输协议插件。 -本页涵盖常规测试套件和 Docker/Parallels runner 的运行方式。下面的 QA 专用 runner 小节([QA 专用 runner](#qa-specific-runners))列出具体的 `qa` 调用,并指回上面的参考文档。 +本页涵盖运行常规测试套件和 Docker/Parallels 运行器。下面的 QA 专用运行器部分([QA 专用运行器](#qa-specific-runners))列出了具体的 `qa` 调用,并指回上面的参考。 ## 快速开始 @@ -38,9 +38,9 @@ Docker runner。本文档是一份“我们如何测试”指南: - 完整门禁(推送前预期运行):`pnpm build && pnpm check && pnpm check:test-types && pnpm test` - 在资源充足的机器上更快运行本地完整套件:`pnpm test:max` -- 直接 Vitest 监听循环:`pnpm test:watch` +- 直接 Vitest watch 循环:`pnpm test:watch` - 直接按文件定位现在也会路由扩展/渠道路径:`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` @@ -51,123 +51,124 @@ Docker runner。本文档是一份“我们如何测试”指南: 调试真实提供商/模型时(需要真实凭证): -- 真实环境套件(模型 + Gateway 网关工具/图片探测):`pnpm test: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 真实模型扫描:`pnpm test:docker:live-models` - - 每个选中的模型现在会运行一个文本轮次和一个小型文件读取风格探测。 - 元数据声明支持 `image` 输入的模型还会运行一次小型图片轮次。 - 在隔离提供商失败时,可用 `OPENCLAW_LIVE_MODEL_FILE_PROBE=0` 或 - `OPENCLAW_LIVE_MODEL_IMAGE_PROBE=0` 禁用额外探测。 - - CI 覆盖范围:每日 `OpenClaw Scheduled Live And E2E Checks` 和手动 - `OpenClaw Release Checks` 都会调用可复用的真实环境/E2E 工作流,并设置 - `include_live_suites: true`,其中包括按提供商分片的独立 Docker 真实模型 - 矩阵任务。 - - 对于定向 CI 重跑,调度 `OpenClaw Live And E2E Checks (Reusable)`, +- 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/heap/trace 产物。配置了 + `CLAWGRIT_REPORTS_TOKEN` 时,每日定时运行会将 mock-provider、deep-profile + 和 GPT 5.4 通道产物发布到 `openclaw/clawgrit-reports`。mock-provider + 报告还包括源码级 Gateway 网关启动、内存、插件压力、重复假模型 + hello-loop 和 CLI 启动数字。 +- Docker live 模型扫测:`pnpm test:docker:live-models` + - 每个选定模型现在会运行一个文本轮次加一个小型文件读取风格探针。 + 元数据声明支持 `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`。 - - 将新的高信号提供商密钥添加到 `scripts/ci-hydrate-live-auth.sh`, + - 将新的高信号提供商 secret 添加到 `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 真实环境通道,使用 `/codex bind` 绑定一个合成 - Slack 私信,执行 `/codex fast` 和 - `/codex permissions`,然后验证普通回复和图片附件通过原生插件绑定而不是 ACP 路由。 -- Codex app-server harness 冒烟测试:`pnpm test:docker:live-codex-harness` +- 原生 Codex 绑定聊天冒烟:`pnpm test:docker:live-codex-bind` + - 针对 Codex app-server 路径运行一条 Docker live 通道,使用 `/codex bind` + 绑定一个合成 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 失败时,可用 - `OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_PROBE=0` 禁用子智能体探测。若要定向检查子智能体,请禁用其他探测: + 验证 `/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`,否则它会在子智能体探测后退出。 -- Crestodian 救援命令冒烟测试:`pnpm test:live:crestodian-rescue-channel` - - 针对消息渠道救援命令面的选择性双保险检查。 - 它会执行 `/crestodian status`,排队一个持久模型 + 除非设置了 `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 首次运行 Docker 冒烟测试:`pnpm test:docker:crestodian-first-run` +- Crestodian 规划器 Docker 冒烟:`pnpm test:docker:crestodian-planner` + - 在无配置容器中运行 Crestodian,`PATH` 上有假 Claude CLI, + 并验证模糊规划器回退会转换为经审计的类型化配置写入。 +- Crestodian 首次运行 Docker 冒烟:`pnpm test:docker:crestodian-first-run` - 从空的 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` 后,运行 +- 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,并且助手转录存储了规范化的 `usage.cost`。 + 验证 JSON 报告 Moonshot/K2.6,并且助手 transcript 存储规范化后的 `usage.cost`。 -当你只需要一个失败用例时,优先通过下面介绍的 allowlist 环境变量缩小真实环境测试范围。 +当你只需要一个失败用例时,优先通过下面描述的 allowlist 环境变量缩小 live 测试范围。 -## QA 专用 runner +## QA 专用运行器 -当你需要 QA-lab 的真实感时,这些命令与主测试套件并列使用: +当你需要 QA-lab 真实性时,这些命令与主测试套件并列: -CI 会在专用工作流中运行 QA Lab。Agentic parity 嵌套在 -`QA-Lab - All Lanes` 和发布验证下,不是独立的 PR 工作流。 +CI 在专用工作流中运行 QA Lab。智能体化一致性嵌套在 +`QA-Lab - All Lanes` 和发布验证下,而不是独立的 PR 工作流。 广泛验证应使用 `Full Release Validation`,并设置 -`rerun_group=qa-parity`,或使用 release-checks QA 组。`QA-Lab - All Lanes` -每晚在 `main` 上运行,也可手动调度,并将 mock parity 通道、真实 -Matrix 通道、Convex 托管的真实 Telegram 通道,以及 Convex 托管的真实 Discord -通道作为并行任务运行。定时 QA 和发布检查会显式传入 Matrix -`--profile fast`,而 Matrix CLI 和手动工作流输入的默认值仍为 -`all`;手动调度可以将 `all` 分片为 `transport`、 -`media`、`e2ee-smoke`、`e2ee-deep` 和 `e2ee-cli` 任务。`OpenClaw Release -Checks` 会在发布批准前运行 parity,以及快速 Matrix 和 Telegram 通道, -发布传输检查使用 `mock-openai/gpt-5.5`,以保持确定性并避免正常的提供商插件启动。这些真实传输 +`rerun_group=qa-parity` 或 release-checks QA 组。稳定版/默认发布 +检查将详尽的 live/Docker soak 放在 `run_release_soak=true` 后面;`full` +配置会强制开启 soak。`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 加快速 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 真实模型/后端分片使用共享的 -`ghcr.io/openclaw/openclaw-live-test:` 镜像,该镜像会为每个选中的 -提交构建一次,然后通过 `OPENCLAW_SKIP_DOCKER_BUILD=1` 拉取它,而不是在 +`ffmpeg` 和 `ffprobe`。Docker live 模型/后端分片使用共享的 +`ghcr.io/openclaw/openclaw-live-test:` 镜像,该镜像会针对每个选定 +提交构建一次,然后用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 拉取它,而不是在 每个分片内重新构建。 - `pnpm openclaw qa suite` - 直接在主机上运行由仓库支持的 QA 场景。 - - 默认使用隔离的 Gateway 网关 worker 并行运行多个已选场景。`qa-channel` 默认并发数为 4(受已选场景数量限制)。使用 `--concurrency ` 调整 worker 数量,或使用 `--concurrency 1` 运行旧的串行通道。 - - 任一场景失败时以非零状态退出。当你想生成产物但不想返回失败退出码时,使用 `--allow-failures`。 - - 支持提供商模式 `live-frontier`、`mock-openai` 和 `aimock`。`aimock` 会启动一个由本地 AIMock 支撑的提供商服务器,用于实验性的 fixture 和协议 mock 覆盖,同时不会替代具备场景感知能力的 `mock-openai` 通道。 + - 默认使用隔离的 Gateway 网关 worker 并行运行多个已选场景。`qa-channel` 默认并发数为 4(受已选场景数量限制)。使用 `--concurrency ` 调整 worker 数量,或使用 `--concurrency 1` 进入较旧的串行通道。 + - 任一场景失败时以非零状态退出。当你想要生成制品但不想使用失败退出代码时,使用 `--allow-failures`。 + - 支持 provider 模式 `live-frontier`、`mock-openai` 和 `aimock`。`aimock` 会启动一个由本地 AIMock 支持的 provider 服务器,用于实验性 fixture 和协议 mock 覆盖,同时不会取代具备场景感知能力的 `mock-openai` 通道。 - `pnpm test:plugins:kitchen-sink-live` - - 通过 QA Lab 运行实时 OpenAI Kitchen Sink 插件压力测试。它会安装外部 Kitchen Sink 包、验证插件 SDK 表面清单、探测 `/healthz` 和 `/readyz`、记录 Gateway 网关 CPU/RSS 证据、运行一次实时 OpenAI 回合,并检查对抗性诊断。需要实时 OpenAI 凭证,例如 `OPENAI_API_KEY`。在已注入凭证的 Testbox 会话中,如果存在 `openclaw-testbox-env` helper,它会自动加载 Testbox 实时凭证配置。 + - 通过 QA Lab 运行实时 OpenAI Kitchen Sink 插件检验流程。它会安装外部 Kitchen Sink 包,验证插件 SDK 表面清单,探测 `/healthz` 和 `/readyz`,记录 Gateway 网关 CPU/RSS 证据,运行一次实时 OpenAI 回合,并检查对抗性诊断。需要实时 OpenAI 凭证,例如 `OPENAI_API_KEY`。在已注水的 Testbox 会话中,当存在 `openclaw-testbox-env` helper 时,它会自动加载 Testbox 实时凭证配置文件。 - `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 网关占满回归。 - - 使用已构建的 `dist` 产物;当 checkout 中还没有新的运行时输出时,请先运行构建。 + - 运行 Gateway 网关启动基准,以及一组小型 mock QA Lab 场景包(`channel-chat-baseline`、`memory-failure-fallback`、`gateway-restart-inflight-run`),并将合并后的 CPU 观测摘要写入 `.artifacts/gateway-cpu-scenarios/`。 + - 默认只标记持续高 CPU 观测(`--cpu-core-warn` 加 `--hot-wall-warn-ms`),因此短暂启动突发会作为指标记录,而不会看起来像持续数分钟的 Gateway 网关占满回归。 + - 使用已构建的 `dist` 制品;当检出内容还没有新的运行时输出时,请先运行构建。 - `pnpm openclaw qa suite --runner multipass` - - 在一次性 Multipass Linux VM 中运行同一套 QA 套件。 + - 在一次性 Multipass Linux VM 内运行同一套 QA 套件。 - 保持与主机上的 `qa suite` 相同的场景选择行为。 - - 复用与 `qa suite` 相同的提供商/模型选择标志。 - - 实时运行会转发对 guest 实用的受支持 QA 凭证输入:基于环境的提供商密钥、QA 实时提供商配置路径,以及存在时的 `CODEX_HOME`。 - - 输出目录必须保持在仓库根目录下,以便 guest 能通过挂载的工作区写回。 - - 在 `.artifacts/qa-e2e/...` 下写入常规 QA 报告和摘要,以及 Multipass 日志。 + - 复用与 `qa suite` 相同的 provider/model 选择标志。 + - 实时运行会转发对 guest 实用且受支持的 QA 凭证输入:基于环境变量的 provider key、QA 实时 provider 配置路径,以及存在时的 `CODEX_HOME`。 + - 输出目录必须保留在仓库根目录下,以便 guest 能通过挂载的工作区写回。 + - 将常规 QA 报告和摘要以及 Multipass 日志写入 `.artifacts/qa-e2e/...`。 - `pnpm qa:lab:up` - - 启动由 Docker 支撑的 QA 站点,用于操作员式 QA 工作。 + - 启动由 Docker 支持的 QA 站点,用于操作员风格的 QA 工作。 - `pnpm test:docker:npm-onboard-channel-agent` - - 从当前 checkout 构建 npm tarball,在 Docker 中全局安装它,运行非交互式 OpenAI API key 新手引导,默认配置 Telegram,验证打包后的插件运行时无需启动时依赖修复即可加载,运行 Doctor,并针对 mock OpenAI 端点运行一次本地 agent 回合。 - - 使用 `OPENCLAW_NPM_ONBOARD_CHANNEL=discord` 可用 Discord 运行同一条打包安装通道。 + - 从当前检出构建一个 npm tarball,在 Docker 中全局安装它,运行非交互式 OpenAI API key 新手引导,默认配置 Telegram,验证打包后的插件运行时可以在没有启动时依赖修复的情况下加载,运行 Doctor,并针对 mock 的 OpenAI endpoint 运行一次本地智能体回合。 + - 使用 `OPENCLAW_NPM_ONBOARD_CHANNEL=discord` 以 Discord 运行同一条打包安装通道。 - `pnpm test:docker:session-runtime-context` - - 为嵌入式运行时上下文转录运行确定性的已构建应用 Docker 冒烟测试。它验证隐藏的 OpenClaw 运行时上下文会作为非显示自定义消息持久化,而不是泄漏到可见的用户回合中;随后种下一个受影响的损坏会话 JSONL,并验证 `openclaw doctor --fix` 会将其重写到活动分支并创建备份。 + - 为嵌入式运行时上下文 transcript 运行确定性的已构建应用 Docker smoke。它会验证隐藏的 OpenClaw 运行时上下文会作为非显示自定义消息持久化,而不是泄漏到可见的用户回合中,然后植入一个受影响的损坏会话 JSONL,并验证 `openclaw doctor --fix` 会将其重写到当前分支并创建备份。 - `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,而不是从注册表安装。 - - 使用与 `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。 - - wrapper 会在 Docker 构建/安装工作之前,在主机上验证 Telegram 或 Convex 凭证环境。只有在刻意调试凭证前置设置时,才设置 `OPENCLAW_NPM_TELEGRAM_SKIP_CREDENTIAL_PREFLIGHT=1`。 - - `OPENCLAW_NPM_TELEGRAM_CREDENTIAL_ROLE=ci|maintainer` 仅为这条通道覆盖共享的 `OPENCLAW_QA_CREDENTIAL_ROLE`。 - - GitHub Actions 将这条通道公开为手动维护者工作流 `NPM Telegram Beta E2E`。它不会在合并时运行。该工作流使用 `qa-live-shared` 环境和 Convex CI 凭证租约。 -- GitHub Actions 还公开了 `Package Acceptance`,用于针对单个候选包进行旁路产品验证。它接受受信任的 ref、已发布 npm 规格、HTTPS tarball URL 加 SHA-256,或来自另一次运行的 tarball 产物,将规范化后的 `openclaw-current.tgz` 作为 `package-under-test` 上传,然后用 smoke、package、product、full 或自定义通道配置运行现有 Docker E2E 调度器。设置 `telegram_mode=mock-openai` 或 `live-frontier`,可针对同一个 `package-under-test` 产物运行 Telegram QA 工作流。 - - 最新 beta 产品验证: + - 默认使用 `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。 + - wrapper 会在 Docker 构建/安装工作前,在主机上验证 Telegram 或 Convex 凭证环境变量。仅在刻意调试凭证前设置时,才设置 `OPENCLAW_NPM_TELEGRAM_SKIP_CREDENTIAL_PREFLIGHT=1`。 + - `OPENCLAW_NPM_TELEGRAM_CREDENTIAL_ROLE=ci|maintainer` 仅为此通道覆盖共享的 `OPENCLAW_QA_CREDENTIAL_ROLE`。 + - GitHub Actions 将此通道暴露为手动 maintainer workflow `NPM Telegram Beta E2E`。它不会在合并时运行。该 workflow 使用 `qa-live-shared` 环境和 Convex CI 凭证租约。 +- GitHub Actions 还暴露 `Package Acceptance`,用于针对一个候选包进行旁路产品证明。它接受可信 ref、已发布的 npm spec、HTTPS tarball URL 加 SHA-256,或来自另一次运行的 tarball artifact,上传标准化后的 `openclaw-current.tgz` 作为 `package-under-test`,然后使用 smoke、package、product、full 或 custom 通道配置文件运行现有 Docker E2E scheduler。设置 `telegram_mode=mock-openai` 或 `live-frontier`,即可让 Telegram QA workflow 针对同一个 `package-under-test` artifact 运行。 + - 最新 beta 产品证明: ```bash gh workflow run package-acceptance.yml --ref main \ @@ -177,7 +178,7 @@ gh workflow run package-acceptance.yml --ref main \ -f telegram_mode=mock-openai ``` -- 精确 tarball URL 验证需要摘要: +- 精确 tarball URL 证明需要 digest: ```bash gh workflow run package-acceptance.yml --ref main \ @@ -187,7 +188,7 @@ gh workflow run package-acceptance.yml --ref main \ -f suite_profile=package ``` -- 产物验证会从另一次 Actions 运行下载 tarball 产物: +- Artifact 证明会从另一次 Actions 运行下载 tarball artifact: ```bash gh workflow run package-acceptance.yml --ref main \ @@ -198,44 +199,44 @@ 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 修复。 + - 在 Docker 中打包并安装当前 OpenClaw 构建,启动已配置 OpenAI 的 Gateway 网关,然后通过配置编辑启用内置渠道/插件。 + - 验证 setup discovery 会让未配置的可下载插件保持缺失,首次配置后的 Doctor 修复会显式安装每个缺失的可下载插件,并且第二次重启不会运行隐藏的依赖修复。 + - 还会安装一个已知的较旧 npm baseline,在运行 `openclaw update --tag ` 前启用 Telegram,并验证候选版本的更新后 Doctor 会清理旧版插件依赖残留,而无需 harness 侧 postinstall 修复。 - `pnpm test:parallels:npm-update` - - 跨 Parallels guest 运行原生打包安装更新冒烟测试。每个已选平台会先安装请求的基线包,然后在同一个 guest 中运行已安装的 `openclaw update` 命令,并验证已安装版本、更新 Status、Gateway 网关就绪性,以及一次本地 agent 回合。 - - 迭代单个 guest 时使用 `--platform macos`、`--platform windows` 或 `--platform linux`。使用 `--json` 获取摘要产物路径和每条通道的 Status。 - - OpenAI 通道默认使用 `openai/gpt-5.5` 进行实时 agent 回合验证。当刻意验证另一个 OpenAI 模型时,传入 `--model ` 或设置 `OPENCLAW_PARALLELS_OPENAI_MODEL`。 - - 用主机超时包裹长时间本地运行,避免 Parallels 传输卡住耗尽剩余测试窗口: + - 跨 Parallels guest 运行原生打包安装更新 smoke。每个已选平台会先安装请求的 baseline 包,然后在同一个 guest 中运行已安装的 `openclaw update` 命令,并验证已安装版本、更新 Status、Gateway 网关就绪状态,以及一次本地智能体回合。 + - 在迭代单个 guest 时,使用 `--platform macos`、`--platform windows` 或 `--platform linux`。使用 `--json` 获取摘要 artifact 路径和各通道 Status。 + - 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`。 - - Windows 更新在冷 guest 上可能会花 10 到 15 分钟执行更新后 Doctor 和包更新工作;只要嵌套 npm 调试日志还在推进,这仍然是健康状态。 - - 不要将这个聚合 wrapper 与单独的 Parallels macOS、Windows 或 Linux 冒烟通道并行运行。它们共享 VM 状态,可能在快照恢复、包服务或 guest Gateway 网关状态上发生冲突。 - - 更新后验证会运行常规内置插件表面,因为语音、图像生成和媒体理解等能力 facade 会通过内置运行时 API 加载,即使 agent 回合本身只检查简单文本响应。 + - 脚本会将嵌套通道日志写入 `/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 加载,即使智能体回合本身只检查简单文本响应。 - `pnpm openclaw qa aimock` - - 仅启动本地 AIMock 提供商服务器,用于直接协议冒烟测试。 + - 仅启动本地 AIMock provider 服务器,用于直接协议 smoke 测试。 - `pnpm openclaw qa matrix` - - 针对一次性 Docker 支撑的 Tuwunel homeserver 运行 Matrix 实时 QA 通道。仅限源码 checkout,打包安装不会随附 `qa-lab`。 - - 完整 CLI、配置文件/场景目录、环境变量和产物布局:[Matrix QA](/zh-CN/concepts/qa-matrix)。 + - 针对一个一次性 Docker 支持的 Tuwunel homeserver 运行 Matrix 实时 QA 通道。仅限源检出 — 打包安装不会包含 `qa-lab`。 + - 完整 CLI、profile/场景目录、环境变量和 artifact 布局:[Matrix QA](/zh-CN/concepts/qa-matrix)。 - `pnpm openclaw qa telegram` - - 使用来自环境的 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 报告、摘要和已观测消息产物。回复场景包含从 driver 发送请求到观测到 SUT 回复的 RTT。 + - 使用来自环境变量的 driver 和 SUT bot token,针对真实私有群组运行 Telegram 实时 QA 通道。 + - 需要 `OPENCLAW_QA_TELEGRAM_GROUP_ID`、`OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKEN` 和 `OPENCLAW_QA_TELEGRAM_SUT_BOT_TOKEN`。group 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 流量。 + - 将 Telegram QA 报告、摘要和 observed-messages artifact 写入 `.artifacts/qa-e2e/...`。回复场景包括从 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 项目脚手架: @@ -244,12 +245,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`) 可选环境变量: @@ -259,14 +260,14 @@ gh workflow run package-acceptance.yml --ref main \ - `OPENCLAW_QA_CREDENTIAL_HTTP_TIMEOUT_MS`(默认 `15000`) - `OPENCLAW_QA_CONVEX_ENDPOINT_PREFIX`(默认 `/qa-credentials/v1`) - `OPENCLAW_QA_CREDENTIAL_OWNER_ID`(可选 trace id) -- `OPENCLAW_QA_ALLOW_INSECURE_HTTP=1` 允许仅本地开发使用 loopback `http://` Convex URL。 +- `OPENCLAW_QA_ALLOW_INSECURE_HTTP=1` 允许将 loopback `http://` Convex URL 用于仅本地开发。 `OPENCLAW_QA_CONVEX_SITE_URL` 在正常运行时应使用 `https://`。 -维护者管理命令(pool add/remove/list)明确需要 +维护者管理员命令(池 add/remove/list)需要专用的 `OPENCLAW_QA_CONVEX_SECRET_MAINTAINER`。 -维护者可用的 CLI 辅助命令: +面向维护者的 CLI 辅助命令: ```bash pnpm openclaw qa credentials doctor @@ -275,7 +276,9 @@ pnpm openclaw qa credentials list --kind telegram pnpm openclaw qa credentials remove --credential-id ``` -在实时运行前使用 `doctor` 检查 Convex 站点 URL、broker 密钥、端点前缀、HTTP 超时,以及 admin/list 可达性,且不会打印密钥值。在脚本和 CI 工具中使用 `--json` 获取机器可读输出。 +在 live 运行前使用 `doctor` 检查 Convex 站点 URL、代理密钥、 +端点前缀、HTTP 超时以及管理员/列表可达性,且不会打印 +密钥值。在脚本和 CI 工具中使用 `--json` 获取机器可读输出。 默认端点契约(`OPENCLAW_QA_CONVEX_SITE_URL` + `/qa-credentials/v1`): @@ -285,79 +288,81 @@ pnpm openclaw qa credentials remove --credential-id - 耗尽/可重试:`{ 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 }` - - 活跃 lease 保护:`{ status: "error", code: "LEASE_ACTIVE", ... }` + - 活跃租约保护:`{ status: "error", code: "LEASE_ACTIVE", ... }` - `POST /admin/list`(仅维护者密钥) - 请求:`{ kind?, status?, includePayload?, limit? }` - 成功:`{ status: "ok", credentials, count }` -Telegram kind 的 payload 形状: +Telegram 类型的载荷形状: - `{ groupId: string, driverToken: string, sutToken: string }` -- `groupId` 必须是数字形式的 Telegram 聊天 ID 字符串。 -- `admin/add` 会针对 `kind: "telegram"` 验证此形状,并拒绝格式错误的 payload。 +- `groupId` 必须是数字形式的 Telegram 聊天 id 字符串。 +- `admin/add` 会针对 `kind: "telegram"` 验证此形状,并拒绝格式错误的载荷。 ### 向 QA 添加渠道 -新渠道适配器的架构和场景辅助工具名称位于 [QA overview → 添加渠道](/zh-CN/concepts/qa-e2e-automation#adding-a-channel)。最低要求:在共享的 `qa-lab` host seam 上实现传输 runner,在插件清单中声明 `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 网关鉴权、路由、工具链、解析、配置) + - 进程内集成测试(Gateway 网关认证、路由、工具、解析、配置) - 已知 bug 的确定性回归测试 -- 期望: +- 预期: - 在 CI 中运行 - 不需要真实密钥 - 应该快速且稳定 - - 解析器和公共表面加载器测试必须用生成的小型插件 fixture 证明宽泛的 `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/extension 工作拖慢无关套件。 + - 非定向 `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,并避免自动回复/插件工作让无关套件饥饿。 - `pnpm test --watch` 仍使用原生根 `vitest.config.ts` 项目图,因为多分片 watch 循环并不实用。 - - `pnpm test`、`pnpm test:watch` 和 `pnpm test:perf:imports` 会先通过带作用域的 lane 路由显式文件/目录目标,因此 `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` 不必承担完整根项目启动开销。 - - `pnpm test:changed` 默认会把变更的 git 路径展开到低成本的带作用域 lane:直接测试编辑、同级 `*.test.ts` 文件、显式源码映射,以及本地导入图依赖项。配置/设置/package 编辑不会广泛运行测试,除非你显式使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`。 - - `pnpm check:changed` 是窄范围工作的常规智能本地检查门禁。它会把 diff 分类为 core、core tests、extensions、extension tests、apps、docs、release metadata、live Docker tooling 和 tooling,然后运行匹配的 typecheck、lint 和 guard 命令。它不会运行 Vitest 测试;需要测试证明时,调用 `pnpm test:changed` 或显式的 `pnpm test `。仅发布元数据的版本号提升会运行定向版本/config/root-dependency 检查,并带有一个 guard,拒绝顶层 version 字段之外的 package 变更。 - - Live Docker ACP harness 编辑会运行聚焦检查:live Docker 鉴权脚本的 shell 语法和 live Docker 调度器 dry-run。仅当 diff 限定在 `scripts["test:docker:live-*"]` 时才包含 `package.json` 变更;依赖、导出、版本和其他 package 表面编辑仍使用更宽泛的 guard。 - - 来自 agents、commands、plugins、auto-reply helpers、`plugin-sdk` 以及类似纯工具区域的轻量导入单元测试,会路由到 `unit-fast` lane,该 lane 会跳过 `test/setup-openclaw-runtime.ts`;有状态/运行时较重的文件仍留在现有 lane 上。 - - 选定的 `plugin-sdk` 和 `commands` 辅助源码文件也会把 changed-mode 运行映射到这些轻量 lane 中的显式同级测试,因此辅助工具编辑可以避免重新运行该目录的完整重型套件。 - - `auto-reply` 为顶层 core helpers、顶层 `reply.*` 集成测试,以及 `src/auto-reply/reply/**` 子树设有专用 bucket。CI 会进一步把 reply 子树拆分为 agent-runner、dispatch 和 commands/state-routing 分片,避免一个导入很重的 bucket 占用完整 Node 尾部时间。 - - 常规 PR/main CI 会有意跳过 extension 批量扫描和仅发布使用的 `agentic-plugins` 分片。完整发布验证会为发布候选触发单独的 `Plugin Prerelease` 子 workflow,用于这些插件/extension 较重的套件。 + - `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` 是窄范围工作的常规智能本地检查门禁。它会将差异分类为核心、核心测试、插件、插件测试、应用、文档、发布元数据、live Docker 工具和工具链,然后运行匹配的类型检查、lint 和保护命令。它不会运行 Vitest 测试;如需测试证明,请调用 `pnpm test:changed` 或显式 `pnpm test `。仅发布元数据的版本升级会运行定向版本/配置/根依赖检查,并带有一个保护,拒绝顶层版本字段之外的包变更。 + - live Docker ACP harness 编辑会运行聚焦检查:live Docker 认证脚本的 shell 语法检查,以及 live 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-mode 运行映射到这些轻量通道中的显式同级测试,因此辅助函数编辑可以避免重新运行该目录的完整重型套件。 + - `auto-reply` 为顶层核心辅助函数、顶层 `reply.*` 集成测试以及 `src/auto-reply/reply/**` 子树提供专用桶。CI 还会把 reply 子树进一步拆分为 agent-runner、dispatch 和 commands/state-routing 分片,避免某个导入较重的桶占据完整 Node 尾部时间。 + - 常规 PR/main CI 会有意跳过插件批量扫描和仅发布使用的 `agentic-plugins` 分片。Full Release Validation 会为发布候选触发单独的 `Plugin Prerelease` 子工作流,以运行这些插件/插件较重的套件。 - + - - 当你更改消息工具发现输入或压缩运行时 - 上下文时,请保留两个层级的覆盖率。 - - 为纯路由和规范化边界添加聚焦的辅助工具回归测试。 - - 保持嵌入式 runner 集成套件健康: + - 更改消息工具发现输入或压缩运行时 + 上下文时,请保留两层覆盖。 + - 为纯路由和规范化 + 边界添加聚焦的辅助函数回归测试。 + - 保持嵌入式运行器集成套件健康: `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` 路径;仅辅助函数测试 + 无法充分替代这些集成路径。 @@ -365,64 +370,65 @@ Telegram kind 的 payload 形状: - 基础 Vitest 配置默认使用 `threads`。 - 共享 Vitest 配置固定 `isolate: false`,并在根项目、e2e 和 live 配置中使用 - 非隔离 runner。 - - 根 UI lane 保留其 `jsdom` 设置和 optimizer,但同样运行在 - 共享非隔离 runner 上。 + 非隔离运行器。 + - 根 UI 通道保留其 `jsdom` 设置和优化器,但也在 + 共享非隔离运行器上运行。 - 每个 `pnpm test` 分片都会从共享 Vitest 配置继承相同的 `threads` + `isolate: false` 默认值。 - - `scripts/run-vitest.mjs` 默认会为 Vitest 子 Node + - `scripts/run-vitest.mjs` 默认为 Vitest 子 Node 进程添加 `--no-maglev`,以减少大型本地运行期间的 V8 编译抖动。 - 设置 `OPENCLAW_VITEST_ENABLE_MAGLEV=1` 可与原始 V8 - 行为对比。 + 设置 `OPENCLAW_VITEST_ENABLE_MAGLEV=1` 可与标准 V8 + 行为进行比较。 - - `pnpm changed:lanes` 会显示一个 diff 触发哪些架构 lane。 - - pre-commit hook 仅做格式化。它会重新暂存格式化后的文件, - 不运行 lint、typecheck 或测试。 - - 当你需要智能本地检查门禁时,请在交接或 push 前显式运行 - `pnpm check:changed`。 - - `pnpm test:changed` 默认通过低成本的带作用域 lane 路由。只有当智能体 - 判断 harness、配置、package 或契约编辑确实需要更宽泛的 - Vitest 覆盖率时,才使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`。 - - `pnpm test:max` 和 `pnpm test:changed:max` 保持相同路由 - 行为,只是 worker 上限更高。 - - 本地 worker 自动缩放有意保持保守,并会在主机 load average 已经很高时退避, - 因此多个并发 - Vitest 运行默认造成的影响更小。 - - 基础 Vitest 配置将项目/配置文件标记为 - `forceRerunTriggers`,因此在测试 - 接线变更时 changed-mode 重新运行仍保持正确。 - - 配置在受支持的 - 主机上保持启用 `OPENCLAW_VITEST_FS_MODULE_CACHE`;如果你想为直接 profiling 指定 - 一个显式缓存位置,请设置 `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-mode 重新运行仍保持正确。 + - 配置会在受支持的 + 主机上保持启用 `OPENCLAW_VITEST_FS_MODULE_CACHE`;如果你想为直接性能分析 + 使用一个显式缓存位置,请设置 `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path`。 - - `pnpm test:perf:imports` 会启用 Vitest 导入耗时报告以及 - import-breakdown 输出。 - - `pnpm test:perf:imports:changed` 将相同的 profiling 视图限定到 + - `pnpm test:perf:imports` 会启用 Vitest 导入时长报告以及 + 导入分解输出。 + - `pnpm test:perf:imports:changed` 会将相同的性能分析视图限定到 自 `origin/main` 以来变更的文件。 - 分片计时数据会写入 `.artifacts/vitest-shard-timings.json`。 - 整体配置运行使用配置路径作为 key;include-pattern CI - 分片会附加分片名称,以便单独跟踪过滤后的分片。 - - 当某个热点测试仍把大部分时间花在启动导入上时, - 将重型依赖放在窄的本地 `*.runtime.ts` seam 后面,并 - 直接 mock 该 seam,而不是为了传递给 `vi.mock(...)` 而深度导入运行时辅助工具。 - - `pnpm test:perf:changed:bench -- --ref ` 会将路由后的 - `test:changed` 与该已提交 diff 的原生根项目路径进行比较, - 并打印 wall time 与 macOS max RSS。 - - `pnpm test:perf:changed:bench -- --worktree` 会通过 - `scripts/test-projects.mjs` 和根 Vitest 配置路由变更文件列表, - 对当前 dirty tree 做基准测试。 + 整个配置运行使用配置路径作为键;include-pattern CI + 分片会追加分片名称,以便单独跟踪经过筛选的分片。 + - 当某个热点测试仍将大部分时间花在启动导入上时, + 请把重型依赖放在窄本地 `*.runtime.ts` 衔接点之后,并 + 直接 mock 该衔接点,而不是为了将运行时辅助函数传入 + `vi.mock(...)` 而深度导入它们。 + - `pnpm test:perf:changed:bench -- --ref ` 会把该已提交 + 差异对应的路由后 `test:changed` 与原生根项目路径进行比较, + 并打印 wall time 以及 macOS 最大 RSS。 + - `pnpm test:perf:changed:bench -- --worktree` 会通过将变更文件列表路由到 + `scripts/test-projects.mjs` 和根 Vitest 配置来对当前 + 脏工作树进行基准测试。 - `pnpm test:perf:profile:main` 会为 - Vitest/Vite 启动和 transform 开销写入主线程 CPU profile。 - - `pnpm test:perf:profile:runner` 会为 - 禁用文件并行的单元套件写入 runner CPU+heap profile。 + Vitest/Vite 启动和转换开销写入主线程 CPU profile。 + - `pnpm test:perf:profile:runner` 会在禁用文件并行的情况下,为 + 单元套件写入运行器 CPU+heap profile。 @@ -432,14 +438,14 @@ Telegram kind 的 payload 形状: - 命令:`pnpm test:stability:gateway` - 配置:`vitest.gateway.config.ts`,强制使用一个 worker - 范围: - - 启动一个真实的 loopback Gateway 网关,默认启用诊断 - - 通过诊断事件路径驱动合成的 Gateway 网关消息、memory 和大 payload churn + - 启动一个默认启用诊断的真实 loopback Gateway 网关 + - 通过诊断事件路径驱动合成的 Gateway 网关消息、内存和大载荷抖动 - 通过 Gateway 网关 WS RPC 查询 `diagnostics.stability` - - 覆盖诊断稳定性 bundle 持久化辅助工具 - - 断言 recorder 保持有界、合成 RSS 样本保持低于压力预算,并且每个会话的队列深度回落到零 -- 期望: + - 覆盖诊断稳定性 bundle 持久化辅助函数 + - 断言记录器保持有界、合成 RSS 样本低于压力预算,并且每会话队列深度会清空回零 +- 预期: - CI 安全且不需要密钥 - - 稳定性回归跟进的窄 lane,而不是完整 Gateway 网关套件的替代品 + - 用于稳定性回归跟进的窄通道,不是完整 Gateway 网关套件的替代品 ### E2E(Gateway 网关 smoke) @@ -447,18 +453,18 @@ Telegram kind 的 payload 形状: - 配置:`vitest.e2e.config.ts` - 文件:`src/**/*.e2e.test.ts`、`test/**/*.e2e.test.ts`,以及 `extensions/` 下的内置插件 E2E 测试 - 运行时默认值: - - 使用 Vitest `threads` 并设置 `isolate: false`,与仓库其余部分保持一致。 + - 使用 Vitest `threads`,并设置 `isolate: false`,与仓库其余部分保持一致。 - 使用自适应 worker(CI:最多 2 个,本地:默认 1 个)。 - 默认以静默模式运行,以减少控制台 I/O 开销。 - 有用的覆盖项: - - `OPENCLAW_E2E_WORKERS=` 用于强制指定 worker 数量(上限为 16)。 + - `OPENCLAW_E2E_WORKERS=` 用于强制设置 worker 数量(上限为 16)。 - `OPENCLAW_E2E_VERBOSE=1` 用于重新启用详细控制台输出。 - 范围: - 多实例 Gateway 网关端到端行为 - - WebSocket/HTTP 表面、节点配对,以及更重的网络相关内容 + - WebSocket/HTTP 接口面、节点配对,以及更重的网络功能 - 预期: - - 在 CI 中运行(当流水线中启用时) - - 无需真实密钥 + - 在 CI 中运行(当管线中启用时) + - 不需要真实密钥 - 比单元测试有更多移动部件(可能更慢) ### E2E:OpenShell 后端冒烟测试 @@ -467,16 +473,16 @@ Telegram kind 的 payload 形状: - 文件:`extensions/openshell/src/backend.e2e.test.ts` - 范围: - 通过 Docker 在主机上启动一个隔离的 OpenShell Gateway 网关 - - 从临时本地 Dockerfile 创建沙箱 - - 通过真实的 `sandbox ssh-config` + SSH exec 演练 OpenClaw 的 OpenShell 后端 - - 通过沙箱 fs 桥验证远程规范文件系统行为 + - 从临时本地 Dockerfile 创建一个沙箱 + - 通过真实的 `sandbox ssh-config` + SSH exec 测试 OpenClaw 的 OpenShell 后端 + - 通过沙箱 fs bridge 验证远程规范文件系统行为 - 预期: - - 仅按需启用;不属于默认 `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_COMMAND=/path/to/openshell` 用于指向非默认的 CLI 二进制文件或封装脚本 ### Live(真实提供商 + 真实模型) @@ -485,173 +491,206 @@ Telegram kind 的 payload 形状: - 文件:`src/**/*.live.test.ts`、`test/**/*.live.test.ts`,以及 `extensions/` 下的内置插件 live 测试 - 默认值:由 `pnpm test:live` **启用**(设置 `OPENCLAW_LIVE_TEST=1`) - 范围: - - “这个提供商/模型在 _今天_ 使用真实凭证时是否真的可用?” - - 捕获提供商格式变更、工具调用差异、凭证问题和速率限制行为 + - “这个提供商/模型在 _今天_ 使用真实凭据时是否真的可用?” + - 捕获提供商格式变化、工具调用细节、认证问题和速率限制行为 - 预期: - - 设计上不保证 CI 稳定(真实网络、真实提供商策略、配额、故障) + - 按设计不保证 CI 稳定(真实网络、真实提供商策略、配额、服务中断) - 会花钱 / 使用速率限制额度 - - 优先运行收窄后的子集,而不是“全部” -- Live 运行会 source `~/.profile` 以获取缺失的 API key。 -- 默认情况下,live 运行仍会隔离 `HOME`,并将配置/凭证材料复制到临时测试 home,这样单元测试 fixture 就不能修改你的真实 `~/.openclaw`。 + - 优先运行缩窄后的子集,而不是“所有内容” +- Live 运行会 source `~/.profile` 以读取缺失的 API key。 +- 默认情况下,live 运行仍会隔离 `HOME`,并把配置/认证材料复制到临时测试 home 中,因此单元测试 fixture 无法修改你的真实 `~/.openclaw`。 - 仅当你有意需要 live 测试使用你的真实 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` 按 live 运行覆盖;测试会在收到速率限制响应时重试。 +- `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` 进行每次 live 覆盖;测试会在收到速率限制响应时重试。 - 进度/Heartbeat 输出: - - Live 套件现在会向 stderr 发出进度行,因此即使 Vitest 控制台捕获处于安静状态,长时间的提供商调用也会清晰显示为活跃。 - - `vitest.live.config.ts` 禁用 Vitest 控制台拦截,因此提供商/Gateway 网关进度行会在 live 运行期间立即流式输出。 - - 用 `OPENCLAW_LIVE_HEARTBEAT_MS` 调整直接模型 Heartbeat。 - - 用 `OPENCLAW_LIVE_GATEWAY_HEARTBEAT_MS` 调整 Gateway 网关/探测 Heartbeat。 + - Live 套件现在会向 stderr 发出进度行,因此即使 Vitest 控制台捕获较安静,长时间的提供商调用也会明显处于活动状态。 + - `vitest.live.config.ts` 会禁用 Vitest 控制台拦截,因此提供商/Gateway 网关进度行会在 live 运行期间立即流式输出。 + - 使用 `OPENCLAW_LIVE_HEARTBEAT_MS` 调整直接模型 Heartbeat。 + - 使用 `OPENCLAW_LIVE_GATEWAY_HEARTBEAT_MS` 调整 Gateway 网关/探测 Heartbeat。 ## 我应该运行哪个套件? -使用这张决策表: +使用此决策表: - 编辑逻辑/测试:运行 `pnpm test`(如果你改动很多,也运行 `pnpm test:coverage`) -- 涉及 Gateway 网关网络 / WS 协议 / 配对:添加 `pnpm test:e2e` -- 调试“我的 bot 掉线了”/提供商特定故障/工具调用:运行收窄后的 `pnpm test:live` +- 触及 Gateway 网关网络 / WS 协议 / 配对:额外运行 `pnpm test:e2e` +- 调试“我的 bot 挂了” / 特定提供商故障 / 工具调用:运行缩窄后的 `pnpm test:live` -## Live(触及网络的)测试 +## Live(触及网络)测试 -对于 live 模型矩阵、CLI 后端冒烟测试、ACP 冒烟测试、Codex app-server -harness,以及所有媒体提供商 live 测试(Deepgram、BytePlus、ComfyUI、图像、 -音乐、视频、媒体 harness)以及 live 运行的凭证处理,请参见 +关于 live 模型矩阵、CLI 后端冒烟测试、ACP 冒烟测试、Codex app-server +harness,以及所有媒体提供商 live 测试(Deepgram、BytePlus、ComfyUI、image、 +music、video、media harness),还有 live 运行的凭据处理,请参阅 [测试 live 套件](/zh-CN/help/testing-live)。关于专用的更新和 -插件验证清单,请参见 +插件验证清单,请参阅 [更新和插件测试](/zh-CN/help/testing-updates-plugins)。 -## Docker 运行器(可选的“在 Linux 中可用”检查) +## Docker runner(可选的“在 Linux 中可用”检查) -这些 Docker 运行器分为两类: +这些 Docker runner 分为两类: -- Live 模型运行器:`test:docker:live-models` 和 `test:docker:live-gateway` 只会在仓库 Docker 镜像内运行各自匹配的 profile-key live 文件(`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 live 运行器默认使用较小的冒烟上限,以便完整 Docker 扫描保持实用: +- Live 模型 runner:`test:docker:live-models` 和 `test:docker:live-gateway` 只会在仓库 Docker 镜像中运行各自匹配的 profile-key live 文件(`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 live runner 默认使用较小的冒烟上限,以便完整 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` 构建一次 live 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` 控制进程 slot,而资源上限会阻止重型 live、npm-install 和多服务 lane 同时全部启动。如果单个 lane 比当前上限更重,调度器仍可在池为空时启动它,然后让它单独运行,直到再次有可用容量。默认值为 10 个 slot、`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 秒打印一次 Status,将成功 lane 的耗时存储在 `.artifacts/docker-tests/lane-timings.json`,并在后续运行中使用这些耗时来优先启动更长的 lane。使用 `OPENCLAW_DOCKER_ALL_DRY_RUN=1` 可以在不构建或运行 Docker 的情况下打印加权 lane 清单,或使用 `node scripts/test-docker-all.mjs --plan-json` 打印所选 lane、package/image 需求和凭证的 CI 计划。 -- `Package Acceptance` 是 GitHub 原生的 package gate,用于回答“这个可安装的 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/插件契约、已发布升级保留矩阵、发布默认值和故障分诊,请参见[更新和插件测试](/zh-CN/help/testing-updates-plugins)。 -- 构建和发布检查会在 tsdown 后运行 `scripts/check-cli-bootstrap-imports.mjs`。该 guard 会从 `dist/entry.js` 和 `dist/cli/run-main.js` 遍历静态构建图,如果命令分发前的启动流程导入了 Commander、prompt UI、undici 或 logging 等 package 依赖,则失败;它还会让内置 Gateway 网关运行 chunk 保持在预算以内,并拒绝静态导入已知冷启动 Gateway 网关路径。打包后的 CLI 冒烟测试还覆盖根帮助、onboard 帮助、doctor 帮助、Status、配置 schema 和 model-list 命令。 -- Package Acceptance 旧版兼容性上限为 `2026.4.25`(包含 `2026.4.25-beta.*`)。在该截止点之前,harness 仅容忍已发布 package 的元数据缺口:省略私有 QA inventory 条目、缺少 `gateway install --wrapper`、tarball 派生的 git fixture 中缺少 patch 文件、缺少持久化的 `update.channel`、旧版插件 install-record 位置、缺少 marketplace install-record 持久化,以及 `plugins update` 期间的配置元数据迁移。对于 `2026.4.25` 之后的 package,这些路径都是严格失败。 -- 容器冒烟运行器:`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:plugin-lifecycle-matrix` 和 `test:docker:config-reload` 会启动一个或多个真实容器,并验证更高层级的集成路径。 + `OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=90000`。当你明确需要更大的穷尽式扫描时,覆盖这些环境变量。 +- `test:docker:all` 会先通过 `test:docker:live-build` 构建一次 live Docker 镜像,通过 `scripts/package-openclaw-for-docker.mjs` 将 OpenClaw 打包一次为 npm tarball,然后构建/复用两个 `scripts/e2e/Dockerfile` 镜像。裸镜像只是用于安装/更新/插件依赖 lane 的 Node/Git runner;这些 lane 会挂载预构建 tarball。功能镜像会把同一个 tarball 安装到 `/app`,用于已构建应用功能 lane。Docker lane 定义位于 `scripts/lib/docker-e2e-scenarios.mjs`;planner 逻辑位于 `scripts/lib/docker-e2e-plan.mjs`;`scripts/test-docker-all.mjs` 执行选定的计划。聚合运行使用加权本地调度器:`OPENCLAW_DOCKER_ALL_PARALLELISM` 控制进程 slot,而资源上限会避免较重的 live、npm-install 和多服务 lane 同时全部启动。如果单个 lane 比活动上限更重,调度器仍可在池为空时启动它,并让它单独运行,直到容量再次可用。默认值为 10 个 slot、`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`。runner 默认执行 Docker 预检,移除陈旧的 OpenClaw E2E 容器,每 30 秒打印一次 Status,将成功 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、包/镜像需求和凭据的 CI 计划。 +- `Package Acceptance` 是 GitHub 原生包门禁,用来验证“这个可安装 tarball 作为产品是否可用?”它会从 `source=npm`、`source=ref`、`source=url` 或 `source=artifact` 解析一个候选包,将其上传为 `package-under-test`,然后针对该精确 tarball 运行可复用的 Docker E2E lane,而不是重新打包所选 ref。Profile 按覆盖广度排序:`smoke`、`package`、`product` 和 `full`。关于包/更新/插件契约、已发布升级 survivor 矩阵、发布默认值和故障分诊,请参阅[更新和插件测试](/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 或日志等包依赖,它会失败;它还会让打包的 Gateway 网关运行 chunk 保持在预算内,并拒绝对已知冷启动 Gateway 网关路径的静态导入。打包 CLI 冒烟测试还覆盖根帮助、onboard 帮助、Doctor 帮助、Status、配置 schema 和一个模型列表命令。 +- Package Acceptance 旧版兼容性上限为 `2026.4.25`(包含 `2026.4.25-beta.*`)。在该截止点之前,harness 只容忍已发布包的元数据缺口:省略的私有 QA inventory 条目、缺失的 `gateway install --wrapper`、tarball 派生 git fixture 中缺失的 patch 文件、缺失的持久化 `update.channel`、旧版插件安装记录位置、缺失的 marketplace 安装记录持久化,以及 `plugins update` 期间的配置元数据迁移。对于 `2026.4.25` 之后的包,这些路径都是严格失败。 +- 容器冒烟 runner:`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:plugin-lifecycle-matrix` 和 `test:docker:config-reload` 会启动一个或多个真实容器,并验证更高层级的集成路径。 -Live 模型 Docker 运行器还只会 bind-mount 所需的 CLI 凭证 home(如果运行未收窄,则挂载所有受支持的 home),然后在运行前将它们复制到容器 home 中,这样外部 CLI OAuth 就能刷新 token,而不会修改主机凭证存储: +Live 模型 Docker runner 还只会 bind-mount 所需的 CLI 认证 home(如果运行未缩窄,则挂载所有受支持的 home),然后在运行前把它们复制到容器 home 中,因此外部 CLI OAuth 可以刷新 token,而不会修改主机认证存储: -- 直连模型:`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) +- 直接模型:`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) - 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`) -- 新手引导向导(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,从 package `stable` 切换到 git `dev`,验证持久化的渠道和插件更新后工作正常,然后切回 package `stable` 并检查更新状态。 -- 升级幸存者冒烟测试:`pnpm test:docker:upgrade-survivor` 会把打包后的 OpenClaw tarball 安装到一个脏的旧用户 fixture 上,其中包含智能体、渠道配置、插件 allowlist、过期的插件依赖状态,以及现有工作区/会话文件。它会在没有真实提供商或渠道密钥的情况下运行软件包更新和非交互式 Doctor,然后启动一个 loopback Gateway 网关,并检查配置/状态保留以及启动/Status 预算。 -- 已发布版本升级幸存者冒烟测试:`pnpm test:docker:published-upgrade-survivor` 默认安装 `openclaw@latest`,植入真实感的现有用户文件,用内置命令配方配置该基线,验证生成的配置,将该已发布安装更新到候选 tarball,运行非交互式 Doctor,写入 `.artifacts/upgrade-survivor/summary.json`,然后启动一个 loopback Gateway 网关,并检查已配置 intent、状态保留、启动、`/healthz`、`/readyz` 和 RPC Status 预算。用 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPEC` 覆盖单个基线,让聚合调度器用 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPECS` 展开精确基线,例如 `all-since-2026.4.23`,并用 `OPENCLAW_UPGRADE_SURVIVOR_SCENARIOS` 展开问题形态的 fixture,例如 `reported-issues`;reported-issues 集合包含 `configured-plugin-installs`,用于自动修复外部 OpenClaw 插件安装。Package Acceptance 将这些暴露为 `published_upgrade_survivor_baseline`、`published_upgrade_survivor_baselines` 和 `published_upgrade_survivor_scenarios`。 +- 可观测性冒烟测试:`pnpm qa:otel:smoke` 是一个私有 QA 源码签出通道。它有意不属于包 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 安装到一个脏的旧用户 fixture 上,其中包含智能体、渠道配置、插件 allowlist、过期插件依赖状态,以及现有工作区/会话文件。它会运行包更新和非交互式 Doctor,不使用实时提供商或渠道密钥,然后启动 local loopback Gateway 网关,并检查配置/状态保留情况以及启动/状态预算。 +- 已发布升级幸存者冒烟测试:`pnpm test:docker:published-upgrade-survivor` 默认安装 `openclaw@latest`,播种真实的现有用户文件,用内置命令配方配置该基线,验证生成的配置,将该已发布安装更新到候选 tarball,运行非交互式 Doctor,写入 `.artifacts/upgrade-survivor/summary.json`,然后启动 local loopback Gateway 网关,并检查已配置意图、状态保留、启动、`/healthz`、`/readyz` 和 RPC 状态预算。可用 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPEC` 覆盖单个基线,要求聚合调度器用 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPECS` 展开精确基线,例如 `all-since-2026.4.23`,并用 `OPENCLAW_UPGRADE_SURVIVOR_SCENARIOS` 展开 issue 形态的 fixture,例如 `reported-issues`;reported-issues 集包含 `configured-plugin-installs`,用于自动修复外部 OpenClaw 插件安装。Package Acceptance 将这些暴露为 `published_upgrade_survivor_baseline`、`published_upgrade_survivor_baselines` 和 `published_upgrade_survivor_scenarios`;Full Release Validation 在阻塞路径中使用默认 latest 基线,并且只在 `run_release_soak=true` 或 `release_profile=full` 时展开到 all-since/reported-issues。 - 会话运行时上下文冒烟测试:`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 缓存。更新冒烟测试默认使用 npm `latest` 作为 stable 基线,然后升级到候选 tarball。可在本地用 `OPENCLAW_INSTALL_SMOKE_UPDATE_BASELINE=2026.4.22` 覆盖,或在 GitHub 上用 Install Smoke 工作流的 `update_baseline_version` 输入覆盖。非 root 安装器检查会保留隔离的 npm 缓存,避免 root 拥有的缓存条目掩盖用户本地安装行为。设置 `OPENCLAW_INSTALL_SMOKE_NPM_CACHE_DIR=/path/to/cache` 可在本地重复运行之间复用 root/update/direct-npm 缓存。 +- 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 工作流的 `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 身份验证 + 健康检查):`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 role 快照覆盖链接 URL、cursor-promoted 可点击项、iframe ref 和 frame metadata。 -- OpenAI Responses `web_search` 最小 reasoning 回归:`pnpm test:docker:openai-web-search-minimal`(脚本:`scripts/e2e/openai-web-search-minimal-docker.sh`)通过 Gateway 网关运行模拟的 OpenAI 服务器,验证 `web_search` 将 `reasoning.effort` 从 `minimal` 提升到 `low`,然后强制提供商 schema 拒绝,并检查原始 detail 出现在 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/子智能体 MCP 清理(真实 Gateway 网关 + 隔离 cron 和一次性子智能体运行后的 stdio MCP child teardown):`pnpm test:docker:cron-mcp-cleanup`(脚本:`scripts/e2e/cron-mcp-cleanup-docker.sh`) -- 插件(覆盖本地路径、`file:`、带提升依赖的 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 服务器。 -- 插件更新无变更冒烟测试:`pnpm test:docker:plugin-update`(脚本:`scripts/e2e/plugin-update-unchanged-docker.sh`) -- 插件生命周期矩阵冒烟测试:`pnpm test:docker:plugin-lifecycle-matrix` 会在裸容器中安装打包后的 OpenClaw tarball,安装一个 npm 插件,切换启用/停用,通过本地 npm registry 升级和降级它,删除已安装代码,然后验证卸载仍会移除陈旧状态,同时为每个生命周期阶段记录 RSS/CPU 指标。 -- 配置 reload metadata 冒烟测试:`pnpm test:docker:config-reload`(脚本:`scripts/e2e/config-reload-source-docker.sh`) -- 插件:`pnpm test:docker:plugins` 覆盖本地路径、`file:`、带提升依赖的 npm registry、git moving refs、ClawHub fixture、marketplace updates 和 Claude-bundle enable/inspect 的安装/更新冒烟测试。`pnpm test:docker:plugin-update` 覆盖已安装插件的无变更更新行为。`pnpm test:docker:plugin-lifecycle-matrix` 覆盖带资源跟踪的 npm 插件安装、启用、停用、升级、降级和缺失代码卸载。 +- 智能体删除共享工作区 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 auth + health):`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 role 快照覆盖链接 URL、光标提升的可点击项、iframe 引用和 frame 元数据。 +- OpenAI Responses `web_search` 最小 reasoning 回归:`pnpm test:docker:openai-web-search-minimal`(脚本:`scripts/e2e/openai-web-search-minimal-docker.sh`)通过 Gateway 网关运行一个模拟 OpenAI 服务器,验证 `web_search` 将 `reasoning.effort` 从 `minimal` 提升到 `low`,然后强制提供商 schema 拒绝,并检查原始 detail 出现在 Gateway 网关日志中。 +- MCP 渠道桥接(播种的 Gateway 网关 + stdio 桥接 + 原始 Claude notification-frame 冒烟测试):`pnpm test:docker:mcp-channels`(脚本:`scripts/e2e/mcp-channels-docker.sh`) +- Pi bundle MCP 工具(真实 stdio MCP 服务器 + 嵌入式 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`) +- 插件(针对本地路径、`file:`、带提升依赖的 npm registry、git 移动引用、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 fixture 服务器。 +- 插件更新无变化冒烟测试:`pnpm test:docker:plugin-update`(脚本:`scripts/e2e/plugin-update-unchanged-docker.sh`) +- 插件生命周期矩阵冒烟测试:`pnpm test:docker:plugin-lifecycle-matrix` 会在裸容器中安装打包好的 OpenClaw tarball,安装一个 npm 插件,切换启用/禁用,通过本地 npm registry 升级和降级它,删除已安装代码,然后验证卸载仍会移除过期状态,同时为每个生命周期阶段记录 RSS/CPU 指标。 +- 配置重载元数据冒烟测试:`pnpm test:docker:config-reload`(脚本:`scripts/e2e/config-reload-source-docker.sh`) +- 插件:`pnpm test:docker:plugins` 覆盖本地路径、`file:`、带提升依赖的 npm registry、git 移动引用、ClawHub fixture、marketplace 更新,以及 Claude-bundle 启用/检查的安装/更新冒烟测试。`pnpm test:docker:plugin-update` 覆盖已安装插件的无变化更新行为。`pnpm test:docker:plugin-lifecycle-matrix` 覆盖带资源跟踪的 npm 插件安装、启用、禁用、升级、降级和缺失代码卸载。 -要手动预构建并复用共享功能镜像: +要手动预构建并复用共享 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,因为它们验证的是 package/install 行为,而不是共享的已构建应用运行时。 +设置了 `OPENCLAW_GATEWAY_NETWORK_E2E_IMAGE` 等套件专用镜像覆盖项时,它们仍然优先。`OPENCLAW_SKIP_DOCKER_BUILD=1` 指向远程共享镜像时,如果该镜像尚不在本地,脚本会拉取它。QR 和安装器 Docker 测试保留自己的 Dockerfile,因为它们验证的是包/安装行为,而不是共享的已构建应用运行时。 -实时模型 Docker 运行器还会以只读方式绑定挂载当前 checkout,并将其暂存到容器内的临时工作目录中。这样既能保持运行时镜像精简,又能针对你的确切本地源代码/配置运行 Vitest。暂存步骤会跳过大型的仅本地缓存和应用构建输出,例如 `.pnpm-store`、`.worktrees`、`__openclaw_vitest__`,以及应用本地的 `.build` 或 Gradle 输出目录,这样 Docker live 运行就不会花费数分钟复制机器特定的构件。 -它们还会设置 `OPENCLAW_SKIP_CHANNELS=1`,这样 Gateway 网关 live 探针就不会在容器内启动真实的 Telegram/Discord 等渠道 worker。 -`test:docker:live-models` 仍会运行 `pnpm test:live`,因此当你需要缩小或排除该 Docker lane 中的 Gateway 网关 live 覆盖范围时,也要透传 `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 可能需要完成自己的冷启动设置。 -该 lane 需要可用的 live 模型密钥,而 `OPENCLAW_PROFILE_FILE`(默认 `~/.profile`)是在 Docker 化运行中提供它的主要方式。 -成功运行会打印一个小型 JSON 负载,例如 `{ "ok": true, "model": +实时模型 Docker runner 也会将当前 checkout 以只读方式 bind-mount,并 +将其暂存到容器内的临时 workdir 中。这样可以让运行时镜像保持精简, +同时仍然针对你本地的准确源代码/配置运行 Vitest。 +暂存步骤会跳过大型本地专用缓存和应用构建输出,例如 +`.pnpm-store`、`.worktrees`、`__openclaw_vitest__`,以及应用本地 `.build` 或 +Gradle 输出目录,这样 Docker 实时运行就不会花费数分钟复制 +机器特定的工件。 +它们还会设置 `OPENCLAW_SKIP_CHANNELS=1`,这样 Gateway 网关实时探测就不会在 +容器内启动真实的 Telegram/Discord 等渠道工作进程。 +`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`,然后验证路由后的会话发现、转录读取、附件元数据、live 事件队列行为、出站发送路由,以及通过真实 stdio MCP bridge 传递的 Claude 风格渠道 + 权限通知。通知检查会直接检查原始 stdio MCP 帧,因此该冒烟测试验证的是 bridge 实际发出的内容,而不只是某个特定客户端 SDK 恰好暴露的内容。 -`test:docker:pi-bundle-mcp-tools` 是确定性的,不需要 live 模型密钥。它会构建仓库 Docker 镜像,在容器内启动真实的 stdio MCP 探针服务器,通过嵌入式 Pi bundle MCP 运行时物化该服务器,执行工具,然后验证 `coding` 和 `messaging` 会保留 `bundle-mcp` 工具,而 `minimal` 和 `tools.deny: ["bundle-mcp"]` 会过滤它们。 -`test:docker:cron-mcp-cleanup` 是确定性的,不需要 live 模型密钥。它会启动一个带有真实 stdio MCP 探针服务器的种子化 Gateway 网关,运行一个隔离的 cron turn 和一个 `/subagents spawn` 一次性子 turn,然后验证 MCP 子进程会在每次运行后退出。 +`test:docker:mcp-channels` 有意保持确定性,不需要 +真实的 Telegram、Discord 或 iMessage 账户。它会启动一个带种子的 Gateway 网关 +容器,启动第二个容器来生成 `openclaw mcp serve`,然后 +验证路由后的会话发现、transcript 读取、附件元数据、 +实时事件队列行为、出站发送路由,以及通过真实 stdio MCP bridge 发送的 Claude 风格渠道 + +权限通知。通知检查会直接检查原始 stdio MCP 帧,因此该冒烟测试验证的是 +bridge 实际发出的内容,而不只是某个特定客户端 SDK 恰好暴露的内容。 +`test:docker:pi-bundle-mcp-tools` 是确定性的,不需要实时 +模型密钥。它会构建仓库 Docker 镜像,在容器内启动一个真实的 stdio MCP 探测服务器, +通过嵌入式 Pi bundle MCP 运行时实体化该服务器, +执行工具,然后验证 `coding` 和 `messaging` 会保留 +`bundle-mcp` 工具,而 `minimal` 和 `tools.deny: ["bundle-mcp"]` 会过滤它们。 +`test:docker:cron-mcp-cleanup` 是确定性的,不需要实时模型 +密钥。它会启动一个带种子的 Gateway 网关和一个真实的 stdio MCP 探测服务器,运行一次 +隔离的 cron turn 和一次 `/subagents spawn` 一次性子 turn,然后验证 +MCP 子进程会在每次运行后退出。 手动 ACP 自然语言线程冒烟测试(非 CI): - `bun scripts/dev/discord-acp-plain-language-smoke.ts --channel ...` -- 保留此脚本用于回归/调试工作流。ACP 线程路由验证以后可能还会需要它,因此不要删除。 +- 保留此脚本用于回归/调试工作流。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 auth -- `OPENCLAW_DOCKER_CLI_TOOLS_DIR=...`(默认:`~/.cache/openclaw/docker-cli-tools`)挂载到 `/home/node/.npm-global`,用于 Docker 内缓存 CLI 安装 -- `$HOME` 下的外部 CLI auth 目录/文件会以只读方式挂载到 `/host-auth...` 下,然后在测试开始前复制到 `/home/node/...` +- `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/...` - 默认目录:`.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_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_LIVE_REQUIRE_PROFILE_KEYS=1` 用于确保凭证来自 profile store(而不是环境变量) - `OPENCLAW_OPENWEBUI_MODEL=...` 用于选择 Gateway 网关为 Open WebUI 冒烟测试暴露的模型 -- `OPENCLAW_OPENWEBUI_PROMPT=...` 用于覆盖 Open WebUI 冒烟测试使用的 nonce 检查提示 -- `OPENWEBUI_IMAGE=...` 用于覆盖固定的 Open WebUI 镜像标签 +- `OPENCLAW_OPENWEBUI_PROMPT=...` 用于覆盖 Open WebUI 冒烟测试使用的 nonce 检查 prompt +- `OPENWEBUI_IMAGE=...` 用于覆盖固定的 Open WebUI 镜像 tag ## 文档完整性检查 -文档编辑后运行文档检查:`pnpm check:docs`。 -当你也需要页内标题检查时,运行完整的 Mintlify anchor 验证:`pnpm docs:check-links:anchors`。 +编辑文档后运行文档检查:`pnpm check:docs`。 +当你还需要页内 heading 检查时,运行完整 Mintlify anchor 验证:`pnpm docs:check-links:anchors`。 ## 离线回归(CI 安全) 这些是不使用真实提供商的“真实 pipeline”回归: -- Gateway 网关工具调用(mock OpenAI,真实 Gateway 网关 + 智能体循环):`src/gateway/gateway.test.ts`(用例:"runs a mock OpenAI tool call end-to-end via gateway agent loop") -- Gateway 网关向导(WS `wizard.start`/`wizard.next`,写入配置 + 强制 auth):`src/gateway/gateway.test.ts`(用例:"runs wizard over ws and writes auth token config") +- Gateway 网关工具调用(mock 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") -## 智能体可靠性评估(Skills) +## Agent 可靠性评估(Skills) -我们已经有一些 CI 安全测试,行为类似“智能体可靠性评估”: +我们已经有一些 CI 安全测试,其行为类似“agent 可靠性评估”: -- 通过真实 Gateway 网关 + 智能体循环进行 mock 工具调用(`src/gateway/gateway.test.ts`)。 +- 通过真实 Gateway 网关 + Agent loop 进行 mock 工具调用(`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` 并遵循必需步骤/参数? -- **工作流契约:**断言工具顺序、会话历史延续和沙箱边界的多轮场景。 +- **决策:** 当 prompt 中列出 Skills 时,agent 是否选择了正确的 skill(或避开了无关的 skill)? +- **合规:** agent 是否在使用前读取 `SKILL.md`,并遵循必需的步骤/参数? +- **工作流契约:** 断言工具顺序、会话历史延续和沙箱边界的多轮场景。 未来评估应优先保持确定性: -- 使用 mock 提供商的场景 runner,用于断言工具调用 + 顺序、Skills 文件读取和会话接线。 -- 一小组聚焦 Skills 的场景(使用与避开、门禁、提示注入)。 -- 可选 live 评估(选择加入、由环境变量控制)仅在 CI 安全套件到位后再添加。 +- 一个使用 mock 提供商断言工具调用 + 顺序、skill 文件读取和会话接线的场景 runner。 +- 一小套聚焦 skill 的场景(使用与避免、门控、prompt injection)。 +- 仅在 CI 安全套件就位后,再添加可选实时评估(选择加入、由环境变量门控)。 ## 契约测试(插件和渠道形状) -契约测试会验证每个已注册插件和渠道是否符合其接口契约。它们会遍历所有已发现插件,并运行一组形状和行为断言。默认的 `pnpm test` unit lane 会有意跳过这些共享 seam 和冒烟文件;当你触及共享渠道或提供商 surface 时,请显式运行契约命令。 +契约测试会验证每个已注册的插件和渠道都符合其 +接口契约。它们会迭代所有发现的插件,并运行一套 +形状和行为断言。默认 `pnpm test` 单元通道会有意 +跳过这些共享边界和冒烟文件;当你触碰共享渠道或提供商表面时, +请显式运行契约命令。 ### 命令 -- 全部契约:`pnpm test:contracts` +- 所有契约:`pnpm test:contracts` - 仅渠道契约:`pnpm test:contracts:channels` - 仅提供商契约:`pnpm test:contracts:plugins` @@ -659,30 +698,30 @@ Skills 仍缺少的内容(见 [Skills](/zh-CN/tools/skills)): 位于 `src/channels/plugins/contracts/*.contract.test.ts`: -- **plugin** - 基本插件形状(id、名称、capabilities) +- **plugin** - 基本插件形状(id、name、capabilities) - **setup** - 设置向导契约 - **session-binding** - 会话绑定行为 -- **outbound-payload** - 消息负载结构 +- **outbound-payload** - 消息 payload 结构 - **inbound** - 入站消息处理 -- **actions** - 渠道 action 处理器 +- **actions** - 渠道动作处理器 - **threading** - 线程 ID 处理 -- **directory** - 目录/花名册 API +- **directory** - 目录/roster API - **group-policy** - 群组策略强制执行 ### 提供商 Status 契约 位于 `src/plugins/contracts/*.contract.test.ts`。 -- **status** - 渠道状态探针 +- **status** - 渠道 Status 探测 - **registry** - 插件 registry 形状 ### 提供商契约 位于 `src/plugins/contracts/*.contract.test.ts`: -- **auth** - Auth flow 契约 -- **auth-choice** - Auth 选择/选取 -- **catalog** - 模型 catalog API +- **auth** - 凭证流程契约 +- **auth-choice** - 凭证选择/选取 +- **catalog** - 模型目录 API - **discovery** - 插件发现 - **loader** - 插件加载 - **runtime** - 提供商运行时 @@ -691,24 +730,24 @@ Skills 仍缺少的内容(见 [Skills](/zh-CN/tools/skills)): ### 何时运行 -- 更改 plugin-sdk 导出或 subpath 后 +- 修改 plugin-sdk exports 或 subpaths 后 - 添加或修改渠道或提供商插件后 - 重构插件注册或发现后 -契约测试会在 CI 中运行,不需要真实 API key。 +契约测试会在 CI 中运行,且不需要真实 API keys。 -## 添加回归(指导) +## 添加回归(指南) -当你修复在 live 中发现的提供商/模型问题时: +当你修复在实时环境中发现的提供商/模型问题时: -- 如果可能,添加 CI 安全回归(mock/stub 提供商,或捕获确切的请求形状转换) -- 如果它本质上只能 live 验证(速率限制、auth 策略),请保持 live 测试范围较窄,并通过环境变量选择加入 -- 优先瞄准能捕获该 bug 的最小层级: +- 尽可能添加 CI 安全回归(mock/stub 提供商,或捕获准确的请求形状转换) +- 如果它本质上只能实时测试(rate limits、凭证策略),请保持实时测试范围狭窄,并通过环境变量选择加入 +- 优先定位能捕获 bug 的最小层级: - 提供商请求转换/replay bug → 直接模型测试 - - Gateway 网关会话/历史/工具 pipeline bug → Gateway 网关 live 冒烟测试或 CI 安全 Gateway 网关 mock 测试 -- SecretRef 遍历 guardrail: - - `src/secrets/exec-secret-ref-id-parity.test.ts` 会从 registry 元数据(`listSecretTargetRegistryEntries()`)为每个 SecretRef class 派生一个采样目标,然后断言 traversal-segment exec id 会被拒绝。 - - 如果你在 `src/secrets/target-registry-data.ts` 中添加新的 `includeInPlan` SecretRef 目标系列,请更新该测试中的 `classifyTargetClass`。该测试会对未分类的目标 id 有意失败,确保新 class 不能被静默跳过。 + - Gateway 网关会话/history/工具 pipeline bug → Gateway 网关实时冒烟测试或 CI 安全的 Gateway 网关 mock 测试 +- SecretRef traversal guardrail: + - `src/secrets/exec-secret-ref-id-parity.test.ts` 会从 registry 元数据(`listSecretTargetRegistryEntries()`)中为每个 SecretRef 类派生一个采样目标,然后断言 traversal-segment exec ids 会被拒绝。 + - 如果你在 `src/secrets/target-registry-data.ts` 中添加新的 `includeInPlan` SecretRef target family,请更新该测试中的 `classifyTargetClass`。该测试会有意在未分类的 target ids 上失败,这样新类别就不能被静默跳过。 ## 相关 diff --git a/docs/zh-CN/reference/RELEASING.md b/docs/zh-CN/reference/RELEASING.md index 2bbb4e798..0d493b0d4 100644 --- a/docs/zh-CN/reference/RELEASING.md +++ b/docs/zh-CN/reference/RELEASING.md @@ -1,15 +1,15 @@ --- read_when: - - 正在查找公开发布渠道定义 - - 运行发布验证或包验收 + - 正在查找公共发布渠道定义 + - 运行发布验证或软件包验收 - 查找版本命名和发布节奏 summary: 发布通道、操作员检查清单、验证环境、版本命名和发布节奏 title: 发布策略 x-i18n: - generated_at: "2026-05-04T06:33:30Z" + generated_at: "2026-05-04T22:29:41Z" model: gpt-5.5 provider: openai - source_hash: ef50d3ef5d1e23b4e2c2b097fc4ca9f6d46bf8acb9aea0c9bca6d14e213b88b6 + source_hash: fc9b8f82deb90c57c7777480013a5ee956d1123e0b16134daf90a94bc82952cb source_path: reference/RELEASING.md workflow: 16 --- @@ -17,134 +17,154 @@ x-i18n: OpenClaw 有三个公开发布通道: - 稳定版:带标签的发布,默认发布到 npm `beta`,或在明确请求时发布到 npm `latest` -- 测试版:发布到 npm `beta` 的预发布标签 +- beta 版:发布到 npm `beta` 的预发布标签 - 开发版:`main` 的移动头部 ## 版本命名 -- 稳定发布版本:`YYYY.M.D` +- 稳定版发布版本:`YYYY.M.D` - Git 标签:`vYYYY.M.D` -- 稳定修正版发布版本:`YYYY.M.D-N` +- 稳定版修正版发布版本:`YYYY.M.D-N` - Git 标签:`vYYYY.M.D-N` -- 测试版预发布版本:`YYYY.M.D-beta.N` +- beta 预发布版本:`YYYY.M.D-beta.N` - Git 标签:`vYYYY.M.D-beta.N` -- 不要对月份或日期补零 +- 月或日不要补零 - `latest` 表示当前已提升的稳定版 npm 发布 -- `beta` 表示当前测试版安装目标 -- 稳定版和稳定修正版发布默认发布到 npm `beta`;发布操作员可以明确指定 `latest`,或稍后提升已验证的测试版构建 +- `beta` 表示当前 beta 安装目标 +- 稳定版和稳定版修正版发布默认发布到 npm `beta`;发布操作员可以显式指定 `latest`,或稍后提升经过审核的 beta 构建 - 每个稳定版 OpenClaw 发布都会同时交付 npm 包和 macOS 应用; - 测试版发布通常先验证并发布 npm/包路径,mac 应用构建/签名/公证则保留给稳定版,除非明确请求 + beta 发布通常会先验证并发布 npm/包路径,除非明确请求,否则 + Mac 应用构建/签名/公证仅保留给稳定版 ## 发布节奏 -- 发布按测试版优先推进 -- 只有在最新测试版通过验证后,才会跟进稳定版 -- 维护者通常从基于当前 `main` 创建的 `release/YYYY.M.D` 分支切出发布, +- 发布先进入 beta +- 只有在最新 beta 验证通过后才进入稳定版 +- 维护者通常会从当前 `main` 创建的 `release/YYYY.M.D` 分支切出发布, 这样发布验证和修复不会阻塞 `main` 上的新开发 -- 如果测试版标签已经推送或发布且需要修复,维护者会切出下一个 `-beta.N` 标签,而不是删除或重新创建旧测试版标签 -- 详细发布流程、审批、凭证和恢复说明仅限维护者查看 +- 如果 beta 标签已经推送或发布且需要修复,维护者会切出下一个 + `-beta.N` 标签,而不是删除或重新创建旧 beta 标签 +- 详细发布流程、审批、凭证和恢复说明仅供维护者使用 ## 发布操作员检查清单 此检查清单是发布流程的公开形态。私有凭证、 签名、公证、dist-tag 恢复和紧急回滚详情保留在 -仅限维护者查看的发布运行手册中。 +仅维护者可见的发布运行手册中。 1. 从当前 `main` 开始:拉取最新内容,确认目标提交已推送, - 并确认当前 `main` CI 足够正常,可以从它创建分支。 -2. 使用 `/changelog` 根据真实提交历史重写顶部 `CHANGELOG.md` 部分, - 保持条目面向用户,提交它、推送它,并在创建分支前再次 rebase/pull。 -3. 审查 + 并确认当前 `main` CI 足够健康,可以从它创建分支。 +2. 使用 `/changelog` 基于真实提交历史重写顶部 `CHANGELOG.md` 章节, + 保持条目面向用户,提交它,推送它,并在创建分支前再 rebase/pull + 一次。 +3. 检查以下文件中的发布兼容性记录: `src/plugins/compat/registry.ts` 和 - `src/commands/doctor/shared/deprecation-compat.ts` 中的发布兼容性记录。只有在升级路径仍有覆盖时才移除过期兼容性,或记录为什么有意继续保留。 + `src/commands/doctor/shared/deprecation-compat.ts`。只有在升级路径仍被覆盖时 + 才移除过期兼容性,否则记录为什么有意继续保留它。 4. 从当前 `main` 创建 `release/YYYY.M.D`;不要直接在 `main` 上执行常规发布工作。 -5. 为预期标签更新所有必需的版本位置,运行 - `pnpm plugins:sync`,让可发布的插件包共享发布版本和兼容性元数据,然后运行本地确定性预检: +5. 为目标标签更新每个必需的版本位置,运行 + `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. 如果验证失败,请在发布分支上修复,并重新运行能够证明修复的最小失败文件、通道、工作流作业、包 profile、提供商或模型 allowlist。只有当变更表面使先前证据失效时,才重新运行完整总控流程。 -9. 对于测试版,标记 `vYYYY.M.D-beta.N`,然后从匹配的 `release/YYYY.M.D` 分支运行 `OpenClaw Release Publish`。它会验证 `pnpm plugins:sync:check`, - 先将所有可发布插件包发布到 npm,再将同一集合以 ClawPack npm-pack tarball 的形式发布到 ClawHub,随后使用匹配的 dist-tag 推广已准备好的 OpenClaw npm 预检产物。发布后,针对已发布的 `openclaw@YYYY.M.D-beta.N` 或 + 允许使用完整的 40 字符发布分支 SHA 进行仅验证预检。保存成功的 + `preflight_run_id`。 +7. 对发布分支、标签或完整提交 SHA 运行 `Full Release Validation`, + 启动所有预发布测试。这是四个大型发布测试环境的唯一手动入口点: + Vitest、Docker、QA Lab 和 Package。 +8. 如果验证失败,在发布分支上修复,并重新运行能证明修复的最小失败 + 文件、通道、工作流作业、包配置文件、提供商或模型允许列表。 + 只有当变更表面使先前证据过期时,才重新运行完整总控流程。 +9. 对于 beta,标记 `vYYYY.M.D-beta.N`,然后从匹配的 + `release/YYYY.M.D` 分支运行 `OpenClaw Release Publish`。它会验证 + `pnpm plugins:sync:check`,先将所有可发布插件包发布到 npm, + 再将同一组以 ClawPack npm-pack tarball 的形式发布到 ClawHub, + 然后使用匹配的 dist-tag 提升准备好的 OpenClaw npm 预检产物。 + 发布后,针对已发布的 `openclaw@YYYY.M.D-beta.N` 或 `openclaw@beta` 包运行发布后包验收。如果已推送或已发布的预发布需要修复, - 请切出下一个匹配的预发布编号;不要删除或重写旧预发布。 -10. 对于稳定版,只有在已验证的测试版或候选发布具备所需验证证据后才继续。 - 稳定版 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 发布/预发布说明;并执行发布公告步骤。 + 切出下一个匹配的预发布编号;不要删除或重写旧预发布。 +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 release/prerelease 说明,并执行发布公告 + 步骤。 ## 发布预检 -- 在发布预检前运行 `pnpm check:test-types`,确保测试 TypeScript 在更快的本地 `pnpm check` 门禁之外仍被覆盖 -- 在发布预检前运行 `pnpm check:architecture`,确保更广泛的导入循环和架构边界检查在更快的本地门禁之外为绿色 -- 在 `pnpm release:check` 前运行 `pnpm build && pnpm ui:build`,确保 pack 验证步骤所需的 `dist/*` 发布工件和 Control UI 包已存在 -- 在根版本号提升后、打标签前运行 `pnpm plugins:sync`。它会更新可发布插件包版本、OpenClaw 对等/API 兼容性元数据、构建元数据以及插件变更日志存根,使它们与核心发布版本一致。`pnpm plugins:sync:check` 是非变更式发布守卫;如果忘记这一步,发布工作流会在任何注册表变更前失败。 -- 在发布批准前运行手动 `Full Release Validation` 工作流,从一个入口点启动所有预发布测试盒。它接受分支、标签或完整提交 SHA,派发手动 `CI`,并派发 `OpenClaw Release Checks`,覆盖安装冒烟、包验收、Docker 发布路径套件、live/E2E、OpenWebUI、QA Lab parity、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@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`,复用 Docker E2E 发布调度器针对该 tarball 运行,并可通过 `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 peer/API 兼容性元数据、构建元数据和插件 changelog 存根,使其匹配核心发布版本。`pnpm plugins:sync:check` 是非变更式发布保护;如果忘记此步骤,发布工作流会在任何 registry 变更前失败。 +- 在发布批准前运行手动 `Full Release Validation` 工作流,以便从一个入口点启动所有预发布测试箱。它接受分支、标签或完整提交 SHA,调度手动 `CI`,并为安装 smoke、包验收、跨 OS 包检查、QA Lab parity、Matrix 和 Telegram 车道调度 `OpenClaw Release Checks`。稳定版/默认运行会把详尽的 live/E2E 和 Docker 发布路径 soak 保留在 `run_release_soak=true` 之后;`release_profile=full` 会强制启用 soak。使用 `release_profile=full` 和 `rerun_group=all` 时,它还会针对发布检查中的 `release-package-under-test` 产物运行包 Telegram E2E。发布后提供 `npm_telegram_package_spec`,可让同一个 Telegram E2E 也验证已发布的 npm 包。发布后提供 `package_acceptance_package_spec`,可让 Package Acceptance 针对已交付的 npm 包而不是按 SHA 构建的产物运行包/更新矩阵。提供 `evidence_package_spec`,可让私有证据报告证明验证匹配已发布的 npm 包,而不强制运行 Telegram E2E。 + 示例: + `gh workflow run full-release-validation.yml --ref main -f ref=release/YYYY.M.D` +- 当你希望在发布工作继续进行时为包候选版本获取旁路证明,请运行手动 `Package Acceptance` 工作流。对 `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`,复用 Docker E2E 发布调度器来验证该 tarball,并可通过 `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/subagent 清理、OpenAI web search 和 OpenWebUI - - `full`:带 OpenWebUI 的 Docker 发布路径分块 + 常用 profile: + - `smoke`:安装/渠道/智能体、Gateway 网关网络和配置 reload 车道 + - `package`:不包含 OpenWebUI 或 live ClawHub 的产物原生包/更新/插件车道 + - `product`:包 profile 加上 MCP 渠道、cron/子智能体清理、OpenAI web 搜索和 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 调度会绕过 changed 作用域,并强制运行 Linux Node 分片、内置插件分片、渠道契约、Node 22 兼容性、`check`、`check-additional`、构建 smoke、docs 检查、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 或其他外部收集器。 +- 验证发布 telemetry 时运行 `pnpm qa:otel:smoke`。它会通过本地 OTLP/HTTP receiver 运行 QA-lab,并在不需要 Opik、Langfuse 或其他外部 collector 的情况下验证导出的 trace span 名称、有界属性,以及内容/标识符脱敏。 - 每次带标签发布前运行 `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 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` 工作流。 -- 跨操作系统安装和升级运行时验证属于公开 `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 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 profile 和 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 检查留在自己的车道中,避免拖慢或阻塞发布 +- 携带 secret 的发布检查应通过 `Full Release Validation` 调度,或从 `main`/发布工作流 ref 调度,以便工作流逻辑和 secret 保持受控 +- 只要解析出的提交可从 OpenClaw 分支或发布标签到达,`OpenClaw Release Checks` 就接受分支、标签或完整提交 SHA +- `OpenClaw NPM Release` 的仅验证预检也接受当前完整 40 字符工作流分支提交 SHA,不要求已推送标签 - 该 SHA 路径仅用于验证,不能提升为真实发布 -- 在 SHA 模式下,工作流只会为包元数据检查合成 `v`;真实发布仍需要真实发布标签 -- 两个工作流都把真实发布和提升路径保留在 GitHub 托管 runner 上,而非变更式验证路径可以使用更大的 Blacksmith Linux runner -- 该工作流会同时使用 `OPENAI_API_KEY` 和 `ANTHROPIC_API_KEY` 工作流密钥运行 `OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_CACHE_TEST=1 pnpm test:live:cache` -- 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/修正版版本)来验证已发布注册表安装路径是否能在新的临时前缀中工作 -- 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_*` 环境凭证。 -- 若要从维护者机器运行完整的发布后 beta 冒烟,请使用 `pnpm release:beta-smoke -- --beta betaN`。该 helper 会运行 Parallels npm 更新/全新目标验证,派发 `NPM Telegram Beta E2E`,轮询精确工作流运行,下载工件,并打印 Telegram 报告。 -- 维护者可以通过手动 `NPM Telegram Beta E2E` 工作流从 GitHub Actions 运行同一个发布后检查。它有意设为仅手动,不会在每次合并时运行。 -- 维护者发布自动化现在使用预检再提升: +- 在 SHA 模式下,工作流仅为包元数据检查合成 `v`;真实发布仍需要真实发布标签 +- 两个工作流都会把真实发布和提升路径保留在 GitHub 托管 runner 上,而非变更式验证路径可以使用更大的 Blacksmith Linux runner +- 该工作流会同时使用 `OPENAI_API_KEY` 和 `ANTHROPIC_API_KEY` 工作流 secret 来运行 `OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_CACHE_TEST=1 pnpm test:live:cache` +- npm 发布预检不再等待单独的发布检查车道 +- 批准前运行 `RELEASE_TAG=vYYYY.M.D node --import tsx scripts/openclaw-npm-release-check.ts`(或匹配的 beta/correction 标签) +- npm 发布后,运行 `node --import tsx scripts/openclaw-npm-postpublish-verify.ts YYYY.M.D`(或匹配的 beta/correction 版本),在全新的临时前缀中验证已发布 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_*` 环境凭据。 +- 若要从维护者机器运行完整的发布后 beta smoke,请使用 `pnpm release:beta-smoke -- --beta betaN`。该 helper 会运行 Parallels npm 更新/全新目标验证,调度 `NPM Telegram Beta E2E`,轮询精确工作流运行,下载产物,并打印 Telegram 报告。 +- 维护者可以通过手动 `NPM Telegram Beta E2E` 工作流从 GitHub Actions 运行同一个发布后检查。它有意设为仅手动,不会在每次 merge 时运行。 +- 维护者发布自动化现在使用预检后提升: - 真实 npm 发布必须通过成功的 npm `preflight_run_id` - - 真实 npm 发布必须从与成功预检运行相同的 `main` 或 `release/YYYY.M.D` 分支派发 - - stable npm 发布默认使用 `beta` - - stable 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` 这样的 stable 修正发布,发布后验证器还会检查从 `YYYY.M.D` 到 `YYYY.M.D-N` 的相同临时前缀升级路径,确保发布修正不会静默地让旧的全局安装停留在基础 stable 载荷上 -- npm 发布预检会失败关闭,除非 tarball 同时包含 `dist/control-ui/index.html` 和非空的 `dist/control-ui/assets/` 载荷,这样我们不会再次发布空的浏览器仪表盘 -- 发布后验证还会检查已发布插件入口点和包元数据是否存在于已安装的注册表布局中。若某个发布缺少插件运行时载荷,发布后验证器会失败,且不能提升到 `latest`。 -- `pnpm test:install:smoke` 还会对候选更新 tarball 执行 npm pack `unpackedSize` 预算,因此安装器 e2e 会在发布发布路径前捕获意外的包体积膨胀 -- 如果发布工作触及 CI 规划、插件时序清单或插件测试矩阵,请在批准前重新生成并审查由 planner 拥有的 `.github/workflows/plugin-prerelease.yml` 中 `plugin-prerelease-extension-shard` 矩阵输出,确保发布说明不会描述过时的 CI 布局 -- stable macOS 发布就绪性还包括更新器表面: - - GitHub 发布必须最终带有打包好的 `.zip`、`.dmg` 和 `.dSYM.zip` - - 发布后,`main` 上的 `appcast.xml` 必须指向新的 stable zip - - 打包后的应用必须保留非 debug bundle id、非空 Sparkle feed URL,以及不低于该发布版本规范 Sparkle 构建下限的 `CFBundleVersion` + - 真实 npm 发布必须从与成功预检运行相同的 `main` 或 `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`,而公开 repo 保持仅 OIDC 发布 + - 公开 `macOS Release` 仅用于验证;当标签只存在于发布分支但工作流从 `main` 调度时,设置 `public_release_branch=release/YYYY.M.D` + - 真实私有 Mac 发布必须通过成功的私有 Mac `preflight_run_id` 和 `validate_run_id` + - 真实发布路径会提升准备好的产物,而不是重新构建它们 +- 对于 `YYYY.M.D-N` 这样的稳定版 correction 发布,发布后 verifier 还会检查同一个临时前缀从 `YYYY.M.D` 升级到 `YYYY.M.D-N` 的路径,确保发布 correction 不会静默地让较旧的全局安装停留在基础稳定版 payload 上 +- 除非 tarball 同时包含 `dist/control-ui/index.html` 和非空的 `dist/control-ui/assets/` payload,否则 npm 发布预检会失败关闭,避免我们再次交付空的浏览器 dashboard +- 发布后验证还会检查已发布插件入口点和包元数据是否存在于安装后的 registry 布局中。缺少插件运行时 payload 的发布会让 postpublish verifier 失败,并且不能提升到 `latest`。 +- `pnpm test:install:smoke` 也会对候选更新 tarball 强制执行 npm pack `unpackedSize` 预算,因此 installer e2e 会在发布路径前捕获意外的 pack 膨胀 +- 如果发布工作触及 CI 规划、插件 timing manifests 或插件测试矩阵,请在批准前重新生成并审查 planner 拥有的 `.github/workflows/plugin-prerelease.yml` 中的 `plugin-prerelease-extension-shard` 矩阵输出,确保发布说明不会描述过时的 CI 布局 +- 稳定版 macOS 发布就绪还包括 updater surfaces: + - GitHub release 最终必须包含打包后的 `.zip`、`.dmg` 和 `.dSYM.zip` + - 发布后,`main` 上的 `appcast.xml` 必须指向新的稳定版 zip + - 打包后的 app 必须保留非 debug bundle id、非空 Sparkle feed URL,并且 `CFBundleVersion` 不低于该发布版本的规范 Sparkle build floor -## 发布测试盒 +## 发布测试箱 -`Full Release Validation` 是操作员从一个入口点启动所有预发布测试的方式。对于快速变化分支上的固定提交证明,请使用该 helper,确保每个子工作流都从固定到目标 SHA 的临时分支运行: +`Full Release Validation` 是操作员从单个入口点启动所有预发布测试的方式。对于快速移动分支上的固定提交证明,请使用 helper,确保每个子工作流都从固定到目标 SHA 的临时分支运行: ```bash pnpm ci:full-release --sha ``` -该 helper 会推送 `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 \ @@ -156,20 +176,20 @@ 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-package-under-test` 工件,并在 `release_profile=full` 且 `rerun_group=all` 时,或在设置了 `npm_telegram_package_spec` 时,分发独立的包 Telegram E2E。随后,`OpenClaw Release -Checks` 会展开安装烟雾测试、跨 OS 发布检查、实时/E2E Docker 发布路径覆盖、带 Telegram 包 QA 的 Package Acceptance、QA Lab 对等性、实时 Matrix 和实时 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` 指向较旧的发布分支或标签也是如此。不存在单独的 Full Release Validation 工作流 ref 输入;通过选择工作流运行 ref 来选择受信任的 harness。不要在移动的 `main` 上使用 `--ref main -f ref=` 做精确提交证明;原始提交 SHA 不能作为工作流分发 ref,因此请使用 `pnpm ci:full-release --sha ` 创建固定的临时分支。 +该工作流会解析目标 ref,使用 `target_ref=` 触发手动 `CI`,触发 `OpenClaw Release Checks`,为面向包的检查准备父级 `release-package-under-test` 工件,并在 `release_profile=full` 且 `rerun_group=all`,或设置了 `npm_telegram_package_spec` 时,触发独立的包 Telegram E2E。随后,`OpenClaw Release Checks` 会扇出安装 smoke、跨 OS 发布检查、启用 soak 时的 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` 指向较旧的发布分支或标签也是如此。没有单独的 Full Release Validation 工作流 ref 输入;通过选择工作流运行 ref 来选择受信任的 harness。 +不要在移动的 `main` 上使用 `--ref main -f ref=` 作为精确提交证明;原始提交 SHA 不能作为工作流触发 ref,因此请使用 `pnpm ci:full-release --sha ` 创建固定的临时分支。 -使用 `release_profile` 选择实时/提供商覆盖范围: +使用 `release_profile` 选择 live/provider 覆盖广度: -- `minimum`:最快的发布关键 OpenAI/核心实时和 Docker 路径 -- `stable`:在 minimum 基础上增加用于发布批准的稳定提供商/后端覆盖 -- `full`:在 stable 基础上增加广泛的 advisory 提供商/媒体覆盖 +- `minimum`:最快的发布关键 OpenAI/core live 和 Docker 路径 +- `stable`:minimum 加上用于发布批准的稳定 provider/backend 覆盖 +- `full`:stable 加上广泛的 advisory provider/media 覆盖 -`OpenClaw Release Checks` 使用受信任的工作流 ref 将目标 ref 解析一次为 `release-package-under-test`,并在发布路径 Docker 检查和 Package Acceptance 中复用该工件。这会让所有面向包的盒子使用相同字节,并避免重复构建包。 -当仓库/组织变量已设置时,跨 OS OpenAI 安装烟雾测试使用 `OPENCLAW_CROSS_OS_OPENAI_MODEL`,否则使用 `openai/gpt-5.4`,因为此 lane 验证的是包安装、新手引导、Gateway 网关启动和一次实时智能体轮次,而不是基准测试最慢的默认模型。更广泛的实时提供商矩阵仍然负责模型特定覆盖。 +当发布阻塞 lane 为绿色,并且你希望在晋级前执行详尽的 live/E2E、Docker 发布路径以及 all-since-2026.4.23 upgrade-survivor 扫描时,对 `stable` 使用 `run_release_soak=true`。`full` 隐含 `run_release_soak=true`。 + +`OpenClaw Release Checks` 使用受信任的工作流 ref 将目标 ref 一次性解析为 `release-package-under-test`,并在 soak 运行时,在跨 OS、Package Acceptance 和发布路径 Docker 检查中复用该工件。这会让所有面向包的盒子使用相同字节,并避免重复构建包。当设置了 repo/org 变量时,跨 OS OpenAI 安装 smoke 使用 `OPENCLAW_CROSS_OS_OPENAI_MODEL`,否则使用 `openai/gpt-5.4`,因为此 lane 证明的是包安装、新手引导、Gateway 网关启动和一次 live 智能体轮次,而不是对最慢默认模型进行基准测试。更广泛的 live provider 矩阵仍然是模型特定覆盖的位置。 根据发布阶段使用这些变体: @@ -201,22 +221,22 @@ gh workflow run full-release-validation.yml \ -f npm_telegram_provider_mode=mock-openai ``` -在聚焦修复后的第一次重跑中,不要使用完整总括工作流。如果一个盒子失败,请使用失败的子工作流、作业、Docker lane、包配置、模型提供商或 QA lane 作为下一次证明。只有当修复更改了共享发布编排,或让先前的全盒子证据过期时,才再次运行完整总括工作流。总括工作流的最终验证器会重新检查记录的子工作流运行 ID,因此当某个子工作流成功重跑后,只需重跑失败的 `Verify full validation` 父作业。 +不要把完整 umbrella 作为聚焦修复后的第一次重跑。如果一个盒子失败,请将失败的子工作流、作业、Docker lane、包配置文件、模型提供商或 QA lane 用作下一次证明。只有当修复更改了共享发布编排,或使先前的全盒证据过期时,才再次运行完整 umbrella。umbrella 的最终验证器会重新检查记录的子工作流运行 ID,因此在子工作流成功重跑后,只需重跑失败的 `Verify full validation` 父作业。 -对于有界恢复,请将 `rerun_group` 传给总括工作流。`all` 是真正的候选发布运行,`ci` 仅运行普通 CI 子项,`plugin-prerelease` 仅运行发布专用插件子项,`release-checks` 运行每个发布盒子,更窄的发布组为 `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 包工件。 +对于有界恢复,将 `rerun_group` 传递给 umbrella。`all` 是真正的发布候选运行,`ci` 只运行普通 CI 子项,`plugin-prerelease` 只运行仅发布的插件子项,`release-checks` 会运行每个发布盒子,较窄的发布组是 `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 包工件。 ### Vitest -Vitest 盒子是手动 `CI` 子工作流。手动 CI 会有意绕过变更作用域,并强制针对候选发布运行普通测试图:Linux Node 分片、内置插件分片、渠道契约、Node 22 兼容性、`check`、`check-additional`、构建烟雾测试、文档检查、Python Skills、Windows、macOS、Android 和 Control UI i18n。 +Vitest 盒子是手动 `CI` 子工作流。手动 CI 会有意绕过 changed 作用域,并为发布候选强制执行普通测试图:Linux Node 分片、内置插件分片、渠道契约、Node 22 兼容性、`check`、`check-additional`、build smoke、docs checks、Python skills、Windows、macOS、Android 和 Control UI i18n。 -使用此盒子回答“源代码树是否通过了完整普通测试套件?”它不同于发布路径产品验证。需要保留的证据: +使用这个盒子回答“源代码树是否通过了完整的普通测试套件?”它不同于发布路径产品验证。需要保留的证据: -- `Full Release Validation` 摘要,显示已分发的 `CI` 运行 URL -- `CI` 在精确目标 SHA 上为绿色 +- `Full Release Validation` 摘要,显示已触发的 `CI` 运行 URL +- `CI` 在精确目标 SHA 上运行绿色 - 调查回归时来自 CI 作业的失败或缓慢分片名称 -- 当运行需要性能分析时,保留 `.artifacts/vitest-shard-timings.json` 等 Vitest 计时工件 +- 当运行需要性能分析时,保留 Vitest 时间工件,例如 `.artifacts/vitest-shard-timings.json` -仅当发布需要确定性的普通 CI,而不需要 Docker、QA Lab、实时、跨 OS 或包盒子时,才直接运行手动 CI: +仅当发布需要确定性的普通 CI,但不需要 Docker、QA Lab、live、跨 OS 或包盒子时,才直接运行手动 CI: ```bash gh workflow run ci.yml --ref main -f target_ref=release/YYYY.M.D @@ -224,51 +244,51 @@ gh workflow run ci.yml --ref main -f target_ref=release/YYYY.M.D ### Docker -Docker 盒子位于 `OpenClaw Release Checks` 中,通过 `openclaw-live-and-e2e-checks-reusable.yml` 以及发布模式 `install-smoke` 工作流实现。它通过打包的 Docker 环境验证候选发布,而不是只做源代码级测试。 +Docker 盒子存在于 `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 作业作为单独的 install-smoke 分片运行 - 仓库 E2E lane -- 发布路径 Docker 分块:`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` 分块中包含 OpenWebUI 覆盖 -- 拆分的内置插件安装/卸载 lane:从 `bundled-plugin-install-uninstall-0` 到 `bundled-plugin-install-uninstall-23` -- 当发布检查包含实时套件时,包含实时/E2E 提供商套件和 Docker 实时模型覆盖 +- 发布路径 Docker chunk:`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 覆盖 +- 拆分的内置插件安装/卸载 lane,从 `bundled-plugin-install-uninstall-0` 到 `bundled-plugin-install-uninstall-23` +- 当 release checks 包含 live 套件时的 live/E2E provider 套件和 Docker live 模型覆盖 -重跑前先使用 Docker 工件。发布路径调度器会上传 `.artifacts/docker-tests/`,其中包含 lane 日志、`summary.json`、`failures.json`、阶段计时、调度器计划 JSON 和重跑命令。对于聚焦恢复,请在可复用 live/E2E 工作流上使用 `docker_lanes=`,而不是重跑所有发布分块。生成的重跑命令会在可用时包含先前的 `package_artifact_run_id` 和已准备的 Docker 镜像输入,因此失败的 lane 可以复用相同的 tarball 和 GHCR 镜像。 +重跑前先使用 Docker 工件。发布路径调度器会上传 `.artifacts/docker-tests/`,其中包含 lane 日志、`summary.json`、`failures.json`、阶段时间、调度器计划 JSON 和重跑命令。对于聚焦恢复,请在可复用 live/E2E 工作流上使用 `docker_lanes=`,而不是重跑所有发布 chunk。生成的重跑命令在可用时包含先前的 `package_artifact_run_id` 和已准备的 Docker 镜像输入,因此失败的 lane 可以复用相同的 tarball 和 GHCR 镜像。 ### QA Lab -QA Lab 盒子也是 `OpenClaw Release Checks` 的一部分。它是智能体行为和渠道级发布门禁,与 Vitest 和 Docker 包机制分离。 +QA Lab 盒子也是 `OpenClaw Release Checks` 的一部分。它是智能体行为和渠道级发布门禁,独立于 Vitest 和 Docker 包机制。 发布 QA Lab 覆盖包括: -- 使用 agentic parity pack 将 OpenAI 候选 lane 与 Opus 4.6 基线进行比较的 mock parity lane -- 使用 `qa-live-shared` 环境的快速实时 Matrix QA 配置 -- 使用 Convex CI 凭证租约的实时 Telegram QA lane -- 当发布遥测需要显式本地证明时,运行 `pnpm qa:otel:smoke` +- mock parity lane,使用 agentic parity pack 将 OpenAI 候选 lane 与 Opus 4.6 基线进行比较 +- 使用 `qa-live-shared` 环境的快速 live Matrix QA 配置文件 +- 使用 Convex CI 凭据租约的 live Telegram QA lane +- 当发布遥测需要明确本地证明时运行 `pnpm qa:otel:smoke` -使用此盒子回答“发布在 QA 场景和实时渠道流程中是否行为正确?”批准发布时,保留 parity、Matrix 和 Telegram lane 的工件 URL。完整 Matrix 覆盖仍可作为手动分片 QA-Lab 运行使用,而不是默认发布关键 lane。 +使用这个盒子回答“发布在 QA 场景和 live 渠道流程中是否行为正确?”批准发布时保留 parity、Matrix 和 Telegram lane 的工件 URL。完整 Matrix 覆盖仍可作为手动分片 QA-Lab 运行使用,而不是默认的发布关键 lane。 ### Package -Package 盒子是可安装产品门禁。它由 `Package Acceptance` 和解析器 `scripts/resolve-openclaw-package-candidate.mjs` 支撑。解析器会将候选项规范化为供 Docker E2E 使用的 `package-under-test` tarball,验证包清单,记录包版本和 SHA-256,并将工作流 harness ref 与包源 ref 分开。 +Package 盒子是可安装产品门禁。它由 `Package Acceptance` 和解析器 `scripts/resolve-openclaw-package-candidate.mjs` 支持。解析器会将候选规范化为 Docker E2E 使用的 `package-under-test` tarball,验证包清单,记录包版本和 SHA-256,并保持工作流 harness ref 与包源 ref 分离。 支持的候选来源: - `source=npm`:`openclaw@beta`、`openclaw@latest`,或精确的 OpenClaw 发布版本 - `source=ref`:使用所选 `workflow_ref` harness 打包受信任的 `package_ref` 分支、标签或完整提交 SHA -- `source=url`:下载一个 HTTPS `.tgz`,并要求提供 `package_sha256` +- `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 保持迁移、更新、陈旧插件依赖清理、离线插件 fixture、插件更新和 Telegram 包 QA。升级矩阵覆盖从 `2026.4.23` 到 `latest` 的每个稳定 npm 已发布基线;对于已经发布的候选项,请使用 `source=npm` 的 Package Acceptance;对于发布前由 SHA 支撑的本地 npm tarball,请使用 `source=ref`/`source=artifact`。它是 GitHub 原生替代方案,可取代过去大多数需要 Parallels 的包/更新覆盖。跨 OS 发布检查对于 OS 特定的新手引导、安装器和平台行为仍然重要,但包/更新产品验证应优先使用 Package Acceptance。 +`OpenClaw Release Checks` 使用 `source=artifact`、准备好的发布包工件、`suite_profile=custom`、`docker_lanes=doctor-switch update-channel-switch upgrade-survivor published-upgrade-survivor plugins-offline plugin-update`、`telegram_mode=mock-openai` 运行 Package Acceptance。Package Acceptance 会针对相同解析出的 tarball 保持迁移、更新、陈旧插件依赖清理、离线插件 fixture、插件更新和 Telegram 包 QA。阻塞发布检查使用默认的最新已发布包基线;`run_release_soak=true` 或 `release_profile=full` 会扩展到从 `2026.4.23` 到 `latest` 的每个稳定 npm 已发布基线,以及 reported-issue fixture。对于已经发布的候选,请使用带 `source=npm` 的 Package Acceptance;对于发布前由 SHA 支持的本地 npm tarball,请使用 `source=ref`/`source=artifact`。它是 GitHub 原生替代方案,用来覆盖此前大多需要 Parallels 的包/更新验证。跨 OS 发布检查对于 OS 特定的新手引导、安装器和平台行为仍然重要,但包/更新产品验证应优先使用 Package Acceptance。 -更新和插件验证的规范清单是[更新和插件测试](/zh-CN/help/testing-updates-plugins)。在判断哪个本地、Docker、Package Acceptance 或 release-check lane 能证明插件安装/更新、Doctor 清理或已发布包迁移变更时使用它。从每个稳定 `2026.4.23+` 包进行详尽的已发布更新迁移,是单独的手动 `Update Migration` 工作流,不属于 Full Release CI。 +更新和插件验证的规范清单是[更新和插件测试](/zh-CN/help/testing-updates-plugins)。在决定哪个本地、Docker、Package Acceptance 或 release-check lane 能证明插件安装/更新、Doctor 清理或已发布包迁移更改时使用它。从每个稳定 `2026.4.23+` 包进行的详尽已发布更新迁移是单独的手动 `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` 为止的包可以针对已发布到 npm 的元数据缺口使用兼容路径:tarball 中缺失的私有 QA 清单条目、缺失的 `gateway install --wrapper`、tarball 派生 git fixture 中缺失的 patch 文件、缺失的持久化 `update.channel`、旧版插件安装记录位置、缺失的 marketplace 安装记录持久化,以及 `plugins update` 期间的配置元数据迁移。已发布的 `2026.4.26` 包可以对已经发布的本地构建元数据 stamp 文件发出警告。更晚的包必须满足现代包契约;这些相同缺口会导致发布验证失败。 -当发布问题涉及实际可安装包时,使用更广泛的 Package Acceptance 配置: +当发布问题涉及实际可安装包时,使用更广泛的 Package Acceptance 配置文件: ```bash gh workflow run package-acceptance.yml \ @@ -280,28 +300,27 @@ gh workflow run package-acceptance.yml \ -f published_upgrade_survivor_baseline=openclaw@2026.4.26 ``` -常见包配置: +常见包配置文件: -- `smoke`:快速 package 安装/渠道/智能体、Gateway 网关网络和配置重载通道 -- `package`:不依赖 live ClawHub 的安装/更新/插件 package 契约;这是 release-check 默认值 +- `smoke`:快速的包安装/渠道/智能体、Gateway 网关网络和配置重载通道 +- `package`:不依赖实时 ClawHub 的安装/更新/插件包契约;这是发布检查的默认项 - `product`:`package` 加上 MCP 渠道、cron/子智能体清理、OpenAI Web 搜索和 OpenWebUI - `full`:带 OpenWebUI 的 Docker 发布路径分块 - `custom`:用于聚焦重跑的精确 `docker_lanes` 列表 -对于 package-candidate Telegram 验证,请在 Package Acceptance 上启用 `telegram_mode=mock-openai` 或 -`telegram_mode=live-frontier`。该 workflow 会把解析后的 -`package-under-test` tarball 传入 Telegram 通道;独立的 -Telegram workflow 仍接受已发布的 npm 规格,用于发布后检查。 +对于候选包的 Telegram 验证,在 Package Acceptance 上启用 `telegram_mode=mock-openai` 或 +`telegram_mode=live-frontier`。该工作流会把解析出的 `package-under-test` tarball 传入 Telegram 通道;独立的 +Telegram 工作流仍然接受已发布的 npm 规格用于发布后检查。 -## 发布自动化 +## 发布发布自动化 -`OpenClaw Release Publish` 是常规的变更发布入口点。它会按发布所需顺序编排 trusted-publisher workflows: +`OpenClaw Release Publish` 是常规的变更型发布入口点。它会按发布所需的顺序编排受信任发布者工作流: -1. 检出发布标签并解析其 commit SHA。 +1. 签出发布标签并解析其提交 SHA。 2. 验证该标签可从 `main` 或 `release/*` 到达。 3. 运行 `pnpm plugins:sync:check`。 4. 使用 `publish_scope=all-publishable` 和 `ref=` 分发 `Plugin NPM Release`。 -5. 使用相同 scope 和 SHA 分发 `Plugin ClawHub Release`。 +5. 使用相同范围和 SHA 分发 `Plugin ClawHub Release`。 6. 使用发布标签、npm dist-tag 和保存的 `preflight_run_id` 分发 `OpenClaw NPM Release`。 Beta 发布示例: @@ -334,59 +353,66 @@ gh workflow run openclaw-release-publish.yml \ -f npm_dist_tag=latest ``` -仅在聚焦修复或重新发布工作中使用较底层的 `Plugin NPM Release` 和 `Plugin ClawHub Release` workflows。对于选定插件修复,请向 `OpenClaw Release Publish` 传入 `plugin_publish_scope=selected` 和 `plugins=@openclaw/name`,或在不得发布 OpenClaw package 时直接分发子 workflow。 +仅在聚焦修复或重新发布工作时使用较低层级的 `Plugin NPM Release` 和 `Plugin ClawHub Release` 工作流。对于选定插件修复,将 +`plugin_publish_scope=selected` 和 `plugins=@openclaw/name` 传给 +`OpenClaw Release Publish`;或者当不得发布 OpenClaw 包时,直接分发子工作流。 -## NPM workflow 输入 +## NPM 工作流输入 -`OpenClaw NPM Release` 接受这些由操作者控制的输入: +`OpenClaw NPM Release` 接受这些由操作员控制的输入: -- `tag`:必需的发布标签,例如 `v2026.4.2`、`v2026.4.2-1` 或 `v2026.4.2-beta.1`;当 `preflight_only=true` 时,也可以是当前完整的 40 字符 workflow 分支 commit SHA,用于仅验证的 preflight -- `preflight_only`:`true` 表示仅验证/构建/package,`false` 表示真实发布路径 -- `preflight_run_id`:真实发布路径必需,workflow 会复用成功 preflight 运行中准备好的 tarball +- `tag`:必需的发布标签,例如 `v2026.4.2`、`v2026.4.2-1` 或 + `v2026.4.2-beta.1`;当 `preflight_only=true` 时,它也可以是当前完整的 40 字符工作流分支提交 SHA,用于仅验证的预检 +- `preflight_only`:`true` 表示仅验证/构建/打包,`false` 表示真实发布路径 +- `preflight_run_id`:真实发布路径必需,使工作流复用成功预检运行中准备好的 tarball - `npm_dist_tag`:发布路径的 npm 目标标签;默认值为 `beta` -`OpenClaw Release Publish` 接受这些由操作者控制的输入: +`OpenClaw Release Publish` 接受这些由操作员控制的输入: -- `tag`:必需的发布标签;必须已经存在 -- `preflight_run_id`:成功的 `OpenClaw NPM Release` preflight 运行 ID;当 `publish_openclaw_npm=true` 时必需 -- `npm_dist_tag`:OpenClaw package 的 npm 目标标签 +- `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/*` package 名称 -- `publish_openclaw_npm`:默认值为 `true`;仅在把 workflow 用作仅插件修复编排器时设置为 `false` +- `plugins`:当 `plugin_publish_scope=selected` 时,逗号分隔的 `@openclaw/*` 包名 +- `publish_openclaw_npm`:默认值为 `true`;仅在把该工作流用作仅插件修复编排器时设置为 `false` -`OpenClaw Release Checks` 接受这些由操作者控制的输入: +`OpenClaw Release Checks` 接受这些由操作员控制的输入: -- `ref`:要验证的分支、标签或完整 commit SHA。带 secret 的检查要求解析后的 commit 可从 OpenClaw 分支或发布标签到达。 +- `ref`:要验证的分支、标签或完整提交 SHA。带有密钥的检查要求解析出的提交可从 OpenClaw 分支或发布标签到达。 +- `run_release_soak`:在稳定版/默认发布检查中选择加入完整的实时/E2E、Docker 发布路径和所有既往升级幸存者 soak。`release_profile=full` 会强制启用它。 规则: - 稳定版和修正版标签可以发布到 `beta` 或 `latest` - Beta 预发布标签只能发布到 `beta` -- 对于 `OpenClaw NPM Release`,仅当 `preflight_only=true` 时才允许输入完整 commit SHA +- 对于 `OpenClaw NPM Release`,仅当 `preflight_only=true` 时才允许输入完整提交 SHA - `OpenClaw Release Checks` 和 `Full Release Validation` 始终仅用于验证 -- 真实发布路径必须使用 preflight 期间所用的同一个 `npm_dist_tag`;workflow 会在发布继续前验证该元数据 +- 真实发布路径必须使用预检期间使用的同一个 `npm_dist_tag`;工作流会在发布前验证该元数据仍然一致 -## 稳定版 npm 发布顺序 +## 稳定版 npm 发布序列 切稳定版 npm 发布时: 1. 使用 `preflight_only=true` 运行 `OpenClaw NPM Release` - - 在标签存在之前,你可以使用当前完整的 workflow 分支 commit SHA,对 preflight workflow 做仅验证的 dry run -2. 对常规 beta 优先流程选择 `npm_dist_tag=beta`,或者仅在你有意直接发布稳定版时选择 `latest` -3. 当你想从一个手动 workflow 获得常规 CI 加 live prompt cache、Docker、QA Lab、Matrix 和 Telegram 覆盖时,在发布分支、发布标签或完整 commit SHA 上运行 `Full Release Validation` -4. 如果你有意只需要确定性的常规测试图,请改为在发布 ref 上运行手动 `CI` workflow + - 在标签存在之前,你可以使用当前完整的工作流分支提交 SHA,对预检工作流进行仅验证的试运行 +2. 对于常规的 beta 优先流程,选择 `npm_dist_tag=beta`;仅在你有意直接发布稳定版时选择 `latest` +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 package -7. 如果发布落在 `beta`,请使用私有 `openclaw/releases-private/.github/workflows/openclaw-npm-dist-tags.yml` workflow,把该稳定版本从 `beta` 提升到 `latest` -8. 如果发布有意直接发布到 `latest`,且 `beta` 应立即跟随相同稳定构建,请使用同一个私有 workflow,把两个 dist-tag 都指向稳定版本,或让它的定时自修复同步稍后移动 `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` -dist-tag 变更位于私有 repo 中是出于安全原因,因为它仍需要 `NPM_TOKEN`,而公共 repo 保持仅使用 OIDC 发布。 +dist-tag 变更位于私有仓库中是出于安全考虑,因为它仍然需要 `NPM_TOKEN`,而公共仓库保留仅 OIDC 的发布。 -这会让直接发布路径和 beta 优先提升路径都已记录,并且对操作者可见。 +这让直接发布路径和 beta 优先提升路径都保持有文档记录,并对操作员可见。 -如果维护者必须回退到本地 npm 凭证,请只在专用 tmux 会话内运行任何 1Password CLI(`op`)命令。不要直接从主智能体 shell 调用 `op`;把它放在 tmux 内可以让提示、警报和 OTP 处理可观察,并防止重复的主机警报。 +如果维护者必须回退到本地 npm 认证,请仅在专用 tmux 会话内运行任何 1Password +CLI(`op`)命令。不要直接从主智能体 shell 调用 `op`;将其放在 tmux 内可以让提示、告警和 OTP 处理可观察,并防止重复的主机告警。 -## 公共参考 +## 公开参考 - [`.github/workflows/full-release-validation.yml`](https://github.com/openclaw/openclaw/blob/main/.github/workflows/full-release-validation.yml) - [`.github/workflows/package-acceptance.yml`](https://github.com/openclaw/openclaw/blob/main/.github/workflows/package-acceptance.yml) @@ -400,7 +426,7 @@ dist-tag 变更位于私有 repo 中是出于安全原因,因为它仍需要 ` 维护者使用 [`openclaw/maintainers/release/README.md`](https://github.com/openclaw/maintainers/blob/main/release/README.md) -中的私有发布文档作为实际 runbook。 +中的私有发布文档作为实际运行手册。 ## 相关 diff --git a/docs/zh-CN/reference/full-release-validation.md b/docs/zh-CN/reference/full-release-validation.md index f0c888aaa..bac6e3726 100644 --- a/docs/zh-CN/reference/full-release-validation.md +++ b/docs/zh-CN/reference/full-release-validation.md @@ -3,20 +3,20 @@ read_when: - 运行或重新运行完整发布验证 - 比较稳定版和完整发布验证配置文件 - 调试发布验证阶段失败 -summary: 完整发布验证的阶段、子工作流、发布配置、重新运行句柄和证据 +summary: 完整发布验证阶段、子工作流、发布配置档、重跑句柄和证据 title: 完整发布验证 x-i18n: - generated_at: "2026-05-03T12:05:48Z" + generated_at: "2026-05-04T22:29:45Z" model: gpt-5.5 provider: openai - source_hash: 038901ad751c00b35f69d7ec5caf74e577dcf2350d7658037c3ecc9ff5fab6d7 + source_hash: d67b7f9d413aa0f367b71f03d5325ff73591ee1ee6c77623712ebd15d295ca8b source_path: reference/full-release-validation.md workflow: 16 --- -`Full Release Validation` 是发布总控流程。它是发布前验证的唯一手动入口点,但大多数工作都在子工作流中进行,因此失败的运行环境可以重新运行,而无需重新启动整个发布流程。 +`Full Release Validation` 是发布总控流程。它是预发布验证的单一手动入口点,但大部分工作发生在子工作流中,因此失败的执行单元可以重新运行,而不必重启整个发布流程。 -从受信任的工作流 ref 运行它,通常是 `main`,并将发布分支、标签或完整提交 SHA 作为 `ref` 传入: +从受信任的工作流引用运行它,通常是 `main`,并将发布分支、标签或完整提交 SHA 作为 `ref` 传入: ```bash gh workflow run full-release-validation.yml \ @@ -27,116 +27,124 @@ gh workflow run full-release-validation.yml \ -f release_profile=stable ``` -子工作流使用受信任的工作流 ref 作为 harness,并使用输入的 `ref` 作为待测候选版本。这样在验证较旧的发布分支或标签时,也能使用新的验证逻辑。 +子工作流使用受信任的工作流引用作为 harness,并使用输入 `ref` 作为待测候选版本。这样在验证较旧的发布分支或标签时,也能使用新的验证逻辑。 -包验收通常会从解析后的 `ref` 构建候选 tarball,包括使用 `pnpm ci:full-release` 分发的完整 SHA 运行。发布后,传入 `package_acceptance_package_spec=openclaw@YYYY.M.D`(或 `openclaw@beta`/`openclaw@latest`),即可改为针对已发布的 npm 包运行相同的包/更新矩阵。 +默认情况下,`release_profile=stable` 会运行阻塞发布的通道,并跳过完整的实时/Docker 长时间浸泡测试。传入 `run_release_soak=true` 可在稳定版运行中包含浸泡测试通道。`release_profile=full` 始终启用浸泡测试通道,因此广泛的 advisory 配置不会悄悄降低覆盖范围。 + +Package Acceptance 通常会从解析后的 `ref` 构建候选 tarball,包括通过 `pnpm ci:full-release` 调度的完整 SHA 运行。发布后,传入 `package_acceptance_package_spec=openclaw@YYYY.M.D`(或 `openclaw@beta`/`openclaw@latest`),即可改为针对已发布的 npm 包运行同一套包/更新矩阵。 ## 顶层阶段 -| 阶段 | 详情 | +| 阶段 | 详情 | | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| 目标解析 | **作业:** `Resolve target ref`
**子工作流:** 无
**证明:** 解析发布分支、标签或完整提交 SHA,并记录选定输入。
**重新运行:** 如果此处失败,请重新运行总控流程。 | -| Vitest 和常规 CI | **作业:** `Run normal full CI`
**子工作流:** `CI`
**证明:** 针对目标 ref 运行手动完整 CI 图,包括 Linux Node lanes、内置插件分片、渠道契约、Node 22 兼容性、`check`、`check-additional`、构建 smoke、文档检查、Python skills、Windows、macOS、Control UI i18n,以及通过总控流程运行的 Android。
**重新运行:** `rerun_group=ci`。 | -| 插件预发布 | **作业:** `Run plugin prerelease validation`
**子工作流:** `Plugin Prerelease`
**证明:** 仅发布时运行的插件静态检查、agentic 插件覆盖、完整扩展批量分片,以及插件预发布 Docker lanes。
**重新运行:** `rerun_group=plugin-prerelease`。 | -| 发布检查 | **作业:** `Run release/live/Docker/QA validation`
**子工作流:** `OpenClaw Release Checks`
**证明:** 安装 smoke、跨操作系统包检查、live/E2E 套件、Docker 发布路径分块、包验收、QA Lab parity、live Matrix 和 live Telegram。
**重新运行:** `rerun_group=release-checks` 或更窄的 release-checks 句柄。 | -| 包产物 | **作业:** `Prepare release package artifact`
**子工作流:** 无
**证明:** 足够早地创建父级 `release-package-under-test` tarball,以供不需要等待 `OpenClaw Release Checks` 的面向包的检查使用。
**重新运行:** 重新运行总控流程,或为 `rerun_group=npm-telegram` 提供 `npm_telegram_package_spec`。 | -| Package Telegram | **作业:** `Run package Telegram E2E`
**子工作流:** `NPM Telegram Beta E2E`
**证明:** 在 `rerun_group=all` 且 `release_profile=full` 时,提供由父级产物支持的 Telegram 包验证;或在设置 `npm_telegram_package_spec` 时,提供已发布包的 Telegram 验证。
**重新运行:** 使用 `npm_telegram_package_spec` 运行 `rerun_group=npm-telegram`。 | -| 总控验证器 | **作业:** `Verify full validation`
**子工作流:** 无
**证明:** 重新检查已记录的子运行结论,并追加来自子工作流的最慢作业表。
**重新运行:** 在重新运行失败的子流程并转绿后,只重新运行此作业。 | +| 目标解析 | **作业:** `Resolve target ref`
**子工作流:** 无
**证明:** 解析发布分支、标签或完整提交 SHA,并记录选定的输入。
**重新运行:** 如果此项失败,重新运行总控流程。 | +| Vitest 和常规 CI | **作业:** `Run normal full CI`
**子工作流:** `CI`
**证明:** 针对目标 ref 的手动完整 CI 图,包括 Linux Node 通道、内置插件分片、渠道契约、Node 22 兼容性、`check`、`check-additional`、构建冒烟测试、文档检查、Python Skills、Windows、macOS、Control UI 国际化,以及通过总控流程运行的 Android。
**重新运行:** `rerun_group=ci`。 | +| 插件预发布 | **作业:** `Run plugin prerelease validation`
**子工作流:** `Plugin Prerelease`
**证明:** 仅发布用插件静态检查、agentic 插件覆盖、完整扩展批次分片,以及插件预发布 Docker 通道。
**重新运行:** `rerun_group=plugin-prerelease`。 | +| 发布检查 | **作业:** `Run release/live/Docker/QA validation`
**子工作流:** `OpenClaw Release Checks`
**证明:** 安装冒烟测试、跨 OS 包检查、Package Acceptance、QA Lab parity、实时 Matrix 和实时 Telegram。使用 `run_release_soak=true` 或 `release_profile=full` 时,还会运行完整的实时/E2E 套件和 Docker 发布路径分块。
**重新运行:** `rerun_group=release-checks` 或更窄的 release-checks 句柄。 | +| 包产物 | **作业:** `Prepare release package artifact`
**子工作流:** 无
**证明:** 提前创建父级 `release-package-under-test` tarball,供不需要等待 `OpenClaw Release Checks` 的面向包检查使用。
**重新运行:** 重新运行总控流程,或为 `rerun_group=npm-telegram` 提供 `npm_telegram_package_spec`。 | +| 包 Telegram | **作业:** `Run package Telegram E2E`
**子工作流:** `NPM Telegram Beta E2E`
**证明:** 在 `rerun_group=all` 且 `release_profile=full` 时,提供基于父级产物的 Telegram 包验证;或在设置 `npm_telegram_package_spec` 时,提供已发布包的 Telegram 验证。
**重新运行:** 使用 `npm_telegram_package_spec` 运行 `rerun_group=npm-telegram`。 | +| 总控验证器 | **作业:** `Verify full validation`
**子工作流:** 无
**证明:** 重新检查已记录的子运行结论,并附加来自子工作流的最慢作业表。
**重新运行:** 重新运行失败的子工作流使其变绿后,只重新运行此作业。 | -对于 `ref=main` 和 `rerun_group=all`,较新的总控流程会取代较旧的总控流程。当父流程被取消时,它的监视器会取消任何已经分发的子工作流。发布分支和标签验证运行默认不会互相取消。 +对于 `ref=main` 和 `rerun_group=all`,较新的总控流程会取代较旧的总控流程。当父级被取消时,它的监控器会取消任何已调度的子工作流。发布分支和标签验证运行默认不会互相取消。 ## 发布检查阶段 -`OpenClaw Release Checks` 是最大的子工作流。它只解析一次目标,并在面向包或 Docker 的阶段需要时准备共享的 `release-package-under-test` 产物。 +`OpenClaw Release Checks` 是最大的子工作流。它会解析一次目标,并在面向包或 Docker 的阶段需要时,准备共享的 `release-package-under-test` 产物。 -| 阶段 | 详情 | -| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| 发布目标 | **作业:** `Resolve target ref`
**支撑工作流:** 无
**测试:** 选定的 ref、可选的预期 SHA、profile、重新运行组,以及聚焦的 live 套件过滤器。
**重新运行:** `rerun_group=release-checks`。 | -| 包产物 | **作业:** `Prepare release package artifact`
**支撑工作流:** 无
**测试:** 打包或解析一个候选 tarball,并上传 `release-package-under-test` 供下游面向包的检查使用。
**重新运行:** 受影响的包、跨操作系统或 live/E2E 组。 | -| 安装 smoke | **作业:** `Run install smoke`
**支撑工作流:** `Install Smoke`
**测试:** 完整安装路径,包括根 Dockerfile smoke 镜像复用、QR 包安装、根和 Gateway 网关 Docker smokes、安装器 Docker 测试、Bun 全局安装 image-provider smoke,以及快速的内置插件安装/卸载 E2E。
**重新运行:** `rerun_group=install-smoke`。 | -| 跨操作系统 | **作业:** `cross_os_release_checks`
**支撑工作流:** `OpenClaw Cross-OS Release Checks (Reusable)`
**测试:** 使用候选 tarball 加基线包,针对选定的提供商和模式,在 Linux、Windows 和 macOS 上运行全新安装与升级 lanes。
**重新运行:** `rerun_group=cross-os`。 | -| 仓库和 live E2E | **作业:** `Run repo/live E2E validation`
**支撑工作流:** `OpenClaw Live And E2E Checks (Reusable)`
**测试:** 仓库 E2E、live cache、OpenAI websocket streaming、原生 live 提供商和插件分片,以及由 `release_profile` 选择的 Docker 支持 live model/backend/gateway harnesses。
**重新运行:** `rerun_group=live-e2e`,可选搭配 `live_suite_filter`。 | -| Docker 发布路径 | **作业:** `Run Docker release-path validation`
**支撑工作流:** `OpenClaw Live And E2E Checks (Reusable)`
**测试:** 针对共享包产物运行 release-path Docker 分块。
**重新运行:** `rerun_group=live-e2e`。 | -| 包验收 | **作业:** `Run package acceptance`
**支撑工作流:** `Package Acceptance`
**测试:** 离线插件包 fixture、插件更新、mock-OpenAI Telegram 包验收,以及从 `2026.4.23` 或之后每个稳定 npm 发布版本到同一 tarball 的已发布升级 survivor 检查。
**重新运行:** `rerun_group=package`。 | -| QA parity | **作业:** `Run QA Lab parity lane` 和 `Run QA Lab parity report`
**支撑工作流:** 直接作业
**测试:** 候选版本和基线 agentic parity packs,然后运行 parity 报告。
**重新运行:** `rerun_group=qa-parity` 或 `rerun_group=qa`。 | -| QA live Matrix | **作业:** `Run QA Lab live Matrix lane`
**支撑工作流:** 直接作业
**测试:** 在 `qa-live-shared` 环境中运行快速 live Matrix QA profile。
**重新运行:** `rerun_group=qa-live` 或 `rerun_group=qa`。 | -| QA live Telegram | **作业:** `Run QA Lab live Telegram lane`
**支撑工作流:** 直接作业
**测试:** 使用 Convex CI 凭证租约运行 live Telegram QA。
**重新运行:** `rerun_group=qa-live` 或 `rerun_group=qa`。 | -| 发布验证器 | **作业:** `Verify release checks`
**支撑工作流:** 无
**测试:** 选定重新运行组所需的 release-check 作业。
**重新运行:** 在聚焦的子作业通过后重新运行。 | +| 阶段 | 详细信息 | +| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 发布目标 | **作业:** `Resolve target ref`
**支撑 workflow:** 无
**测试:** 选定的 ref、可选的预期 SHA、配置档、重跑组以及聚焦的 live 套件过滤器。
**重跑:** `rerun_group=release-checks`。 | +| 包构件 | **作业:** `Prepare release package artifact`
**支撑 workflow:** 无
**测试:** 打包或解析一个候选 tarball,并上传 `release-package-under-test`,供下游面向包的检查使用。
**重跑:** 受影响的包、跨 OS 或 live/E2E 组。 | +| 安装冒烟测试 | **作业:** `Run install smoke`
**支撑 workflow:** `Install Smoke`
**测试:** 完整安装路径,包括复用根 Dockerfile 冒烟镜像、QR 包安装、根和 Gateway 网关 Docker 冒烟测试、安装器 Docker 测试、Bun 全局安装 image-provider 冒烟测试,以及快速内置插件安装/卸载 E2E。
**重跑:** `rerun_group=install-smoke`。 | +| 跨 OS | **作业:** `cross_os_release_checks`
**支撑 workflow:** `OpenClaw Cross-OS Release Checks (Reusable)`
**测试:** 在 Linux、Windows 和 macOS 上,针对选定的提供商和模式运行全新安装与升级通道,使用候选 tarball 加基线包。
**重跑:** `rerun_group=cross-os`。 | +| 仓库和 live E2E | **作业:** `Run repo/live E2E validation`
**支撑 workflow:** `OpenClaw Live And E2E Checks (Reusable)`
**测试:** 仓库 E2E、live 缓存、OpenAI websocket 流式传输、原生 live 提供商和插件分片,以及由 `release_profile` 选择的 Docker 支撑 live 模型/backend/Gateway 网关 harness。
**运行:** `run_release_soak=true`、`release_profile=full`,或聚焦的 `rerun_group=live-e2e`。
**重跑:** `rerun_group=live-e2e`,可选带 `live_suite_filter`。 | +| Docker 发布路径 | **作业:** `Run Docker release-path validation`
**支撑 workflow:** `OpenClaw Live And E2E Checks (Reusable)`
**测试:** 针对共享包构件运行发布路径 Docker 分块。
**运行:** `run_release_soak=true`、`release_profile=full`,或聚焦的 `rerun_group=live-e2e`。
**重跑:** `rerun_group=live-e2e`。 | +| 包验收 | **作业:** `Run package acceptance`
**支撑 workflow:** `Package Acceptance`
**测试:** 离线插件包夹具、插件更新、mock-OpenAI Telegram 包验收,以及针对同一 tarball 的已发布升级存活检查。阻塞发布检查使用默认的最新已发布基线;soak 检查会扩展到 `2026.4.23` 及之后的每个稳定 npm 发布版本,以及已报告问题的夹具。
**重跑:** `rerun_group=package`。 | +| QA parity | **作业:** `Run QA Lab parity lane` 和 `Run QA Lab parity report`
**支撑 workflow:** 直接作业
**测试:** 候选和基线 agentic parity 包,然后生成 parity 报告。
**重跑:** `rerun_group=qa-parity` 或 `rerun_group=qa`。 | +| QA live Matrix | **作业:** `Run QA Lab live Matrix lane`
**支撑 workflow:** 直接作业
**测试:** `qa-live-shared` 环境中的快速 live Matrix QA 配置档。
**重跑:** `rerun_group=qa-live` 或 `rerun_group=qa`。 | +| QA live Telegram | **作业:** `Run QA Lab live Telegram lane`
**支撑 workflow:** 直接作业
**测试:** 使用 Convex CI 凭证租约的 live Telegram QA。
**重跑:** `rerun_group=qa-live` 或 `rerun_group=qa`。 | +| 发布验证器 | **作业:** `Verify release checks`
**支撑 workflow:** 无
**测试:** 所选重跑组所需的发布检查作业。
**重跑:** 在聚焦的子作业通过后重跑。 | ## Docker 发布路径分块 当 `live_suite_filter` 为空时,Docker 发布路径阶段会运行这些分块: -| 分块 | 覆盖范围 | -| --------------------------------------------------------------- | ------------------------------------------------------------------------ | -| `core` | Core Docker 发布路径 smoke lanes。 | -| `package-update-openai` | OpenAI 包安装和更新行为。 | -| `package-update-anthropic` | Anthropic 包安装和更新行为。 | -| `package-update-core` | 提供商无关的包和更新行为。 | -| `plugins-runtime-plugins` | 覆盖插件行为的插件运行时 lanes。 | -| `plugins-runtime-services` | 由服务支持的插件运行时 lanes;按需包含 OpenWebUI。 | -| `plugins-runtime-install-a` through `plugins-runtime-install-h` | 为并行发布验证而拆分的插件安装/运行时批次。 | +| 分块 | 覆盖范围 | +| --------------------------------------------------------------- | ----------------------------------------------------------------------- | +| `core` | 核心 Docker 发布路径冒烟通道。 | +| `package-update-openai` | OpenAI 包安装和更新行为。 | +| `package-update-anthropic` | Anthropic 包安装和更新行为。 | +| `package-update-core` | 提供商中立的包和更新行为。 | +| `plugins-runtime-plugins` | 执行插件行为的插件运行时通道。 | +| `plugins-runtime-services` | 服务支撑的插件运行时通道;按需包含 OpenWebUI。 | +| `plugins-runtime-install-a` through `plugins-runtime-install-h` | 为并行发布验证拆分的插件安装/运行时批次。 | -使用可复用 live/E2E 工作流上的目标 `docker_lanes=`,当且仅当一个 Docker lane 失败时。发布产物会在可用时包含每个 lane 的重跑命令,并带有包产物和镜像复用输入。 +当只有一个 Docker 通道失败时,在可复用 live/E2E workflow 上使用定向的 `docker_lanes=`。发布构件会在可用时包含按通道的重跑命令,并带有包构件和镜像复用输入。 ## 发布配置档 -`release_profile` 主要控制发布检查中的 live/提供商覆盖范围。它不会移除常规完整 CI、插件预发布、安装冒烟测试、包验收、QA Lab 或 Docker 发布路径分块。`full` 还会在 `rerun_group=all` 时,让总控运行针对父级发布包产物的包 Telegram E2E,因此完整的预发布候选不会静默跳过该 Telegram 包 lane。 +`release_profile` 主要控制发布检查内的 live/提供商覆盖范围。它不会移除常规完整 CI、插件预发布、安装冒烟测试、包验收或 QA Lab。对于 `stable`,详尽的仓库/live E2E 和 Docker 发布路径分块属于 soak 覆盖范围,并在 `run_release_soak=true` 时运行。`full` 会强制启用 soak 覆盖范围,并且在 `rerun_group=all` 时还会让总控运行使用父发布包构件的包 Telegram E2E,因此完整的预发布候选不会静默跳过该 Telegram 包通道。 -| 配置档 | 预期用途 | 包含的 live/提供商覆盖范围 | +| 配置档 | 预期用途 | 包含的 live/提供商覆盖范围 | | --------- | --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `minimum` | 最快的发布关键冒烟测试。 | OpenAI/core live 路径、OpenAI 的 Docker live 模型、原生 gateway core、原生 OpenAI gateway 配置档、原生 OpenAI 插件,以及 Docker live gateway OpenAI。 | -| `stable` | 默认发布批准配置档。 | `minimum` 加上 Anthropic 冒烟测试、Google、MiniMax、后端、原生 live test harness、Docker live CLI 后端、Docker ACP bind、Docker Codex harness,以及一个 OpenCode Go 冒烟分片。 | -| `full` | 广泛的 advisory 扫描。 | `stable` 加上 advisory 提供商、插件 live 分片和媒体 live 分片。 | +| `minimum` | 最快的发布关键冒烟测试。 | OpenAI/core live 路径、OpenAI 的 Docker live 模型、原生 Gateway 网关 core、原生 OpenAI Gateway 网关配置档、原生 OpenAI 插件,以及 Docker live Gateway 网关 OpenAI。 | +| `stable` | 默认发布批准配置档。 | `minimum` 加上 Anthropic 冒烟测试、Google、MiniMax、backend、原生 live 测试 harness、Docker live CLI backend、Docker ACP bind、Docker Codex harness,以及一个 OpenCode Go 冒烟分片。 | +| `full` | 广泛 advisory 扫描。 | `stable` 加上 advisory 提供商、插件 live 分片和媒体 live 分片。 | -## 仅 full 包含的新增项 +## 仅 full 添加项 这些套件会被 `stable` 跳过,并由 `full` 包含: -| 区域 | 仅 full 覆盖范围 | +| 领域 | 仅 full 覆盖范围 | | -------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | -| Docker live 模型 | OpenCode Go、OpenRouter、xAI、Z.ai 和 Fireworks。 | -| Docker live gateway | advisory 提供商拆分为 DeepSeek/Fireworks、OpenCode Go/OpenRouter 和 xAI/Z.ai 分片。 | -| 原生 gateway 提供商配置档 | 完整 Anthropic Opus 和 Sonnet/Haiku 分片、Fireworks、DeepSeek、完整 OpenCode Go 模型分片、OpenRouter、xAI 和 Z.ai。 | -| 原生插件 live 分片 | 插件 A-K、L-N、O-Z other、Moonshot 和 xAI。 | -| 原生媒体 live 分片 | Audio、Google music、MiniMax music 和 video groups A-D。 | +| Docker live 模型 | OpenCode Go、OpenRouter、xAI、Z.ai 和 Fireworks。 | +| Docker live Gateway 网关 | advisory 提供商拆分为 DeepSeek/Fireworks、OpenCode Go/OpenRouter 和 xAI/Z.ai 分片。 | +| 原生 Gateway 网关提供商配置档 | 完整 Anthropic Opus 和 Sonnet/Haiku 分片、Fireworks、DeepSeek、完整 OpenCode Go 模型分片、OpenRouter、xAI 和 Z.ai。 | +| 原生插件 live 分片 | 插件 A-K、L-N、O-Z 其他、Moonshot 和 xAI。 | +| 原生媒体 live 分片 | 音频、Google 音乐、MiniMax 音乐,以及视频组 A-D。 | -`stable` 包含 `native-live-src-gateway-profiles-anthropic-smoke` 和 `native-live-src-gateway-profiles-opencode-go-smoke`;`full` 改用更广的 Anthropic 和 OpenCode Go 模型分片。聚焦重跑仍可使用聚合的 `native-live-src-gateway-profiles-anthropic` 或 `native-live-src-gateway-profiles-opencode-go` 句柄。 +`stable` 包含 `native-live-src-gateway-profiles-anthropic-smoke` 和 `native-live-src-gateway-profiles-opencode-go-smoke`;`full` 则使用更广的 Anthropic 和 OpenCode Go 模型分片。聚焦重跑仍可使用聚合的 `native-live-src-gateway-profiles-anthropic` 或 `native-live-src-gateway-profiles-opencode-go` 句柄。 ## 聚焦重跑 -使用 `rerun_group` 以避免重复运行无关的发布盒: +使用 `rerun_group` 来避免重复运行无关的发布 box: -| 句柄 | 范围 | +| Handle | 范围 | | ------------------- | --------------------------------------------------------------------- | | `all` | 所有完整发布验证阶段。 | | `ci` | 仅手动完整 CI 子项。 | | `plugin-prerelease` | 仅插件预发布子项。 | | `release-checks` | 所有 OpenClaw 发布检查阶段。 | -| `install-smoke` | 通过发布检查进行安装冒烟测试。 | -| `cross-os` | 跨操作系统发布检查。 | +| `install-smoke` | 从安装冒烟测试到发布检查。 | +| `cross-os` | 跨 OS 发布检查。 | | `live-e2e` | 仓库/live E2E 和 Docker 发布路径验证。 | | `package` | 包验收。 | -| `qa` | QA parity 加 QA live lane。 | -| `qa-parity` | 仅 QA parity lane 和报告。 | -| `qa-live` | 仅 QA live Matrix 和 Telegram。 | +| `qa` | QA 一致性加 QA 实时通道。 | +| `qa-parity` | 仅 QA 一致性通道和报告。 | +| `qa-live` | 仅 QA 实时 Matrix 和 Telegram。 | | `npm-telegram` | 已发布包 Telegram E2E;需要 `npm_telegram_package_spec`。 | -当一个 live 套件失败时,将 `live_suite_filter` 与 `rerun_group=live-e2e` 搭配使用。有效的筛选器 ID 在可复用 live/E2E 工作流中定义,包括 `docker-live-models`、`live-gateway-docker`、`live-gateway-anthropic-docker`、`live-gateway-google-docker`、`live-gateway-minimax-docker`、`live-gateway-advisory-docker`、`live-cli-backend-docker`、`live-acp-bind-docker` 和 `live-codex-harness-docker`。 +当一个实时套件失败时,将 `live_suite_filter` 与 `rerun_group=live-e2e` 一起使用。 +有效的筛选器 ID 在可复用的实时/E2E 工作流中定义,包括 +`docker-live-models`、`live-gateway-docker`、 +`live-gateway-anthropic-docker`、`live-gateway-google-docker`、 +`live-gateway-minimax-docker`、`live-gateway-advisory-docker`、 +`live-cli-backend-docker`、`live-acp-bind-docker` 和 +`live-codex-harness-docker`。 -`live-gateway-advisory-docker` 句柄是其三个提供商分片的聚合重跑句柄,因此它仍会展开到所有 advisory Docker gateway 作业。 +`live-gateway-advisory-docker` 句柄是其三个提供商分片的聚合重跑句柄,因此它仍会展开到所有 advisory Docker Gateway 网关作业。 ## 要保留的证据 -将 `Full Release Validation` 摘要保留为发布级索引。它链接子运行 ID,并包含最慢作业表。对于失败,先检查子工作流,然后重跑上方最小匹配句柄。 +将 `Full Release Validation` 摘要保留为发布级索引。它会链接子运行 ID,并包含最慢作业表。对于失败,先检查子工作流,然后重跑上面匹配的最小句柄。 -有用的产物: +有用的构件: -- 来自完整发布验证父项和 `OpenClaw Release Checks` 的 `release-package-under-test` -- `.artifacts/docker-tests/` 下的 Docker 发布路径产物 -- 包验收 `package-under-test` 和 Docker 验收产物 -- 每个操作系统和套件的跨操作系统发布检查产物 -- QA parity、Matrix 和 Telegram 产物 +- Full Release Validation 父级和 `OpenClaw Release Checks` 中的 `release-package-under-test` +- `.artifacts/docker-tests/` 下的 Docker 发布路径构件 +- Package Acceptance 的 `package-under-test` 和 Docker 验收构件 +- 每个 OS 和套件的跨 OS 发布检查构件 +- QA 一致性、Matrix 和 Telegram 构件 ## 工作流文件