chore(i18n): refresh zh-CN translations
This commit is contained in:
parent
836b750b6d
commit
ef8d1bcea4
126
docs/zh-CN/ci.md
126
docs/zh-CN/ci.md
@ -1,27 +1,27 @@
|
||||
---
|
||||
read_when:
|
||||
- 你需要了解某个 CI 作业为什么运行或没有运行。
|
||||
- 你正在调试失败的 GitHub Actions 检查。
|
||||
summary: CI 作业图、范围门控,以及本地命令对应项
|
||||
- 你需要了解某个 CI 作业为什么运行或没有运行
|
||||
- 你正在调试失败的 GitHub Actions 检查
|
||||
summary: CI 作业图、范围门禁,以及对应的本地命令
|
||||
title: CI 流水线
|
||||
x-i18n:
|
||||
generated_at: "2026-04-24T05:02:59Z"
|
||||
generated_at: "2026-04-24T07:42:05Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 8e24efec145ff144b007e248ef0f9c56287619eb9af204d45d49984909a6136b
|
||||
source_hash: 489ac05725a316b25f56f7f754d6a8652abbd60481fbe6e692572b81581fe405
|
||||
source_path: ci.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
CI 会在每次推送到 `main` 以及每个拉取请求时运行。它使用智能范围控制,在仅更改了无关区域时跳过昂贵的作业。
|
||||
CI 会在每次推送到 `main` 以及每个拉取请求时运行。它使用智能范围界定,在只改动无关区域时跳过高开销作业。
|
||||
|
||||
QA Lab 在主智能范围工作流之外有专用的 CI 通道。`Parity gate` 工作流会在匹配的 PR 变更和手动触发时运行;它会构建私有 QA 运行时,并比较模拟的 GPT-5.4 和 Opus 4.6 智能体包。`QA-Lab - All Lanes` 工作流会在 `main` 上每晚运行,并且也可手动触发;它会将模拟 parity gate、实时 Matrix 通道和实时 Telegram 通道作为并行作业扇出执行。实时作业使用 `qa-live-shared` 环境,而 Telegram 通道使用 Convex 租约。`OpenClaw Release Checks` 也会在发布审批前运行同样的 QA Lab 通道。
|
||||
QA Lab 在主智能范围工作流之外有专门的 CI 通道。`Parity gate` 工作流会在匹配的 PR 变更和手动触发时运行;它会构建私有 QA 运行时,并比较模拟的 GPT-5.4 和 Opus 4.6 智能体包。`QA-Lab - All Lanes` 工作流会在 `main` 上每晚运行,也可手动触发;它会将模拟 parity gate、实时 Matrix 通道和实时 Telegram 通道并行扇出为多个作业。实时作业使用 `qa-live-shared` environment,Telegram 通道使用 Convex leases。`OpenClaw Release Checks` 也会在发布批准前运行相同的 QA Lab 通道。
|
||||
|
||||
`Duplicate PRs After Merge` 工作流是一个供维护者在合并后清理重复项的手动工作流。它默认以 dry-run 模式运行,只有在 `apply=true` 时才会关闭明确列出的 PR。在修改 GitHub 之前,它会验证已落地的 PR 是否已合并,并检查每个重复 PR 是否具有共享的引用 issue,或存在重叠的变更 hunk。
|
||||
`Duplicate PRs After Merge` 工作流是一个供维护者使用的手动工作流,用于合并后的重复 PR 清理。它默认以 dry-run 方式运行,只有在 `apply=true` 时才会关闭明确列出的 PR。在修改 GitHub 之前,它会验证已落地的 PR 确实已合并,并确认每个重复 PR 要么引用了相同的问题,要么存在重叠的变更 hunk。
|
||||
|
||||
`Docs Agent` 工作流是一个事件驱动的 Codex 维护通道,用于让现有文档与最近已落地的更改保持一致。它没有纯定时调度:`main` 上一次成功的、非机器人触发的推送 CI 运行可以触发它,手动触发也可以直接运行它。工作流运行触发的调用会在 `main` 已继续前进,或者过去一小时内已经创建了另一个未被跳过的 Docs Agent 运行时跳过。当它运行时,会审查从上一个未被跳过的 Docs Agent 源 SHA 到当前 `main` 的提交范围,因此每小时运行一次即可覆盖自上次文档处理以来累计到 `main` 的所有更改。
|
||||
`Docs Agent` 工作流是一个事件驱动的 Codex 维护通道,用于让现有文档与最近落地的更改保持一致。它没有纯定时调度:当 `main` 上一次成功的非机器人推送 CI 运行完成后,可以触发它;也可以通过手动触发直接运行。由 workflow-run 触发的调用会在 `main` 已继续前进,或过去一小时内已创建过另一个未跳过的 Docs Agent 运行时跳过。当它运行时,会审查从上一次未跳过的 Docs Agent 源 SHA 到当前 `main` 的提交范围,因此每小时一次的运行可以覆盖自上次文档处理以来积累的所有 `main` 变更。
|
||||
|
||||
`Test Performance Agent` 工作流是一个事件驱动的 Codex 维护通道,用于处理慢测试。它没有纯定时调度:`main` 上一次成功的、非机器人触发的推送 CI 运行可以触发它,但如果当天 UTC 已经有另一个由工作流运行触发的调用已经运行或正在运行,它就会跳过。手动触发会绕过这个按天限制的活动门控。该通道会构建完整测试套件的分组 Vitest 性能报告,让 Codex 只做小范围且不降低覆盖率的测试性能修复,而不是进行大规模重构,然后重新运行完整测试套件报告,并拒绝任何导致通过基线测试数量下降的更改。如果基线中已有失败测试,Codex 只能修复明显的失败项,并且代理运行后的完整测试套件报告必须通过,之后才会提交任何内容。当 `main` 在机器人推送落地前继续前进时,该通道会对已验证补丁执行 rebase,重新运行 `pnpm check:changed`,并重试推送;存在冲突的过时补丁会被跳过。它使用 GitHub 托管的 Ubuntu,这样 Codex action 就可以与 docs agent 保持相同的 drop-sudo 安全姿态。
|
||||
`Test Performance Agent` 工作流是一个事件驱动的 Codex 维护通道,用于处理慢速测试。它没有纯定时调度:当 `main` 上一次成功的非机器人推送 CI 运行完成后,可以触发它,但如果该 UTC 日期内已有另一个 workflow-run 调用已经运行或仍在运行,它就会跳过。手动触发会绕过这个按天计的活动门禁。该通道会构建一个完整测试套件的分组 Vitest 性能报告,让 Codex 只进行小范围、保持覆盖率的测试性能修复,而不是大规模重构;然后重新运行完整测试套件报告,并拒绝任何会降低通过基线测试数量的更改。如果基线中已有失败测试,Codex 只能修复明显失败的问题,并且 agent 处理后的完整测试套件报告必须通过,之后才会提交任何内容。当 `main` 在机器人推送落地前继续前进时,该通道会 rebase 已验证的补丁,重新运行 `pnpm check:changed`,并重试推送;存在冲突的过时补丁会被跳过。它使用 GitHub 托管的 Ubuntu,这样 Codex action 就可以与 docs agent 保持相同的 drop-sudo 安全策略。
|
||||
|
||||
```bash
|
||||
gh workflow run duplicate-after-merge.yml \
|
||||
@ -32,83 +32,83 @@ gh workflow run duplicate-after-merge.yml \
|
||||
|
||||
## 作业概览
|
||||
|
||||
| 作业 | 目的 | 运行时机 |
|
||||
| -------------------------------- | -------------------------------------------------------------------------------------------- | ------------------------------------ |
|
||||
| `preflight` | 检测是否仅更改了文档、已更改范围、已更改扩展,并构建 CI 清单 | 始终在非草稿推送和 PR 上运行 |
|
||||
| `security-scm-fast` | 通过 `zizmor` 进行私钥检测和工作流审计 | 始终在非草稿推送和 PR 上运行 |
|
||||
| `security-dependency-audit` | 针对 npm 漏洞公告执行无依赖的生产锁文件审计 | 始终在非草稿推送和 PR 上运行 |
|
||||
| `security-fast` | 快速安全作业所需的聚合作业 | 始终在非草稿推送和 PR 上运行 |
|
||||
| `build-artifacts` | 构建 `dist/`、Control UI、构建产物检查以及可复用的下游产物 | Node 相关更改 |
|
||||
| `checks-fast-core` | 快速 Linux 正确性通道,例如 bundled/plugin-contract/protocol 检查 | Node 相关更改 |
|
||||
| `checks-fast-contracts-channels` | 分片渠道契约检查,并提供稳定的聚合检查结果 | Node 相关更改 |
|
||||
| `checks-node-extensions` | 覆盖整个扩展套件的完整内置插件测试分片 | Node 相关更改 |
|
||||
| `checks-node-core-test` | 核心 Node 测试分片,不包括渠道、内置、契约和扩展通道 | Node 相关更改 |
|
||||
| `extension-fast` | 仅针对已更改内置插件的聚焦测试 | 包含扩展更改的拉取请求 |
|
||||
| `check` | 分片后的主要本地门控对应项:生产类型、lint、守卫、测试类型和严格 smoke | Node 相关更改 |
|
||||
| `check-additional` | 架构、边界、扩展表面守卫、包边界和 gateway-watch 分片 | Node 相关更改 |
|
||||
| `build-smoke` | 已构建 CLI 的 smoke 测试和启动内存 smoke | Node 相关更改 |
|
||||
| `checks` | 已构建产物渠道测试的验证器,以及仅推送时运行的 Node 22 兼容性检查 | Node 相关更改 |
|
||||
| `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` | 两种风味的 Android 单元测试,以及一个 debug APK 构建 | Android 相关更改 |
|
||||
| `test-performance-agent` | 在受信任活动之后每日运行的 Codex 慢测试优化 | `main` CI 成功后或手动触发 |
|
||||
| Job | 用途 | 运行时机 |
|
||||
| -------------------------------- | -------------------------------------------------------------------------------------------- | ---------------------------------- |
|
||||
| `preflight` | 检测是否仅改动 docs、变更范围、已变更 extensions,并构建 CI manifest | 所有非草稿 push 和 PR 都会运行 |
|
||||
| `security-scm-fast` | 通过 `zizmor` 进行私钥检测和工作流审计 | 所有非草稿 push 和 PR 都会运行 |
|
||||
| `security-dependency-audit` | 针对 npm advisories 的无依赖生产 lockfile 审计 | 所有非草稿 push 和 PR 都会运行 |
|
||||
| `security-fast` | 快速安全作业的必需聚合作业 | 所有非草稿 push 和 PR 都会运行 |
|
||||
| `build-artifacts` | 构建 `dist/`、Control UI、内置产物检查以及可复用的下游产物 | 与 Node 相关的变更 |
|
||||
| `checks-fast-core` | 快速 Linux 正确性通道,例如 bundled/plugin-contract/protocol 检查 | 与 Node 相关的变更 |
|
||||
| `checks-fast-contracts-channels` | 分片的渠道契约检查,并提供稳定的聚合检查结果 | 与 Node 相关的变更 |
|
||||
| `checks-node-extensions` | 对整个 extension 套件运行完整的内置插件测试分片 | 与 Node 相关的变更 |
|
||||
| `checks-node-core-test` | Core Node 测试分片,不包括渠道、内置、契约和 extension 通道 | 与 Node 相关的变更 |
|
||||
| `extension-fast` | 仅针对已变更内置插件的聚焦测试 | 带有 extension 变更的拉取请求 |
|
||||
| `check` | 分片后的主本地门禁等价项:生产类型、lint、guard、测试类型和严格 smoke | 与 Node 相关的变更 |
|
||||
| `check-additional` | 架构、边界、extension-surface guard、package-boundary 和 gateway-watch 分片 | 与 Node 相关的变更 |
|
||||
| `build-smoke` | 已构建 CLI 的 smoke 测试和启动内存 smoke | 与 Node 相关的变更 |
|
||||
| `checks` | 已构建产物渠道测试的验证器,以及仅 push 时运行的 Node 22 兼容性检查 | 与 Node 相关的变更 |
|
||||
| `check-docs` | docs 格式、lint 和损坏链接检查 | docs 有变更时 |
|
||||
| `skills-python` | 针对 Python 支持的 Skills 运行 Ruff + pytest | 与 Python Skills 相关的变更 |
|
||||
| `checks-windows` | Windows 专用测试通道 | 与 Windows 相关的变更 |
|
||||
| `macos-node` | 使用共享构建产物的 macOS TypeScript 测试通道 | 与 macOS 相关的变更 |
|
||||
| `macos-swift` | macOS 应用的 Swift lint、构建和测试 | 与 macOS 相关的变更 |
|
||||
| `android` | 两个 flavor 的 Android 单元测试,以及一个 debug APK 构建 | 与 Android 相关的变更 |
|
||||
| `test-performance-agent` | 在可信活动之后每日运行的 Codex 慢速测试优化 | 主 CI 成功后或手动触发 |
|
||||
|
||||
## 快速失败顺序
|
||||
|
||||
作业的排序方式是:让廉价检查先失败,再决定是否运行昂贵作业:
|
||||
作业的排序方式是让廉价检查先失败,避免昂贵作业继续运行:
|
||||
|
||||
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 通道并行,这样下游消费者就能在共享构建准备好后立即开始。
|
||||
4. 更重的平台和运行时通道随后扇出执行:`checks-fast-core`、`checks-fast-contracts-channels`、`checks-node-extensions`、`checks-node-core-test`、仅 PR 运行的 `extension-fast`、`checks`、`checks-windows`、`macos-node`、`macos-swift` 和 `android`。
|
||||
3. `build-artifacts` 与快速 Linux 通道并行运行,这样下游消费者可以在共享构建就绪后立即开始。
|
||||
4. 更重的平台和运行时通道随后扇出:`checks-fast-core`、`checks-fast-contracts-channels`、`checks-node-extensions`、`checks-node-core-test`、仅 PR 运行的 `extension-fast`、`checks`、`checks-windows`、`macos-node`、`macos-swift` 和 `android`。
|
||||
|
||||
范围逻辑位于 `scripts/ci-changed-scope.mjs`,并由 `src/scripts/ci-changed-scope.test.ts` 中的单元测试覆盖。
|
||||
CI 工作流编辑会验证 Node CI 图以及工作流 lint,但不会仅因为工作流本身的更改就强制运行 Windows、Android 或 macOS 原生构建;这些平台通道仍然只针对平台源码更改进行范围控制。
|
||||
Windows Node 检查的范围仅限于 Windows 特定的进程/路径包装器、npm/pnpm/UI 运行器辅助工具、包管理器配置,以及执行该通道的 CI 工作流表面;无关的源码、插件、安装 smoke 和纯测试更改仍然保留在 Linux Node 通道中,因此不会为了已经由常规测试分片覆盖的内容而占用一个 16 vCPU 的 Windows worker。
|
||||
单独的 `install-smoke` 工作流会通过它自己的 `preflight` 作业复用同一个范围脚本。它将 smoke 覆盖拆分为 `run_fast_install_smoke` 和 `run_full_install_smoke`。拉取请求会对 Docker/包表面、内置插件包/清单更改,以及 Docker smoke 作业会覆盖的核心插件/渠道/Gateway 网关/插件 SDK 表面运行快速路径。仅源码级的内置插件更改、纯测试编辑和纯文档编辑不会占用 Docker worker。快速路径会构建一次根 Dockerfile 镜像,检查 CLI,运行容器 gateway-network e2e,验证一个内置扩展构建参数,并在 120 秒命令超时限制下运行有界的内置插件 Docker 配置。完整路径会保留 QR 包安装以及安装器 Docker/更新覆盖,用于每晚定时运行、手动触发、workflow-call 发布检查,以及确实触及安装器/包/Docker 表面的拉取请求。对 `main` 的推送,包括合并提交,不会强制走完整路径;当 changed-scope 逻辑会在推送时请求完整覆盖时,该工作流仍只保留快速 Docker smoke,并将完整安装 smoke 留给夜间或发布验证。较慢的 Bun 全局安装 image-provider smoke 由 `run_bun_global_install_smoke` 单独门控;它会在每晚调度和发布检查工作流中运行,手动触发 `install-smoke` 时也可以选择启用,但拉取请求和 `main` 推送不会运行它。QR 和安装器 Docker 测试保留各自以安装为重点的 Dockerfile。本地 `test:docker:all` 会预构建一个共享的 live-test 镜像和一个共享的 `scripts/e2e/Dockerfile` built-app 镜像,然后以 `OPENCLAW_SKIP_DOCKER_BUILD=1` 并行运行 live/E2E smoke 通道;默认主池并发数为 8,可通过 `OPENCLAW_DOCKER_ALL_PARALLELISM` 调整,对提供商敏感的尾池并发数也为 8,可通过 `OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM` 调整。本地聚合默认会在首次失败后停止调度新的池化通道,并且每个通道都有 120 分钟超时,可通过 `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS` 覆盖。可复用的 live/E2E 工作流也采用共享镜像模式:先在 Docker 矩阵之前构建并推送一个带 SHA 标签的 GHCR Docker E2E 镜像,然后以 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行矩阵。定时的 live/E2E 工作流会每天运行完整的发布路径 Docker 套件。完整的内置更新/渠道矩阵仍然保留为手动/完整套件,因为它会重复执行真实的 npm 更新和 doctor 修复流程。
|
||||
CI 工作流编辑会校验 Node CI 图以及工作流 lint,但它们本身不会强制触发 Windows、Android 或 macOS 原生构建;这些平台通道仍然只针对平台源码变更进行范围界定。
|
||||
Windows Node 检查的范围限定于 Windows 专用的进程/路径包装器、npm/pnpm/UI 运行器辅助工具、包管理器配置,以及执行该通道的 CI 工作流表面;无关的源码、plugin、install-smoke 和仅测试变更仍然会留在 Linux Node 通道中,因此不会为了已经由常规测试分片覆盖的内容而占用 16 vCPU 的 Windows worker。
|
||||
独立的 `install-smoke` 工作流会通过它自己的 `preflight` 作业复用同一个范围脚本。它将 smoke 覆盖拆分为 `run_fast_install_smoke` 和 `run_full_install_smoke`。拉取请求会对 Docker/package 表面、内置 plugin package/manifest 变更,以及 Docker smoke 作业会覆盖到的 core plugin/channel/Gateway 网关/插件 SDK 表面运行快速路径。仅源码的内置插件变更、仅测试编辑以及仅 docs 编辑不会占用 Docker worker。快速路径会构建一次根 Dockerfile 镜像、检查 CLI、运行容器 gateway-network e2e、验证一个内置 extension build arg,并在 120 秒命令超时下运行受限的内置插件 Docker profile。完整路径保留 QR package install 以及 installer Docker/update 覆盖,用于每晚定时运行、手动触发、workflow-call 发布检查,以及真正触及 installer/package/Docker 表面的拉取请求。推送到 `main`(包括 merge commit)不会强制走完整路径;当 changed-scope 逻辑会在 push 上请求完整覆盖时,该工作流仍只保留快速 Docker smoke,而将完整安装 smoke 留给夜间或发布验证。较慢的 Bun 全局安装 image-provider smoke 由 `run_bun_global_install_smoke` 单独门控;它会在夜间调度和发布检查工作流中运行,手动触发 `install-smoke` 时也可以选择启用,但拉取请求和推送到 `main` 时不会运行。QR 和 installer Docker 测试保留它们自己的安装专用 Dockerfile。本地 `test:docker:all` 会先构建一个共享 live-test 镜像和一个共享的 `scripts/e2e/Dockerfile` built-app 镜像,然后在 `OPENCLAW_SKIP_DOCKER_BUILD=1` 下并行运行 live/E2E smoke 通道;默认主池并发数为 8,可通过 `OPENCLAW_DOCKER_ALL_PARALLELISM` 调整;provider 敏感的尾池并发数默认为 8,可通过 `OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM` 调整。默认情况下,各通道启动会错开 2 秒,以避免本地 Docker daemon 在创建时出现风暴;可用 `OPENCLAW_DOCKER_ALL_START_STAGGER_MS=0` 或其他毫秒值覆盖。本地聚合器默认会在第一次失败后停止调度新的池化通道,并且每个通道都有一个 120 分钟的超时,可通过 `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS` 覆盖。可复用的 live/E2E 工作流也采用共享镜像模式:在 Docker 矩阵开始之前构建并推送一个带 SHA 标签的 GHCR Docker E2E 镜像,然后在 `OPENCLAW_SKIP_DOCKER_BUILD=1` 下运行矩阵。定时的 live/E2E 工作流每天运行完整的发布路径 Docker 套件。完整的内置 update/channel 矩阵仍然保持为手动/全套模式,因为它会重复执行真实的 npm update 和 doctor repair 过程。
|
||||
|
||||
本地 changed-lane 逻辑位于 `scripts/changed-lanes.mjs`,由 `scripts/check-changed.mjs` 执行。这个本地门控在架构边界方面比宽泛的 CI 平台范围更严格:核心生产更改会运行核心生产类型检查以及核心测试,核心纯测试更改只运行核心测试类型检查/测试,扩展生产更改会运行扩展生产类型检查以及扩展测试,而扩展纯测试更改只运行扩展测试类型检查/测试。公共插件 SDK 或 plugin-contract 更改会扩展到扩展验证,因为扩展依赖这些核心契约。仅发布元数据的版本提升会运行有针对性的版本/配置/根依赖检查。未知的根目录/配置更改会以安全优先方式退回到所有通道。
|
||||
本地已变更通道逻辑位于 `scripts/changed-lanes.mjs`,并由 `scripts/check-changed.mjs` 执行。这个本地门禁在架构边界方面比宽泛的 CI 平台范围更严格:core 生产变更会运行 core prod typecheck 加 core tests,core 仅测试变更只运行 core 测试 typecheck/tests,extension 生产变更会运行 extension prod typecheck 加 extension tests,而 extension 仅测试变更只运行 extension 测试 typecheck/tests。公开的插件 SDK 或 plugin-contract 变更会扩展到 extension 验证,因为 extensions 依赖这些 core 契约。仅包含发布元数据的版本号变更会运行有针对性的 version/config/root-dependency 检查。未知的 root/config 变更会以安全优先方式回退到所有通道。
|
||||
|
||||
在推送时,`checks` 矩阵会添加仅推送时运行的 `compat-node22` 通道。在拉取请求上,该通道会被跳过,矩阵会继续聚焦于常规测试/渠道通道。
|
||||
在 push 时,`checks` 矩阵会增加仅 push 运行的 `compat-node22` 通道。在拉取请求中,该通道会被跳过,矩阵会保持聚焦于常规测试/渠道通道。
|
||||
|
||||
最慢的 Node 测试家族会被拆分或平衡,以便让每个作业都保持较小规模,同时避免过度占用 runner:渠道契约以三个加权分片运行,内置插件测试在六个扩展 worker 之间平衡分配,小型核心单元通道会成对组合,auto-reply 以三个平衡 worker 运行而不是六个很小的 worker,而 agentic Gateway 网关/插件配置会分散到现有仅源码的 agentic Node 作业中,而不是等待已构建产物。大范围的浏览器、QA、媒体以及杂项插件测试使用各自专用的 Vitest 配置,而不是共享的插件兜底配置。扩展分片作业会以一个 Vitest worker 和更大的 Node 堆内存串行运行插件配置组,这样导入密集型的插件批次就不会让小型 CI runner 过度提交。宽范围的 agents 通道使用共享的 Vitest 文件级并行调度器,因为它主要受导入/调度支配,而不是被某个单独的慢测试文件主导。`runtime-config` 会与 infra core-runtime 分片一起运行,以避免共享运行时分片承担尾部耗时。`check-additional` 会把 package-boundary 的编译/canary 工作放在一起,并将运行时拓扑架构与 gateway watch 覆盖拆开;boundary guard 分片会在一个作业内部并发运行其小型且彼此独立的守卫。Gateway 网关 watch、渠道测试以及核心 support-boundary 分片会在 `build-artifacts` 中于 `dist/` 和 `dist-runtime/` 已构建完成后并发运行,保留它们原有的检查名称作为轻量验证作业,同时避免额外占用两个 Blacksmith worker,以及避免出现第二个产物消费者队列。
|
||||
最慢的 Node 测试族已被拆分或做了均衡,以便每个作业都保持较小规模,同时不过度预留 runner:渠道契约按权重拆成三个分片,内置插件测试在六个 extension worker 之间均衡分配,小型 core 单元通道成对组合,auto-reply 改为三个均衡 worker 而不是六个很小的 worker,而 agentic Gateway 网关/plugin 配置则分散到现有仅源码的 agentic Node 作业中,而不是等待已构建产物。宽范围的浏览器、QA、媒体和杂项插件测试使用各自专用的 Vitest 配置,而不是共享的插件兜底配置。Extension 分片作业会以串行方式运行 plugin 配置组,使用一个 Vitest worker 和更大的 Node heap,这样导入负载较重的插件批次就不会让小型 CI runner 过载。宽范围的 agents 通道使用共享的 Vitest 文件级并行调度器,因为它的瓶颈主要是导入/调度,而不是由某个单独的慢测试文件主导。`runtime-config` 与 infra core-runtime 分片一起运行,以避免共享 runtime 分片独自承担尾部耗时。`check-additional` 将 package-boundary compile/canary 工作保持在一起,并将 runtime topology architecture 与 gateway watch 覆盖拆开;boundary guard 分片会在一个作业内部并发运行其小型、彼此独立的 guard。Gateway watch、渠道测试和 core support-boundary 分片会在 `dist/` 和 `dist-runtime/` 已经构建完成后,于 `build-artifacts` 内部并发运行;这样既保留了它们原有的 check 名称作为轻量验证作业,又避免了额外占用两个 Blacksmith worker 以及第二条 artifact-consumer 队列。
|
||||
|
||||
Android CI 会同时运行 `testPlayDebugUnitTest` 和 `testThirdPartyDebugUnitTest`,然后构建 Play debug APK。第三方 flavor 没有独立的 source set 或 manifest;它的单元测试通道仍然会在启用 SMS/通话记录 BuildConfig 标志的情况下编译该 flavor,同时避免在每次 Android 相关推送时重复执行 debug APK 打包作业。
|
||||
`extension-fast` 仅在 PR 上运行,因为推送运行已经会执行完整的内置插件分片。这样可以在评审时提供已变更插件的反馈,同时避免在 `main` 上为了 `checks-node-extensions` 已经覆盖的内容而额外占用一个 Blacksmith worker。
|
||||
Android CI 会同时运行 `testPlayDebugUnitTest` 和 `testThirdPartyDebugUnitTest`,然后构建 Play debug APK。第三方 flavor 没有单独的 source set 或 manifest;它的单元测试通道仍会在启用 SMS/call-log `BuildConfig` 标志的情况下编译该 flavor,同时避免在每次与 Android 相关的推送中重复执行 debug APK 打包作业。
|
||||
`extension-fast` 仅在 PR 中运行,因为 push 运行已经会执行完整的内置插件分片。这样既能为评审提供已变更插件的反馈,又不会在 `main` 上为了 `checks-node-extensions` 中已经存在的覆盖而额外占用一个 Blacksmith worker。
|
||||
|
||||
当同一 PR 或 `main` 引用上有新的推送落地时,GitHub 可能会将被替代的作业标记为 `cancelled`。除非同一引用的最新一次运行也失败了,否则应将其视为 CI 噪音。聚合分片检查使用 `!cancelled() && always()`,因此它们仍会报告正常的分片失败,但在整个工作流已经被替代后不会继续排队。
|
||||
CI 并发键已版本化(`CI-v7-*`),这样 GitHub 侧旧队列组中的僵尸任务就无法无限期阻塞更新的 main 运行。
|
||||
当同一个 PR 或 `main` ref 上有更新的推送到达时,GitHub 可能会把被取代的作业标记为 `cancelled`。除非同一 ref 的最新运行也失败了,否则应将其视为 CI 噪声。聚合分片检查使用 `!cancelled() && always()`,这样它们仍会报告正常的分片失败,但在整个工作流已经被更新运行取代后不会继续排队。
|
||||
CI 并发键采用版本化形式(`CI-v7-*`),这样 GitHub 端旧队列组中的僵尸任务就不会无限期阻塞较新的 `main` 运行。
|
||||
|
||||
## Runner
|
||||
|
||||
| Runner | 作业 |
|
||||
| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `ubuntu-24.04` | `preflight`、快速安全作业及其聚合(`security-scm-fast`、`security-dependency-audit`、`security-fast`)、快速 protocol/contract/bundled 检查、分片渠道契约检查、除 lint 外的 `check` 分片、`check-additional` 分片及聚合、Node 测试聚合验证器、文档检查、Python Skills、workflow-sanity、labeler、auto-response;install-smoke preflight 也使用 GitHub 托管的 Ubuntu,这样 Blacksmith 矩阵可以更早排队 |
|
||||
| `blacksmith-8vcpu-ubuntu-2404` | `build-artifacts`、build-smoke、Linux Node 测试分片、内置插件测试分片、`android` |
|
||||
| `blacksmith-16vcpu-ubuntu-2404` | `check-lint`,它仍然对 CPU 足够敏感,以至于 8 vCPU 的成本高于节省;install-smoke Docker 构建,在这里 32 vCPU 的排队时间成本高于节省 |
|
||||
| `blacksmith-16vcpu-windows-2025` | `checks-windows` |
|
||||
| `blacksmith-6vcpu-macos-latest` | `openclaw/openclaw` 上的 `macos-node`;fork 会回退到 `macos-latest` |
|
||||
| `blacksmith-12vcpu-macos-latest` | `openclaw/openclaw` 上的 `macos-swift`;fork 会回退到 `macos-latest` |
|
||||
| Runner | Jobs |
|
||||
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `ubuntu-24.04` | `preflight`、快速安全作业及其聚合作业(`security-scm-fast`、`security-dependency-audit`、`security-fast`)、快速 protocol/contract/bundled 检查、分片渠道契约检查、除 lint 外的 `check` 分片、`check-additional` 分片及聚合、Node 测试聚合验证器、文档检查、Python Skills、workflow-sanity、labeler、auto-response;install-smoke preflight 也使用 GitHub 托管的 Ubuntu,这样 Blacksmith 矩阵可以更早开始排队 |
|
||||
| `blacksmith-8vcpu-ubuntu-2404` | `build-artifacts`、build-smoke、Linux Node 测试分片、内置插件测试分片、`android` |
|
||||
| `blacksmith-16vcpu-ubuntu-2404` | `check-lint`,它仍然足够依赖 CPU,使用 8 vCPU 的成本高于节省的收益;install-smoke Docker 构建,在这里 32 vCPU 的排队时间成本高于节省的收益 |
|
||||
| `blacksmith-16vcpu-windows-2025` | `checks-windows` |
|
||||
| `blacksmith-6vcpu-macos-latest` | `openclaw/openclaw` 上的 `macos-node`;fork 会回退到 `macos-latest` |
|
||||
| `blacksmith-12vcpu-macos-latest` | `openclaw/openclaw` 上的 `macos-swift`;fork 会回退到 `macos-latest` |
|
||||
|
||||
## 本地对应项
|
||||
## 本地等价命令
|
||||
|
||||
```bash
|
||||
pnpm changed:lanes # 检查 origin/main...HEAD 的本地 changed-lane 分类器
|
||||
pnpm check:changed # 智能本地门控:按边界通道运行变更相关的类型检查/lint/测试
|
||||
pnpm check # 快速本地门控:生产 tsgo + 分片 lint + 并行快速守卫
|
||||
pnpm changed:lanes # 检查 origin/main...HEAD 的本地已变更通道分类器
|
||||
pnpm check:changed # 智能本地门禁:按边界通道运行已变更的 typecheck/lint/tests
|
||||
pnpm check # 快速本地门禁:生产 tsgo + 分片 lint + 并行快速 guards
|
||||
pnpm check:test-types
|
||||
pnpm check:timed # 相同门控,但附带各阶段耗时
|
||||
pnpm check:timed # 同样的门禁,但包含各阶段耗时
|
||||
pnpm build:strict-smoke
|
||||
pnpm check:architecture
|
||||
pnpm test:gateway:watch-regression
|
||||
pnpm test # Vitest 测试
|
||||
pnpm test # vitest 测试
|
||||
pnpm test:channels
|
||||
pnpm test:contracts:channels
|
||||
pnpm check:docs # 文档格式 + lint + 断链检查
|
||||
pnpm build # 当 CI 产物/build-smoke 通道相关时构建 dist
|
||||
pnpm check:docs # docs 格式 + lint + 损坏链接
|
||||
pnpm build # 当 CI artifact/build-smoke 通道相关时构建 dist
|
||||
node scripts/ci-run-timings.mjs <run-id> # 汇总总耗时、排队时间和最慢作业
|
||||
node scripts/ci-run-timings.mjs --recent 10 # 比较最近成功的 main CI 运行
|
||||
pnpm test:perf:groups --full-suite --allow-failures --output .artifacts/test-perf/baseline-before.json
|
||||
|
||||
@ -1,51 +1,51 @@
|
||||
---
|
||||
read_when:
|
||||
- 运行或修复测试
|
||||
summary: 如何在本地运行测试(`vitest`),以及何时使用 `force` / `coverage` 模式
|
||||
summary: 如何在本地运行测试(vitest),以及何时使用 force/coverage 模式
|
||||
title: 测试
|
||||
x-i18n:
|
||||
generated_at: "2026-04-24T05:03:01Z"
|
||||
generated_at: "2026-04-24T07:41:54Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: df4ad5808ddbc06c704c9bcf9f780b06f9be94ac213ed22e79d880dedcaa6d3b
|
||||
source_hash: 26cdb5fe005e738ddd00b183e91ccebe08c709bd64eed377d573a37b76e3a3bf
|
||||
source_path: reference/test.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
- 完整测试工具包(测试套件、live、Docker):[测试](/zh-CN/help/testing)
|
||||
|
||||
- `pnpm test:force`:终止任何仍占用默认控制端口的残留 Gateway 网关进程,然后使用隔离的 Gateway 网关端口运行完整的 Vitest 测试套件,这样服务端测试就不会与正在运行的实例发生冲突。当之前的 Gateway 网关运行导致端口 `18789` 仍被占用时,请使用它。
|
||||
- `pnpm test:coverage`:使用 V8 覆盖率运行单元测试套件(通过 `vitest.unit.config.ts`)。这是一个针对已加载文件的单元覆盖率门禁,而不是整个仓库的全文件覆盖率。阈值为 70% 的行数 / 函数 / 语句,以及 55% 的分支。由于 `coverage.all` 为 false,该门禁衡量的是单元覆盖率套件加载到的文件,而不是把每个拆分测试 lane 中的源文件都视为未覆盖。
|
||||
- `pnpm test:force`:终止任何仍在占用默认控制端口的残留 Gateway 网关进程,然后使用隔离的 Gateway 网关端口运行完整的 Vitest 测试套件,这样服务端测试就不会与正在运行的实例冲突。当之前的 Gateway 网关运行导致端口 18789 仍被占用时,使用此命令。
|
||||
- `pnpm test:coverage`:使用 V8 覆盖率运行单元测试套件(通过 `vitest.unit.config.ts`)。这是一个针对已加载文件的单元覆盖率门禁,不是针对整个仓库所有文件的覆盖率。阈值为 70% 的行数/函数/语句,以及 55% 的分支。由于 `coverage.all` 为 false,该门禁衡量的是单元覆盖率测试套件加载的文件,而不是把每个分片测试通道中的源文件都视为未覆盖。
|
||||
- `pnpm test:coverage:changed`:仅对自 `origin/main` 以来变更的文件运行单元覆盖率。
|
||||
- `pnpm test:changed`:当 diff 只涉及可路由的源码 / 测试文件时,会将变更的 Git 路径展开为作用域明确的 Vitest lane。配置 / 设置变更仍会回退到原生根项目运行,这样在需要时,接线层编辑会更广泛地重新运行测试。
|
||||
- `pnpm changed:lanes`:显示相对于 `origin/main` 的 diff 所触发的架构 lane。
|
||||
- `pnpm check:changed`:针对相对于 `origin/main` 的 diff 运行智能变更门禁。它会让核心工作对应核心测试 lane,扩展工作对应扩展测试 lane,仅测试相关工作只运行测试 typecheck / 测试,把公开 Plugin SDK 或 plugin-contract 变更扩展为一次扩展验证,并让仅发布元数据的版本变更保持在有针对性的版本 / 配置 / 根依赖检查范围内。
|
||||
- `pnpm test`:通过作用域明确的 Vitest lane 路由显式的文件 / 目录目标。未指定目标的运行会使用固定分片组,并展开为叶子配置以便在本地并行执行;扩展组始终会展开为每个扩展 / 插件的分片配置,而不是一个巨大的根项目进程。
|
||||
- 完整测试和扩展分片运行会更新 `.artifacts/vitest-shard-timings.json` 中的本地计时数据;后续运行会使用这些计时来平衡慢分片和快分片。设置 `OPENCLAW_TEST_PROJECTS_TIMINGS=0` 可忽略本地计时产物。
|
||||
- 部分 `plugin-sdk` 和 `commands` 测试文件现在会路由到专用的轻量 lane,这些 lane 仅保留 `test/setup.ts`,而运行时较重的用例仍保留在原有 lane 中。
|
||||
- 部分 `plugin-sdk` 和 `commands` 辅助源码文件也会把 `pnpm test:changed` 映射到这些轻量 lane 中明确的同级测试,因此对小型辅助函数的修改可以避免重新运行依赖重运行时的测试套件。
|
||||
- `auto-reply` 现在也拆分为三个专用配置(`core`、`top-level`、`reply`),这样 reply harness 就不会主导较轻的顶层状态 / token / helper 测试。
|
||||
- 基础 Vitest 配置现在默认使用 `pool: "threads"` 和 `isolate: false`,并在整个仓库配置中启用共享的非隔离 runner。
|
||||
- `pnpm test:changed`:当 diff 仅触及可路由的源文件/测试文件时,会将变更的 git 路径展开为有作用域的 Vitest 测试通道。配置/设置变更仍会回退到原生根项目运行,这样在需要时,连线方式相关的修改仍会更广泛地重新运行测试。
|
||||
- `pnpm changed:lanes`:显示相对于 `origin/main` 的 diff 所触发的架构测试通道。
|
||||
- `pnpm check:changed`:针对相对于 `origin/main` 的 diff 运行智能变更门禁。它会将 core 工作与 core 测试通道一起运行,将扩展工作与扩展测试通道一起运行,将仅测试改动限制为仅测试类型检查/测试,并将公开 Plugin SDK 或插件契约变更扩展为一次扩展验证,同时让仅发布元数据的版本提升保持在定向的版本/配置/根依赖检查范围内。
|
||||
- `pnpm test`:通过有作用域的 Vitest 测试通道路由显式的文件/目录目标。未指定目标的运行会使用固定的分片组,并展开为叶子配置以便在本地并行执行;扩展组始终会展开为按扩展划分的分片配置,而不是一个巨大的根项目进程。
|
||||
- 完整测试和扩展分片运行会在 `.artifacts/vitest-shard-timings.json` 中更新本地时间数据;后续运行会使用这些时间数据来平衡慢速和快速分片。设置 `OPENCLAW_TEST_PROJECTS_TIMINGS=0` 可忽略本地时间工件。
|
||||
- 选定的 `plugin-sdk` 和 `commands` 测试文件现在会路由到专用的轻量测试通道,这些通道仅保留 `test/setup.ts`,而运行时负载较重的用例仍留在现有测试通道中。
|
||||
- 选定的 `plugin-sdk` 和 `commands` 辅助源文件也会将 `pnpm test:changed` 映射到这些轻量测试通道中的显式同级测试,因此小型辅助函数改动可以避免重新运行依赖重型运行时的测试套件。
|
||||
- `auto-reply` 现在也被拆分为三个专用配置(`core`、`top-level`、`reply`),这样 reply 测试框架就不会主导较轻量的顶层状态/token/helper 测试。
|
||||
- 基础 Vitest 配置现在默认使用 `pool: "threads"` 和 `isolate: false`,并在整个仓库配置中启用共享的非隔离运行器。
|
||||
- `pnpm test:channels` 运行 `vitest.channels.config.ts`。
|
||||
- `pnpm test:extensions` 和 `pnpm test extensions` 运行所有扩展 / 插件分片。重型渠道插件、browser 插件以及 OpenAI 会作为专用分片运行;其他插件组保持批量处理。对单个内置插件 lane,请使用 `pnpm test extensions/<id>`。
|
||||
- `pnpm test:perf:imports`:启用 Vitest 导入时长 + 导入明细报告,同时仍对显式文件 / 目录目标使用作用域明确的 lane 路由。
|
||||
- `pnpm test:perf:imports:changed`:同样的导入性能分析,但仅针对自 `origin/main` 以来变更的文件。
|
||||
- `pnpm test:perf:changed:bench -- --ref <git-ref>`:针对同一份已提交的 Git diff,对比已路由的 changed 模式路径和原生根项目运行的基准表现。
|
||||
- `pnpm test:perf:changed:bench -- --worktree`:对当前工作树变更集进行基准测试,无需先提交。
|
||||
- `pnpm test:extensions` 和 `pnpm test extensions` 运行所有扩展/插件分片。重量级渠道插件、浏览器插件以及 OpenAI 会作为专用分片运行;其他插件组则保持批量执行。对某个内置插件测试通道使用 `pnpm test extensions/<id>`。
|
||||
- `pnpm test:perf:imports`:启用 Vitest 导入耗时 + 导入明细报告,同时对显式文件/目录目标仍使用有作用域的测试通道路由。
|
||||
- `pnpm test:perf:imports:changed`:相同的导入性能分析,但仅针对自 `origin/main` 以来变更的文件。
|
||||
- `pnpm test:perf:changed:bench -- --ref <git-ref>`:针对同一已提交 git diff,将路由后的 changed 模式路径与原生根项目运行进行基准对比。
|
||||
- `pnpm test:perf:changed:bench -- --worktree`:在无需先提交的情况下,对当前工作区变更集进行基准测试。
|
||||
- `pnpm test:perf:profile:main`:为 Vitest 主线程写入 CPU profile(`.artifacts/vitest-main-profile`)。
|
||||
- `pnpm test:perf:profile:runner`:为单元测试 runner 写入 CPU + 堆 profile(`.artifacts/vitest-runner-profile`)。
|
||||
- `pnpm test:perf:groups --full-suite --allow-failures --output .artifacts/test-perf/baseline-before.json`:串行运行每个完整测试套件的 Vitest 叶子配置,并写出分组时长数据以及每个配置的 JSON / 日志产物。测试性能代理会在尝试修复慢测试之前,将其用作基线。
|
||||
- `pnpm test:perf:groups:compare .artifacts/test-perf/baseline-before.json .artifacts/test-perf/after-agent.json`:在面向性能的改动之后比较分组报告。
|
||||
- `pnpm test:perf:profile:runner`:为单元测试运行器写入 CPU + 堆 profile(`.artifacts/vitest-runner-profile`)。
|
||||
- `pnpm test:perf:groups --full-suite --allow-failures --output .artifacts/test-perf/baseline-before.json`:串行运行每个完整测试套件的 Vitest 叶子配置,并写入分组耗时数据以及每个配置对应的 JSON/日志工件。Test Performance Agent 会将其作为尝试修复慢测试之前的基线。
|
||||
- `pnpm test:perf:groups:compare .artifacts/test-perf/baseline-before.json .artifacts/test-perf/after-agent.json`:比较一次以性能为重点的改动前后的分组报告。
|
||||
- Gateway 网关集成测试:通过 `OPENCLAW_TEST_INCLUDE_GATEWAY=1 pnpm test` 或 `pnpm test:gateway` 选择启用。
|
||||
- `pnpm test:e2e`:运行 Gateway 网关端到端 smoke 测试(多实例 WS / HTTP / 节点配对)。在 `vitest.e2e.config.ts` 中默认使用 `threads` + `isolate: false` 和自适应 workers;可使用 `OPENCLAW_E2E_WORKERS=<n>` 调整,并设置 `OPENCLAW_E2E_VERBOSE=1` 以输出详细日志。
|
||||
- `pnpm test:live`:运行提供商 live 测试(minimax / zai)。需要 API key,并且需要 `LIVE=1`(或提供商专用的 `*_LIVE_TEST=1`)才能取消跳过。
|
||||
- `pnpm test:docker:all`:先构建共享的 live-test 镜像和 Docker E2E 镜像各一次,然后在默认并发数 8 下,以 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行 Docker smoke lane。可使用 `OPENCLAW_DOCKER_ALL_PARALLELISM=<n>` 调整主池,使用 `OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM=<n>` 调整对提供商更敏感的尾部池;两者默认都为 8。除非设置 `OPENCLAW_DOCKER_ALL_FAIL_FAST=0`,否则 runner 会在首次失败后停止调度新的池化 lane;每个 lane 默认超时 120 分钟,可通过 `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS` 覆盖。每个 lane 的日志会写入 `.artifacts/docker-tests/<run-id>/`。
|
||||
- `pnpm test:docker:openwebui`:启动 Docker 化的 OpenClaw + Open WebUI,通过 Open WebUI 登录,检查 `/api/models`,然后通过 `/api/chat/completions` 运行一次真实的代理聊天。需要可用的 live 模型 key(例如 `~/.profile` 中的 OpenAI),会拉取外部 Open WebUI 镜像,并不像常规单元 / e2e 测试套件那样预期具备 CI 稳定性。
|
||||
- `pnpm test:docker:mcp-channels`:启动一个已预置的 Gateway 网关容器和第二个客户端容器,后者会启动 `openclaw mcp serve`,然后验证经路由的会话发现、转录读取、附件元数据、实时事件队列行为、出站发送路由,以及通过真实 stdio bridge 传递的 Claude 风格渠道 + 权限通知。Claude 通知断言会直接读取原始 stdio MCP frame,因此这个 smoke 测试反映的是 bridge 实际发出的内容。
|
||||
- `pnpm test:e2e`:运行 Gateway 网关端到端冒烟测试(多实例 WS/HTTP/节点配对)。在 `vitest.e2e.config.ts` 中默认使用 `threads` + `isolate: false` 和自适应 worker;可通过 `OPENCLAW_E2E_WORKERS=<n>` 调整,并设置 `OPENCLAW_E2E_VERBOSE=1` 以输出详细日志。
|
||||
- `pnpm test:live`:运行提供商 live 测试(minimax/zai)。需要 API key,并且设置 `LIVE=1`(或特定提供商的 `*_LIVE_TEST=1`)后才会取消跳过。
|
||||
- `pnpm test:docker:all`:先构建共享的 live-test 镜像和 Docker E2E 镜像一次,然后默认以并发数 8、并设置 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行 Docker 冒烟测试通道。可通过 `OPENCLAW_DOCKER_ALL_PARALLELISM=<n>` 调整主池,通过 `OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM=<n>` 调整对提供商敏感的尾部池;两者默认都为 8。为避免本地 Docker 守护进程在创建阶段出现风暴,测试通道启动默认错开 2 秒;可通过 `OPENCLAW_DOCKER_ALL_START_STAGGER_MS=<ms>` 覆盖。除非设置 `OPENCLAW_DOCKER_ALL_FAIL_FAST=0`,否则运行器会在首次失败后停止调度新的池化测试通道;每个测试通道默认有 120 分钟超时,可通过 `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS` 覆盖。每个测试通道的日志会写入 `.artifacts/docker-tests/<run-id>/`。
|
||||
- `pnpm test:docker:openwebui`:启动 Docker 化的 OpenClaw + Open WebUI,通过 Open WebUI 登录,检查 `/api/models`,然后通过 `/api/chat/completions` 运行一次真实的代理聊天。需要可用的 live 模型密钥(例如在 `~/.profile` 中配置的 OpenAI),会拉取外部 Open WebUI 镜像,并且不像普通单元/e2e 测试套件那样预期具备 CI 稳定性。
|
||||
- `pnpm test:docker:mcp-channels`:启动一个预置数据的 Gateway 网关容器和第二个客户端容器,后者会拉起 `openclaw mcp serve`,然后验证路由对话发现、转录读取、附件元数据、live 事件队列行为、出站发送路由,以及通过真实 stdio bridge 传递的 Claude 风格渠道 + 权限通知。Claude 通知断言会直接读取原始 stdio MCP 帧,因此该冒烟测试反映的是 bridge 实际发出的内容。
|
||||
|
||||
## 本地 PR 门禁
|
||||
|
||||
对于本地 PR 合并 / 门禁检查,请运行:
|
||||
对于本地 PR 合并/门禁检查,运行:
|
||||
|
||||
- `pnpm check:changed`
|
||||
- `pnpm check`
|
||||
@ -54,12 +54,12 @@ x-i18n:
|
||||
- `pnpm test`
|
||||
- `pnpm check:docs`
|
||||
|
||||
如果 `pnpm test` 在负载较高的主机上出现偶发失败,先重跑一次,再将其视为回归问题,然后使用 `pnpm test <path/to/test>` 进行隔离。对于内存受限的主机,请使用:
|
||||
如果 `pnpm test` 在负载较高的主机上出现偶发失败,在将其视为回归之前先重跑一次,然后用 `pnpm test <path/to/test>` 进行定位。对于内存受限的主机,使用:
|
||||
|
||||
- `OPENCLAW_VITEST_MAX_WORKERS=1 pnpm test`
|
||||
- `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/tmp/openclaw-vitest-cache pnpm test:changed`
|
||||
|
||||
## 模型延迟基准测试(本地 key)
|
||||
## 模型延迟基准(本地密钥)
|
||||
|
||||
脚本:[`scripts/bench-model.ts`](https://github.com/openclaw/openclaw/blob/main/scripts/bench-model.ts)
|
||||
|
||||
@ -67,14 +67,14 @@ x-i18n:
|
||||
|
||||
- `source ~/.profile && pnpm tsx scripts/bench-model.ts --runs 10`
|
||||
- 可选环境变量:`MINIMAX_API_KEY`、`MINIMAX_BASE_URL`、`MINIMAX_MODEL`、`ANTHROPIC_API_KEY`
|
||||
- 默认提示词:“用一个单词回复:ok。不要使用标点或额外文本。”
|
||||
- 默认提示词:“Reply with a single word: ok. No punctuation or extra text.”
|
||||
|
||||
最近一次运行(2025-12-31,20 次):
|
||||
上次运行(2025-12-31,20 次):
|
||||
|
||||
- minimax 中位数 1279ms(最小 1114,最大 2431)
|
||||
- opus 中位数 2454ms(最小 1224,最大 3170)
|
||||
|
||||
## CLI 启动基准测试
|
||||
## CLI 启动基准
|
||||
|
||||
脚本:[`scripts/bench-cli-startup.ts`](https://github.com/openclaw/openclaw/blob/main/scripts/bench-cli-startup.ts)
|
||||
|
||||
@ -99,37 +99,37 @@ x-i18n:
|
||||
|
||||
- `startup`:`--version`、`--help`、`health`、`health --json`、`status --json`、`status`
|
||||
- `real`:`health`、`status`、`status --json`、`sessions`、`sessions --json`、`agents list --json`、`gateway status`、`gateway status --json`、`gateway health --json`、`config get gateway.port`
|
||||
- `all`:以上两个预设
|
||||
- `all`:同时包含两个预设
|
||||
|
||||
输出会包含每个命令的 `sampleCount`、平均值、p50、p95、最小 / 最大值、exit-code / signal 分布,以及最大 RSS 摘要。可选的 `--cpu-prof-dir` / `--heap-prof-dir` 会为每次运行写入 V8 profile,这样计时和 profile 捕获会使用同一个 harness。
|
||||
输出包含每条命令的 `sampleCount`、平均值、p50、p95、最小/最大值、exit-code/signal 分布,以及最大 RSS 汇总。可选的 `--cpu-prof-dir` / `--heap-prof-dir` 会为每次运行写入 V8 profile,因此计时和 profile 捕获使用的是同一个测试框架。
|
||||
|
||||
已保存输出约定:
|
||||
保存输出约定:
|
||||
|
||||
- `pnpm test:startup:bench:smoke` 会将定向 smoke 产物写入 `.artifacts/cli-startup-bench-smoke.json`
|
||||
- `pnpm test:startup:bench:save` 会使用 `runs=5` 和 `warmup=1` 将完整测试套件产物写入 `.artifacts/cli-startup-bench-all.json`
|
||||
- `pnpm test:startup:bench:update` 会使用 `runs=5` 和 `warmup=1` 刷新已提交的基线 fixture,路径为 `test/fixtures/cli-startup-bench.json`
|
||||
- `pnpm test:startup:bench:smoke` 会将定向冒烟工件写入 `.artifacts/cli-startup-bench-smoke.json`
|
||||
- `pnpm test:startup:bench:save` 会使用 `runs=5` 和 `warmup=1` 将完整测试套件工件写入 `.artifacts/cli-startup-bench-all.json`
|
||||
- `pnpm test:startup:bench:update` 会使用 `runs=5` 和 `warmup=1` 刷新已检入的基线夹具 `test/fixtures/cli-startup-bench.json`
|
||||
|
||||
已提交的 fixture:
|
||||
已检入的夹具:
|
||||
|
||||
- `test/fixtures/cli-startup-bench.json`
|
||||
- 使用 `pnpm test:startup:bench:update` 刷新
|
||||
- 使用 `pnpm test:startup:bench:check` 将当前结果与该 fixture 进行比较
|
||||
- 使用 `pnpm test:startup:bench:check` 将当前结果与该夹具进行比较
|
||||
|
||||
## 新手引导 E2E(Docker)
|
||||
|
||||
Docker 是可选的;只有在运行容器化的新手引导 smoke 测试时才需要。
|
||||
Docker 是可选的;这只在容器化新手引导冒烟测试中需要。
|
||||
|
||||
在干净的 Linux 容器中执行完整冷启动流程:
|
||||
在一个干净的 Linux 容器中执行完整冷启动流程:
|
||||
|
||||
```bash
|
||||
scripts/e2e/onboard-docker.sh
|
||||
```
|
||||
|
||||
该脚本会通过 pseudo-tty 驱动交互式向导,验证配置 / 工作区 / 会话文件,然后启动 Gateway 网关并运行 `openclaw health`。
|
||||
该脚本会通过 pseudo-tty 驱动交互式向导,验证配置/工作区/会话文件,然后启动 Gateway 网关并运行 `openclaw health`。
|
||||
|
||||
## QR 导入 smoke 测试(Docker)
|
||||
## QR 导入冒烟测试(Docker)
|
||||
|
||||
确保受维护的 QR 运行时 helper 能在受支持的 Docker Node 运行时下正常加载(默认 Node 24,兼容 Node 22):
|
||||
确保维护中的 QR 运行时 helper 能在受支持的 Docker Node 运行时中正确加载(默认 Node 24,兼容 Node 22):
|
||||
|
||||
```bash
|
||||
pnpm test:docker:qr
|
||||
|
||||
Loading…
Reference in New Issue
Block a user