chore(i18n): refresh zh-CN translations

This commit is contained in:
openclaw-docs-i18n[bot] 2026-05-01 03:03:15 +00:00
parent 28ac0cb55b
commit 8368406b5d
6 changed files with 966 additions and 936 deletions

View File

@ -2,33 +2,33 @@
read_when:
- 更改群聊行为或提及门控
sidebarTitle: Groups
summary: 各平台上的群聊行为Discord/iMessage/Matrix/Microsoft Teams/Signal/Slack/Telegram/WhatsApp/Zalo
summary: 各界面的群聊行为Discord/iMessage/Matrix/Microsoft Teams/Signal/Slack/Telegram/WhatsApp/Zalo
title: 群组
x-i18n:
generated_at: "2026-04-30T14:57:26Z"
generated_at: "2026-05-01T02:59:51Z"
model: gpt-5.5
provider: openai
source_hash: ed9cba03cf4546a20d473e8095a54858530869b27f8934f2680e8dbe987dbf5e
source_hash: a8580f98ab03c89770688102da776627d8ce18b7bd34c4a687009fd4aabb6213
source_path: channels/groups.md
workflow: 16
---
OpenClaw 会在各个平台上一致处理群聊Discord、iMessage、Matrix、Microsoft Teams、Signal、Slack、Telegram、WhatsApp、Zalo。
OpenClaw 在各个表面上对群聊的处理保持一致Discord、iMessage、Matrix、Microsoft Teams、Signal、Slack、Telegram、WhatsApp、Zalo。
## 初学者简介2 分钟)
## 新手介绍2 分钟)
OpenClaw “存在于”你自己的消息账号中。没有单独的 WhatsApp bot 用户。如果**你**在某个群组中OpenClaw 就能看到该群组并在那里回复。
OpenClaw “运行”在你自己的消息账号上。没有单独的 WhatsApp bot 用户。如果**你**在某个群组中OpenClaw 就能看到该群组并在那里回复。
默认行为:
- 群组受限制(`groupPolicy: "allowlist"`)。
- 除非你明确禁用提及门控,否则回复需要提及
- 群组/渠道中的普通最终回复默认是私有的。可见的房间输出使用 `message` 工具。
- 回复需要提及,除非你明确禁用提及门控。
- 群组/渠道中的常规最终回复默认是私密的。可见的房间输出使用 `message` 工具。
换句话说:允许列表中的发送者可以通过提及 OpenClaw 来触发它。
<Note>
**太长不看**
**概要**
- **私信访问**由 `*.allowFrom` 控制。
- **群组访问**由 `*.groupPolicy` + 允许列表(`*.groups`、`*.groupAllowFrom`)控制。
@ -48,15 +48,18 @@ otherwise -> reply
## 可见回复
对于群组/渠道房间OpenClaw 默认使用 `messages.groupChat.visibleReplies: "message_tool"`
这意味着智能体仍会处理该轮次,并且可以更新记忆/会话状态,但它的普通最终答案不会自动发回房间。要可见地发言,智能体使用 `message(action=send)`
这意味着智能体仍会处理这一轮,并且可以更新记忆/会话状态,但它的常规最终答案不会自动发回房间。要可见地发言,智能体使用 `message(action=send)`
对于直接聊天和任何其他来源轮次,使用 `messages.visibleReplies: "message_tool"` 可在全局应用相同的仅工具可见回复行为。`messages.groupChat.visibleReplies` 仍然是针对群组/渠道房间的更具体覆盖项。
如果在当前工具策略下消息工具不可用OpenClaw 会回退到自动可见回复,而不是静默抑制响应。
`openclaw doctor` 会警告这种不匹配。
这取代了旧模式:强制模型在大多数潜伏模式轮次中回答 `NO_REPLY`。在仅工具模式中,不产生任何可见输出只意味着不调用消息工具
对于直接聊天和任何其他来源轮次,使用 `messages.visibleReplies: "message_tool"` 可在全局应用相同的仅工具可见回复行为。`messages.groupChat.visibleReplies` 仍然是针对群组/渠道房间更具体的覆盖项
当智能体在仅工具模式中工作时,仍会发送输入状态提示。对于这些轮次,默认群组输入状态模式会从 “message” 升级为 “instant”因为在智能体决定是否调用消息工具之前可能永远不会有普通的助手消息文本。显式配置的输入状态模式仍然优先生效
这取代了旧模式:强制模型在大多数潜伏模式轮次中回答 `NO_REPLY`。在仅工具模式下,不产生可见内容只是意味着不调用消息工具
要恢复群组/渠道房间的旧版自动最终回复:
智能体在仅工具模式下工作时,仍会发送正在输入指示。对于这些轮次,默认群组输入模式会从 “message” 升级为 “instant”因为在智能体决定是否调用消息工具之前可能永远不会有常规助手消息文本。显式的输入模式配置仍然优先。
要为群组/渠道房间恢复旧版自动最终回复:
```json5
{
@ -68,9 +71,9 @@ otherwise -> reply
}
```
文件保存Gateway 网关会热重载 `messages` 配置。只有在部署中禁用了文件监听或配置重载时才需要重启。
保存文件后Gateway 网关会热重载 `messages` 配置。仅当部署中禁用了文件监听或配置重载时才需要重启。
要要求每个来源聊天的可见输出都通过消息工具:
要要求每个来源聊天的可见输出都通过消息工具发送
```json5
{
@ -80,16 +83,16 @@ otherwise -> reply
}
```
原生斜杠命令Discord、Telegram 以及其他支持原生命令的平台)会绕过 `visibleReplies: "message_tool"`,并始终可见地回复,以便渠道原生命令 UI 获得预期响应。这仅适用于已验证的原生命令轮次;文本输入的 `/...` 命令和普通聊天轮次仍遵循配置的群组默认值。
原生命令Discord、Telegram 以及其他支持原生命令的表面)会绕过 `visibleReplies: "message_tool"`,并始终可见地回复,这样渠道原生命令 UI 才能获得预期的响应。这仅适用于已验证的原生命令轮次;文本输入的 `/...` 命令和普通聊天轮次仍遵循配置的群组默认值。
## 上下文可见性允许列表
## 上下文可见性允许列表
群组安全涉及两种不同的控制:
- **触发授权**:谁可以触发智能体(`groupPolicy`、`groups`、`groupAllowFrom`、渠道专用允许列表)。
- **上下文可见性**:哪些补充上下文会注入模型(回复文本、引用、线程历史、转发元数据)。
- **触发授权**:谁可以触发智能体(`groupPolicy`、`groups`、`groupAllowFrom`、渠道特定允许列表)。
- **上下文可见性**:哪些补充上下文会注入模型(回复文本、引用、线程历史、转发元数据)。
默认情况下OpenClaw 优先考虑正常聊天行为,并尽量按接收原样保留上下文。这意味着允许列表主要决定谁可以触发操作,而不是作为每段引用或历史片段的通用脱敏边界。
默认情况下OpenClaw 优先保持正常聊天行为,并让上下文大体按接收原样保留。这意味着允许列表主要决定谁可以触发操作,而不是每个引用或历史片段的通用脱敏边界。
<AccordionGroup>
<Accordion title="当前行为因渠道而异">
@ -98,11 +101,11 @@ otherwise -> reply
</Accordion>
<Accordion title="加固方向(计划中)">
- `contextVisibility: "all"`(默认)保当前按接收原样的行为。
- `contextVisibility: "all"`(默认)保当前按接收原样的行为。
- `contextVisibility: "allowlist"` 将补充上下文过滤为允许列表中的发送者。
- `contextVisibility: "allowlist_quote"``allowlist` 加上一个显式引用/回复例外。
- `contextVisibility: "allowlist_quote"``allowlist` 加上一个显式引用/回复例外。
这个加固模型跨渠道一致实现之前,预期不同平台会存在差异。
此加固模型跨渠道一致实现之前,预期不同表面会存在差异。
</Accordion>
</AccordionGroup>
@ -111,39 +114,39 @@ otherwise -> reply
如果你想要……
| 目标 | 要设置的内容 |
| 目标 | 需要设置什么 |
| -------------------------------------------- | ---------------------------------------------------------- |
| 允许所有群组,但只在 @提及时回复 | `groups: { "*": { requireMention: true } }` |
| 禁用所有群组回复 | `groupPolicy: "disabled"` |
| 仅允许特定群组 | `groups: { "<group-id>": { ... } }`(没有 `"*"` 键) |
| 只有你可以在群组中触发 | `groupPolicy: "allowlist"`、`groupAllowFrom: ["+1555..."]` |
| 仅特定群组 | `groups: { "<group-id>": { ... } }`(没有 `"*"` 键) |
| 只有你可以在群组中触发 | `groupPolicy: "allowlist"`, `groupAllowFrom: ["+1555..."]` |
## 会话键
- 群组会话使用 `agent:<agentId>:<channel>:group:<id>` 会话键(房间/渠道使用 `agent:<agentId>:<channel>:channel:<id>`)。
- Telegram 论坛话题会向群组 ID 添加 `:topic:<threadId>`,因此每个话题都有自己的会话。
- 直接聊天使用主会话(如果已配置,也可以按发送者使用单独会话)。
- Telegram 论坛主题会向群组 ID 添加 `:topic:<threadId>`,因此每个主题都有自己的会话。
- 直接聊天使用主会话(如果已配置,则使用按发送者的会话)。
- 群组会话会跳过 Heartbeat。
<a id="pattern-personal-dms-public-groups-single-agent"></a>
## 模式:个人私信 + 公开群组(单智能体)
## 模式:个人私信 + 公开群组(单智能体)
可以。如果你的“个人”流量是**私信**,而“公开”流量是**群组**,这会很好用
可以,这很适合你的“个人”流量是**私信**、你的“公开”流量是**群组**的情况
原因:在单智能体模式下,私信通常会落入**主**会话键(`agent:main:main`,而群组始终使用**非主**会话键(`agent:main:<channel>:group:<id>`)。如果你启用 `mode: "non-main"` 的沙箱隔离这些群组会话会在配置的沙箱后端中运行而你的主私信会话仍留在主机上。如果你没有选择后端Docker 是默认后端。
原因:在单智能体模式下,私信通常会落到**主**会话键(`agent:main:main`)中,而群组始终使用**非主**会话键(`agent:main:<channel>:group:<id>`)。如果你启用 `mode: "non-main"` 的沙箱隔离,这些群组会话会在配置的沙箱后端中运行,而你的主私信会话仍留在主机上。如果你没有选择后端Docker 是默认后端。
会给你一个智能体“大脑”(共享工作区 + 记忆),但有两种执行姿态:
为你提供一个智能体“大脑”(共享工作区 + 记忆),但有两种执行姿态:
- **私信**:完整工具(主机)
- **群组**:沙箱 + 受限工具
<Note>
如果你需要真正分离的工作区/角色(“个人”和“公开”绝不能混用),请使用第二个智能体 + 绑定。参见[多智能体路由](/zh-CN/concepts/multi-agent)。
如果你需要真正独立的工作区/人格(“个人”和“公开”绝不能混合),请使用第二个智能体 + 绑定。参见[多智能体路由](/zh-CN/concepts/multi-agent)。
</Note>
<Tabs>
<Tab title="私信在主机上,群组在沙箱中">
<Tab title="私信在主机上运行,群组使用沙箱隔离">
```json5
{
agents: {
@ -168,7 +171,7 @@ otherwise -> reply
```
</Tab>
<Tab title="群组只能看到允许列表中的文件夹">
让“群组只能看到文件夹 X”而不是“不能访问主机”?保留 `workspaceAccess: "none"`,并只将允许列表中的路径挂载到沙箱
要“群组只能看到文件夹 X”而不是“无主机访问”?保留 `workspaceAccess: "none"`,并只将允许列表中的路径挂载到沙箱:
```json5
{
@ -196,7 +199,7 @@ otherwise -> reply
相关:
- 配置键和默认值:[Gateway 网关配置](/zh-CN/gateway/config-agents#agentsdefaultssandbox)
- 调试工具被阻止的原因[沙箱 vs 工具策略 vs 提权](/zh-CN/gateway/sandbox-vs-tool-policy-vs-elevated)
- 调试工具为什么被阻止:[沙箱 vs 工具策略 vs 提权](/zh-CN/gateway/sandbox-vs-tool-policy-vs-elevated)
- 绑定挂载详情:[沙箱隔离](/zh-CN/gateway/sandboxing#custom-bind-mounts)
## 显示标签
@ -260,30 +263,30 @@ otherwise -> reply
| `"allowlist"` | 只允许匹配已配置允许列表的群组/房间。 |
<AccordionGroup>
<Accordion title="渠道说明">
- `groupPolicy` 与提及门控(需要 @提及)是分开的
<Accordion title="渠道说明">
- `groupPolicy` 独立于提及门控(后者要求 @提及
- WhatsApp/Telegram/Signal/iMessage/Microsoft Teams/Zalo使用 `groupAllowFrom`(回退:显式 `allowFrom`)。
- Signal`groupAllowFrom` 可以匹配入站 Signal 群组 ID 或发送者电话/UUID。
- 私信配对批(`*-allowFrom` 存储条目)仅适用于私信访问;群组发送者授权仍显式使用群组允许列表
- 私信配对批`*-allowFrom` 存储条目)仅适用于私信访问;群组发送者授权仍显式保留在群组允许列表中
- Discord允许列表使用 `channels.discord.guilds.<id>.channels`
- Slack允许列表使用 `channels.slack.channels`
- Matrix允许列表使用 `channels.matrix.groups`。优先使用房间 ID 或别名;已加入房间的名称查找是尽力而为,未解析的名称会在运行时被忽略。使用 `channels.matrix.groupAllowFrom` 限制发送者;也支持按房间配置`users` 允许列表。
- Matrix允许列表使用 `channels.matrix.groups`。优先使用房间 ID 或别名;已加入房间的名称查找是尽力而为,未解析的名称会在运行时被忽略。使用 `channels.matrix.groupAllowFrom` 限制发送者;也支持按房间的 `users` 允许列表。
- 群组私信单独控制(`channels.discord.dm.*`、`channels.slack.dm.*`)。
- Telegram 允许列表可以匹配用户 ID`"123456789"`、`"telegram:123456789"`、`"tg:123456789"`)或用户名(`"@alice"` 或 `"alice"`);前缀不区分大小写。
- 默认值 `groupPolicy: "allowlist"`;如果你的群组允许列表为空,群组消息会被阻止。
- 运行时安全:当提供商块完全缺失(不存在 `channels.<provider>`)时,群组策略会回退到故障关闭模式(通常是 `allowlist`),而不是继承 `channels.defaults.groupPolicy`
- 默认值 `groupPolicy: "allowlist"`;如果你的群组允许列表为空,群组消息会被阻止。
- 运行时安全:当提供商块完全缺失(`channels.<provider>` 不存在)时,群组策略会回退到失败关闭模式(通常是 `allowlist`),而不是继承 `channels.defaults.groupPolicy`
</Accordion>
</AccordionGroup>
快速心智模型(群组消息的评估顺序):
群组消息的快速心智模型(评估顺序):
<Steps>
<Step title="groupPolicy">
`groupPolicy`open/disabled/allowlist
</Step>
<Step title="群组允许列表">
群组允许列表(`*.groups`、`*.groupAllowFrom`、渠道专用允许列表)。
群组允许列表(`*.groups`、`*.groupAllowFrom`、特定渠道允许列表)。
</Step>
<Step title="提及门控">
提及门控(`requireMention`、`/activation`)。
@ -292,9 +295,9 @@ otherwise -> reply
## 提及门控(默认)
除非按群组覆盖,否则群组消息需要提及。默认值按子系统位于 `*.groups."*"` 下。
群组消息需要提及,除非按群组覆盖。默认值位于每个子系统的 `*.groups."*"` 下。
回复机器人消息在渠道支持回复元数据时会计为隐式提及。引用机器人消息在暴露引用元数据的渠道上也可计为隐式提及。当前内置案例包括 Telegram、WhatsApp、Slack、Discord、Microsoft Teams 和 ZaloUser。
当渠道支持回复元数据时,回复机器人消息会被视为隐式提及。在暴露引用元数据的渠道上,引用机器人消息也可以被视为隐式提及。当前内置情况包括 Telegram、WhatsApp、Slack、Discord、Microsoft Teams 和 ZaloUser。
```json5
{
@ -334,15 +337,15 @@ otherwise -> reply
<AccordionGroup>
<Accordion title="提及门控说明">
- `mentionPatterns` 是大小写不敏感的安全正则表达式模式;无效模式和不安全的嵌套重复形式会被忽略。
- 提供显式提及的面仍会通过;模式是一种回退机制。
- 按智能体覆盖:`agents.list[].groupChat.mentionPatterns`(当多个智能体共享一个群组时很有用)。
- 只有在可以进行提及检测时,才会强制执行提及门控(配置原生提及或 `mentionPatterns`)。
- 将某个群组或发送者加入允许列表不会禁用提及门控;当所有消息都应触发时,请将该群组的 `requireMention``false`
- 群聊提示上下文会在每轮携带解析的静默回复指令;工作区文件不应重复 `NO_REPLY` 机制。
- 允许静默回复的群组会将干净的空模型轮次或仅推理模型轮次视为静默,等同于 `NO_REPLY`。只有在明确允许直接静默回复时,直接聊天才会执行相同行为;否则空回复仍会保留为失败的智能体轮次。
- `mentionPatterns`不区分大小写的安全正则表达式模式;无效模式和不安全的嵌套重复形式会被忽略。
- 提供显式提及的面仍会通过;模式是一种回退机制。
- 按智能体覆盖:`agents.list[].groupChat.mentionPatterns`(当多个智能体共享一个群组时很有用)。
- 只有在可以检测提及时,才会强制执行提及门控(配置原生提及或 `mentionPatterns`)。
- 将群组或发送者加入允许列表不会禁用提及门控;当所有消息都应触发时,请将该群组的 `requireMention` 设为 `false`
- 群聊提示上下文会在每轮携带解析的静默回复指令;工作区文件不应重复 `NO_REPLY` 机制。
- 允许静默回复的群组会将干净的空模型轮次或仅推理模型轮次视为静默,等同于 `NO_REPLY`。只有在明确允许直接静默回复时,直接聊天才会执行相同处理;否则空回复仍会被视为失败的智能体轮次。
- Discord 默认值位于 `channels.discord.guilds."*"`(可按服务器/渠道覆盖)。
- 群组历史上下文在各渠道中统一方式包装,并且**仅待处理**(因提及门控而跳过的消息);使用 `messages.groupChat.historyLimit` 设置全局默认值,使用 `channels.<channel>.historyLimit`(或 `channels.<channel>.accounts.*.historyLimit`)进行覆盖。设`0` 可禁用。
- 群组历史上下文在各渠道中统一包装,并且**仅待处理**(因提及门控而跳过的消息);使用 `messages.groupChat.historyLimit` 设置全局默认值,使用 `channels.<channel>.historyLimit`(或 `channels.<channel>.accounts.*.historyLimit`)进行覆盖。设为 `0` 可禁用。
</Accordion>
</AccordionGroup>
@ -354,19 +357,19 @@ otherwise -> reply
- `tools`:允许/拒绝整个群组的工具。
- `toolsBySender`:群组内按发送者覆盖。使用显式键前缀:`id:<senderId>`、`e164:<phone>`、`username:<handle>`、`name:<displayName>` 和 `"*"` 通配符。旧版无前缀键仍被接受,并且仅按 `id:` 匹配。
解析顺序(最具体优先):
解析顺序(最具体优先):
<Steps>
<Step title="群组 toolsBySender">
群组/渠道 `toolsBySender` 匹配。
</Step>
<Step title="群组工具">
<Step title="群组 tools">
群组/渠道 `tools`
</Step>
<Step title="默认 toolsBySender">
默认(`"*"``toolsBySender` 匹配。
</Step>
<Step title="默认工具">
<Step title="默认 tools">
默认(`"*"``tools`。
</Step>
</Steps>
@ -392,15 +395,15 @@ otherwise -> reply
```
<Note>
群组/渠道工具限制会在全局/智能体工具策略之外额外应用(拒绝仍然优先)。某些渠道对房间/渠道使用不同的嵌套结构(例如 Discord `guilds.*.channels.*`、Slack `channels.*`、Microsoft Teams `teams.*.channels.*`)。
群组/渠道工具限制会叠加到全局/智能体工具策略之上(拒绝仍然优先)。某些渠道对房间/渠道使用不同的嵌套结构(例如 Discord `guilds.*.channels.*`、Slack `channels.*`、Microsoft Teams `teams.*.channels.*`)。
</Note>
## 群组允许列表
配置 `channels.whatsapp.groups`、`channels.telegram.groups` 或 `channels.imessage.groups` 时,这些键会作为群组允许列表。使用 `"*"` 可允许所有群组,同时仍设置默认提及行为。
配置 `channels.whatsapp.groups`、`channels.telegram.groups` 或 `channels.imessage.groups` 时,键会作为群组允许列表。使用 `"*"` 可允许所有群组,同时仍设置默认提及行为。
<Warning>
常见混淆:私信配对批准同于群组授权。对于支持私信配对的渠道,配对存储只会解锁私信。群组命令仍需要来自配置允许列表(如 `groupAllowFrom`)的显式群组发送者授权,或该渠道记录的配置回退。
常见混淆:私信配对批准不同于群组授权。对于支持私信配对的渠道,配对存储只会解锁私信。群组命令仍需要来自配置允许列表的显式群组发送者授权,例如 `groupAllowFrom` 或该渠道记录的配置回退。
</Warning>
常见意图(复制/粘贴):
@ -460,7 +463,7 @@ otherwise -> reply
- `/activation mention`
- `/activation always`
所有者由 `channels.whatsapp.allowFrom` 确定(未设置时使用机器人的自有 E.164)。将命令作为独立消息发送。其他界面目前会忽略 `/activation`
所有者由 `channels.whatsapp.allowFrom` 确定(未设置时使用机器人的自身 E.164)。将命令作为独立消息发送。其他表面目前会忽略 `/activation`
## 上下文字段
@ -470,27 +473,27 @@ otherwise -> reply
- `GroupSubject`(如果已知)
- `GroupMembers`(如果已知)
- `WasMentioned`(提及门控结果)
- Telegram 论坛主题还包含 `MessageThreadId``IsForum`
- Telegram 论坛话题还包括 `MessageThreadId``IsForum`
渠道特定说明:
- BlueBubbles 可以选择在填充 `GroupMembers` 之前,从本地通讯录数据库补充未命名的 macOS 群组参与者。此功能默认关闭,并且仅在正常群组门控通过后运行。
- BlueBubbles 可以在填充 `GroupMembers` 之前,从本地通讯录数据库可选地补充未命名的 macOS 群组参与者信息。此功能默认关闭,并且只在正常群组门控通过后运行。
智能体系统提示会在新群组会话的第一轮包含群组介绍。它提醒模型像人一样回复,避免 Markdown 表格,尽量减少空行并遵循正常聊天间距,并避免输入字面量 `\n` 序列。来自渠道的群组名称和参与者标签会渲染为围栏包裹的不受信任元数据,而不是内联系统指令。
智能体系统提示会在新群组会话的第一轮包含群组介绍。它提醒模型像人一样回复,避免使用 Markdown 表格,尽量减少空行并遵循正常聊天间距,且避免输入字面量 `\n` 序列。来自渠道的群组名称和参与者标签会以围栏形式呈现为不受信任的元数据,而不是内联系统指令。
## iMessage 细节
- 路由或加入允许列表时优先使用 `chat_id:<id>`
- 路由或加入允许列表时优先使用 `chat_id:<id>`
- 列出聊天:`imsg chats --limit 20`。
- 群组回复始终回同一个 `chat_id`
- 群组回复始终回同一个 `chat_id`
## WhatsApp 系统提示
## WhatsApp 系统提示
请参阅 [WhatsApp](/zh-CN/channels/whatsapp#system-prompts),了解规范的 WhatsApp 系统提示规则,包括群组和直接提示解析、通配符行为以及账号覆盖语义。
请参阅 [WhatsApp](/zh-CN/channels/whatsapp#system-prompts),了解规范的 WhatsApp 系统提示规则,包括群组和直接提示解析、通配符行为以及账号覆盖语义。
## WhatsApp 细节
请参阅[群组消息](/zh-CN/channels/group-messages),了解 WhatsApp 专属行为(历史注入、提及处理细节)。
请参阅 [群组消息](/zh-CN/channels/group-messages),了解仅限 WhatsApp 的行为(历史注入、提及处理细节)。
## 相关

View File

@ -1,75 +1,75 @@
---
read_when:
- 你需要了解某个 CI 作业为什么运行或未运行
- 你正在调试一失败的 GitHub Actions 检查
- 你正在协调一次发布验证运行或重新运行
summary: CI 作业图、范围门禁、发布总括项和本地命令等价项
- 你需要了解 CI 作业为什么运行或未运行
- 你正在调试一失败的 GitHub Actions 检查
- 你正在协调发布验证的一次运行或重新运行
summary: CI 作业图、范围门控、发布总括和本地命令等价项
title: CI 流水线
x-i18n:
generated_at: "2026-05-01T02:24:10Z"
generated_at: "2026-05-01T03:00:03Z"
model: gpt-5.5
provider: openai
source_hash: 0c2ee36f96ccf86d4adb739f5f7efb82c05f733e7693571ce391269d2538fec7
source_hash: aea06f9f336f9a478a284473b5c5f38730b87837b1acb0390161bf2c455f6c41
source_path: ci.md
workflow: 16
---
OpenClaw CI 会在每次推送到 `main` 以及每个拉取请求时运行。`preflight` 作业会分类差异,并在只有无关区域发生变化时关闭昂贵的执行通道。手动 `workflow_dispatch` 运行会有意绕过智能作用域划分并为候选版本和广泛验证展开完整图。Android 通道通过 `include_android` 保持可选启用。仅发布用的插件覆盖率位于单独的 [`Plugin Prerelease`](#plugin-prerelease) 工作流中,并且只会从 [`Full Release Validation`](#full-release-validation) 或显式手动分发运行。
OpenClaw CI 会在每次推送到 `main` 以及每个拉取请求时运行。`preflight` 作业会分类差异,并在只有无关区域发生变更时关闭高成本通道。手动 `workflow_dispatch` 运行会有意绕过智能作用域划分,并为发布候选版本和广泛验证展开完整图。Android 通道通过 `include_android` 保持选择性启用。仅发布使用的插件覆盖位于单独的 [`插件预发布`](#plugin-prerelease) 工作流中,并且只会从 [`完整发布验证`](#full-release-validation) 或显式手动触发运行。
## 流水线概览
| 作业 | 用途 | 运行时机 |
| 作业 | 目的 | 运行时机 |
| -------------------------------- | -------------------------------------------------------------------------------------------- | ---------------------------------- |
| `preflight` | 检测仅文档变更、变更作用域、变更插件,并构建 CI 清单 | 始终在非草稿推送和 PR 上运行 |
| `security-scm-fast` | 通过 `zizmor` 进行私钥检测和工作流审计 | 始终在非草稿推送和 PR 上运行 |
| `security-dependency-audit` | 针对 npm 公告进行无依赖的生产锁文件审计 | 始终在非草稿推送和 PR 上运行 |
| `security-fast` | 快速安全作业所需的聚合 | 始终在非草稿推送和 PR 上运行 |
| `check-dependencies` | 生产 Knip 仅依赖检查,加上未使用文件允许列表防护 | Node 相关变更 |
| `build-artifacts` | 构建 `dist/`、Control UI、构建产物检查以及可复用的下游产物 | Node 相关变更 |
| `checks-fast-core` | 快速 Linux 正确性通道,例如内置/插件契约/协议检查 | Node 相关变更 |
| `checks-fast-contracts-channels` | 分片渠道契约检查,并提供稳定的聚合检查结果 | Node 相关变更 |
| `checks-node-core-test` | Core Node 测试分片,不包括渠道、内置、契约和插件通道 | Node 相关变更 |
| `check` | 分片的主要本地门禁等价项生产类型、lint、防护、测试类型和严格冒烟 | Node 相关变更 |
| `check-additional` | 架构、边界、插件表面防护、包边界和 Gateway 网关 watch 分片 | Node 相关变更 |
| `build-smoke` | 已构建 CLI 冒烟测试和启动内存冒烟 | Node 相关变更 |
| `checks` | 构建产物渠道测试的验证器 | Node 相关变更 |
| `checks-node-compat-node22` | Node 22 兼容性构建和冒烟通道 | 用于发布的手动 CI 分发 |
| `check-docs` | 文档格式、lint 和断链检查 | 文档变更 |
| `skills-python` | 面向 Python 支撑的 Skills 的 Ruff + pytest | Python Skill 相关变更 |
| `checks-windows` | Windows 专用进程/路径测试,加上共享运行时导入说明符回归 | Windows 相关变更 |
| `macos-node` | 使用共享构建产物的 macOS TypeScript 测试通道 | macOS 相关变更 |
| `macos-swift` | macOS 应用的 Swift lint、构建和测试 | macOS 相关变更 |
| `android` | 两种 flavor 的 Android 单元测试,加上一次调试 APK 构建 | Android 相关变更 |
| `test-performance-agent` | 受信任活动后的每日 Codex 慢测试优化 | 主 CI 成功或手动分发 |
| `preflight` | 检测仅文档变更、变更作用域、变更插件,并构建 CI 清单 | 始终在非草稿推送和 PR 上运行 |
| `security-scm-fast` | 通过 `zizmor` 检测私钥并审计工作流 | 始终在非草稿推送和 PR 上运行 |
| `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` | 构建产物渠道测试的验证器 | Node 相关变更 |
| `checks-node-compat-node22` | Node 22 兼容性构建和 smoke 通道 | 发布的手动 CI 触发 |
| `check-docs` | 文档格式、lint 和断链检查 | 文档变更 |
| `skills-python` | 针对 Python 支持的 Skills 执行 Ruff + pytest | Python Skills 相关变更 |
| `checks-windows` | Windows 特定的进程/路径测试,以及共享运行时导入说明符回归测试 | Windows 相关变更 |
| `macos-node` | 使用共享构建产物的 macOS TypeScript 测试通道 | macOS 相关变更 |
| `macos-swift` | macOS 应用的 Swift lint、构建和测试 | macOS 相关变更 |
| `android` | 两种 flavor 的 Android 单元测试,以及一次 debug APK 构建 | Android 相关变更 |
| `test-performance-agent` | 可信活动后每日进行的 Codex 慢测试优化 | 主 CI 成功或手动触发 |
## 快速失败顺序
1. `preflight` 决定哪些通道实际存在。`docs-scope` 和 `changed-scope` 逻辑是此作业中的步骤,而不是独立作业。
2. `security-scm-fast`、`security-dependency-audit`、`security-fast`、`check`、`check-additional`、`check-docs` 和 `skills-python` 会快速失败,不等待更重的产物和平台矩阵作业。
3. `build-artifacts` 会与快速 Linux 通道重叠运行,以便共享构建就绪后下游消费者可以立即开始。
1. `preflight` 决定哪些通道实际存在。`docs-scope` 和 `changed-scope` 逻辑是此作业内的步骤,不是独立作业。
2. `security-scm-fast`、`security-dependency-audit`、`security-fast`、`check`、`check-additional`、`check-docs` 和 `skills-python` 会快速失败,不等待更重的产物和平台矩阵作业。
3. `build-artifacts` 会与快速 Linux 通道重叠运行,使下游消费者可以在共享构建就绪后立即开始。
4. 更重的平台和运行时通道随后展开:`checks-fast-core`、`checks-fast-contracts-channels`、`checks-node-core-test`、`checks`、`checks-windows`、`macos-node`、`macos-swift` 和 `android`
较新的推送落在同一个 PR 或 `main` ref 上时GitHub 可能会将被取代的作业标记为 `cancelled`。除非同一 ref 的最新运行也失败,否则将其视为 CI 噪声。聚合分片检查使用 `!cancelled() && always()`,因此它们仍会报告正常的分片失败,但不会在整个工作流已经被取代后继续排队。自动 CI 并发键带有版本号(`CI-v7-*`),因此 GitHub 侧旧队列组中的僵尸项无法无限阻塞新的 main 运行。手动完整套件运行使用 `CI-manual-v1-*`,并且不会取消正在进行的运行。
当同一个 PR 或 `main` ref 上有更新推送落地GitHub 可能会将被取代的作业标记为 `cancelled`。除非同一 ref 的最新运行也失败,否则将其视为 CI 噪声。聚合分片检查使用 `!cancelled() && always()`,因此它们仍会报告正常的分片失败,但不会在整个工作流已经被取代后继续排队。自动 CI 并发键带有版本号(`CI-v7-*`),因此 GitHub 端旧队列组中的僵尸运行无法无限期阻塞新的 main 运行。手动完整套件运行使用 `CI-manual-v1-*`,并且不会取消正在进行的运行。
## 作用域路由
## 作用域路由
作用域逻辑位于 `scripts/ci-changed-scope.mjs`,并由 `src/scripts/ci-changed-scope.test.ts` 中的单元测试覆盖。手动发会跳过变更作用域检测,并让 preflight 清单表现得像每个有作用域的区域都发生了变
作用域逻辑位于 `scripts/ci-changed-scope.mjs`,并由 `src/scripts/ci-changed-scope.test.ts` 中的单元测试覆盖。手动发会跳过变更作用域检测,并让 preflight 清单表现得像每个有作用域的区域都发生了变
- **CI 工作流编辑**会验证 Node CI 图和工作流 linting,但不会单独强制 Windows、Android 或 macOS 原生构建;这些平台通道仍限定为平台源代码变更。
- **仅 CI 路由编辑、选定的低成本核心测试 fixture 编辑,以及窄范围插件契约 helper/测试路由编辑**使用快速的仅 Node 清单路径:`preflight`、security以及`checks-fast-core` 任务。当变更仅限于该快速任务直接覆盖的路由或 helper 表面时,路径会跳过构建产物、Node 22 兼容性、渠道契约、完整核心分片、内置插件分片和额外护矩阵。
- **Windows Node 检查**限定于 Windows 专用进程/路径包装器、npm/pnpm/UI 运行器 helper、包管理器配置以及执行该通道的 CI 工作流表面;无关源代码、插件、安装冒烟和仅测试变更仍停留在 Linux Node 通道上。
- **CI 工作流编辑**会验证 Node CI 图和工作流 lint本身不会强制运行 Windows、Android 或 macOS 原生构建;这些平台通道仍然限定于平台源代码变更。
- **仅 CI 路由编辑、选定的低成本核心测试 fixture 编辑,以及窄范围插件契约 helper/测试路由编辑**使用快速的仅 Node 清单路径:`preflight`、security以及`checks-fast-core` 任务。当变更仅限于该快速任务直接覆盖的路由或 helper 表面时,路径会跳过构建产物、Node 22 兼容性、渠道契约、完整核心分片、内置插件分片和额外护矩阵。
- **Windows Node 检查**限定于 Windows 特定的进程/路径 wrapper、npm/pnpm/UI runner helper、包管理器配置以及执行该通道的 CI 工作流表面;无关源代码、插件、install-smoke 和仅测试变更仍留在 Linux Node 通道上。
最慢的 Node 测试族会被拆分或平衡,使每个作业保持较小规模且不过度预留运行器渠道契约作为三个加权分片运行小型核心单元通道会配对auto-reply 作为四个均衡 worker 运行reply 子树拆分为 agent-runner、dispatch 和 commands/state-routing 分片),agentic gateway/插件配置则分散到现有的仅源代码 agentic Node 作业中,而不是等待构建产物。广泛的浏览器、QA、媒体和杂项插件测试使用其专用 Vitest 配置,而不是共享插件兜底项。include-pattern 分片使用 CI 分片名称记录计时条目,因此 `.artifacts/vitest-shard-timings.json` 可以区分整个配置和过滤后的分片。`check-additional` 将包边界编译/canary 工作保持在一起,并将运行时拓扑架构与 Gateway 网关 watch 覆盖分离边界防护分片会在一个作业内并发运行其小型独立防护。Gateway 网关 watch、渠道测试和核心支持边界分片会在 `dist/``dist-runtime/`构建完成后,在 `build-artifacts` 内并发运行。
最慢的 Node 测试族会被拆分或均衡,使每个作业保持较小规模且不过度预留 runner:渠道契约作为三个加权分片运行,小型核心单元通道会配对运行auto-reply 作为四个均衡 worker 运行reply 子树拆分为 agent-runner、dispatch 和 commands/state-routing 分片),而 agentic gateway/plugin 配置分布在现有仅源代码的 agentic Node 作业中,而不是等待构建产物。宽泛的浏览器、QA、媒体和杂项插件测试使用其专用 Vitest 配置,而不是共享插件 catch-all。include-pattern 分片会使用 CI 分片名称记录计时条目,因此 `.artifacts/vitest-shard-timings.json` 可以区分整个配置和过滤后的分片。`check-additional` 将包边界编译/canary 工作放在一起,并将运行时拓扑架构与 gateway watch 覆盖分开边界保护分片会在一个作业内并发运行其小型独立保护。Gateway watch、渠道测试和核心 support-boundary 分片会在 `dist/``dist-runtime/` 已构建完成后,在 `build-artifacts` 内并发运行。
Android CI 会同时运行 `testPlayDebugUnitTest``testThirdPartyDebugUnitTest`,然后构建 Play 调试 APK。第三方 flavor 没有单独的源码集或清单;其单元测试通道仍会使用 SMS/call-log BuildConfig 标志编译该 flavor同时避免在每次 Android 相关推送中重复执行调试 APK 打包作业。
Android CI 会同时运行 `testPlayDebugUnitTest``testThirdPartyDebugUnitTest`,然后构建 Play debug APK。third-party flavor 没有单独的 source set 或 manifest它的单元测试通道仍会使用 SMS/call-log BuildConfig 标志编译该 flavor同时避免在每个 Android 相关推送上重复执行 debug APK 打包作业。
`check-dependencies` 分片运行 `pnpm deadcode:dependencies`生产 Knip 仅依赖检查,固定到最新 Knip 版本,并为 `dlx` 安装禁用 pnpm 的最低发布时间限制)和 `pnpm deadcode:unused-files`,后者会将 Knip 的生产未使用文件发现结果`scripts/deadcode-unused-files.allowlist.mjs` 进行比较。当 PR 新增未经审查的未使用文件或留下过期的允许列表条目时,未使用文件防护会失败,同时保留 Knip 无法静态解析的有意动态插件、生成内容、构建、实时测试和包桥接表面。
`check-dependencies` 分片运行 `pnpm deadcode:dependencies`一个仅依赖项的生产 Knip 检查,固定到最新 Knip 版本,并在 `dlx` 安装时禁用 pnpm 的最小发布时间限制)和 `pnpm deadcode:unused-files`,后者会将 Knip 的生产未使用文件发现与 `scripts/deadcode-unused-files.allowlist.mjs` 进行比较。当 PR 添加新的未经审查未使用文件或留下过期允许列表条目时,未使用文件保护会失败,同时保留 Knip 无法静态解析的有意动态插件、生成内容、构建内容、实时测试以及包桥接表面。
## 手动
## 手动
手动 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` 以启用 release-validation 门禁的方式分发单独的 `Plugin Prerelease` 工作流时运行。
手动 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` 分片、完整插件批量 sweep以及插件预发布 Docker 通道都排除在 CI 之外。Docker 预发布套件只会在 `完整发布验证` 以启用 release-validation 门禁的方式触发单独的 `插件预发布` 工作流时运行。
手动运行使用唯一并发组,因此候选版本完整套件不会被同一 ref 上的另一个推送或 PR 运行取消。可选的 `target_ref` 输入允许受信任调用方针对分支、标签或完整提交 SHA 运行该图,同时使用所选分发 ref 中的工作流文件。
手动运行使用唯一的并发组,因此发布候选完整套件不会被同一 ref 上的另一次推送或 PR 运行取消。可选的 `target_ref` 输入允许可信调用方针对某个分支、标签或完整提交 SHA 运行该图,同时使用所选触发 ref 中的工作流文件。
```bash
gh workflow run ci.yml --ref release/YYYY.M.D
@ -77,19 +77,19 @@ gh workflow run ci.yml --ref main -f target_ref=<branch-or-sha> -f include_andro
gh workflow run full-release-validation.yml --ref main -f ref=<branch-or-sha>
```
## 运行器
## Runner
| 运行器 | 作业 |
| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ubuntu-24.04` | `preflight`、快速安全作业和聚合作业`security-scm-fast`、`security-dependency-audit`、`security-fast`)、快速协议/契约/内置检查、分片渠道契约检查、除 lint 以外的 `check` 分片、`check-additional` 分片和聚合作业、Node 测试聚合验证器、文档检查、Python Skills、workflow-sanity、labeler、auto-responseinstall-smoke 预检也使用 GitHub 托管的 Ubuntu这样 Blacksmith 矩阵可以更早排队 |
| `ubuntu-24.04` | `preflight`、快速安全作业和聚合`security-scm-fast`、`security-dependency-audit`、`security-fast`)、快速协议/契约/内置检查、分片渠道契约检查、除 lint 之外的 `check` 分片、`check-additional` 分片和聚合项、Node 测试聚合验证器、文档检查、Python Skills、workflow-sanity、labeler、auto-responseinstall-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`分叉仓库回退到 `macos-latest` |
| `blacksmith-12vcpu-macos-latest` | `openclaw/openclaw` 上的 `macos-swift`分叉仓库回退到 `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
@ -117,27 +117,27 @@ pnpm test:perf:groups:compare .artifacts/test-perf/baseline-before.json .artifac
## 完整发布验证
`Full Release Validation` 是“发布前运行所有内容”的手动总控工作流。它接受分支、标签或完整提交 SHA使用该目标调度手动 `CI` 工作流,调度 `Plugin Prerelease` 以提供仅发布所需的插件/软件包/静态/Docker 证明,并调度 `OpenClaw Release Checks` 以执行安装冒烟、软件包验收、Docker 发布路径套件、live/E2E、OpenWebUI、QA Lab parity、Matrix 和 Telegram 通道。提供已发布的软件包规格时,它还可以运行发布后的 `NPM Telegram Beta E2E` 工作流。
`Full Release Validation` 是“发布前运行所有内容”的手动总控工作流。它接受分支、标签或完整提交 SHA使用该目标分派手动 `CI` 工作流,分派 `Plugin Prerelease` 以进行仅发布所需的插件/包/静态/Docker 验证,并分派 `OpenClaw Release Checks` 以运行安装冒烟、包验收、Docker 发布路径套件、live/E2E、OpenWebUI、QA Lab parity、Matrix 和 Telegram 通道。提供已发布包规格时,它还可以运行发布后的 `NPM Telegram Beta E2E` 工作流。
参见[完整发布验证](/zh-CN/reference/full-release-validation),了解阶段矩阵、精确的工作流作业名称、配置差异、构件和聚焦重跑句柄
有关阶段矩阵、精确工作流作业名称、配置文件差异、构件和聚焦重跑句柄,请参阅[完整发布验证](/zh-CN/reference/full-release-validation)。
`release_profile` 控制传发布检查的 live/提供商覆盖范围。手动发布工作流默认使用 `stable`;仅在你明确需要宽泛的建议性提供商/媒体矩阵时才使用 `full`
`release_profile` 控制传递到发布检查的 live/提供商覆盖范围。手动发布工作流默认使用 `stable`;仅在你有意需要广泛的 advisory 提供商/媒体矩阵时才使用 `full`
- `minimum` 保留最快的 OpenAI/核心发布关键通道。
- `stable` 添加稳定的提供商/后端集合。
- `full` 运行宽泛的建议性提供商/媒体矩阵。
- `full` 运行广泛的 advisory 提供商/媒体矩阵。
总控会记录已调度的子运行 ID最终的 `Verify full validation` 作业会重新检查当前子运行结论,并为每个子运行追加最慢作业表。如果某个子工作流重跑后变绿,只需重跑父验证器作业刷新总控结果和耗时摘要。
总控工作流会记录已分派的子运行 ID最终的 `Verify full validation` 作业会重新检查当前子运行结论,并为每个子运行追加最慢作业表。如果子工作流重跑后变绿,只需重跑父验证器作业即可刷新总控结果和耗时摘要。
对于恢复,`Full Release Validation` 和 `OpenClaw Release Checks` 都接受 `rerun_group`发布候选版使用 `all`,仅普通完整 CI 子项使用 `ci`,仅插件预发布子项使用 `plugin-prerelease`,每个发布子项使用 `release-checks`,或在总控上使用更窄的组:`install-smoke`、`cross-os`、`live-e2e`、`package`、`qa`、`qa-parity`、`qa-live` 或 `npm-telegram`。这样在聚焦修复后,失败的发布盒子重跑可以保持有界
恢复`Full Release Validation` 和 `OpenClaw Release Checks` 都接受 `rerun_group`对发布候选使用 `all`,仅普通完整 CI 子工作流使用 `ci`,仅插件预发布子工作流使用 `plugin-prerelease`,所有发布子工作流使用 `release-checks`,或者在总控中使用更窄的组:`install-smoke`、`cross-os`、`live-e2e`、`package`、`qa`、`qa-parity`、`qa-live` 或 `npm-telegram`。这样,在聚焦修复后可以将失败发布箱的重跑范围保持受限
`OpenClaw Release Checks` 使用受信任的工作流 ref选 ref 一次解析为 `release-package-under-test` tarball然后将该构件传给 live/E2E 发布路径 Docker 工作流和软件包验收分片。这会让各发布盒子使用一致的软件包字节,并避免在多个子作业中重新打包同一个候选项
`OpenClaw Release Checks` 使用受信任的工作流 ref将选 ref 一次解析为 `release-package-under-test` tarball然后把该构件传递给 live/E2E 发布路径 Docker 工作流和包验收分片。这样可以让发布箱之间的包字节保持一致,并避免在多个子作业中重新打包同一个候选版本
针对 `ref=main` `rerun_group=all` 的重复 `Full Release Validation` 运行会取代较旧的总控。父监视器在父项被取消时,会取消它已经调度的任何子工作流,因此较新的 main 验证不会排在陈旧的两小时发布检查运行后面。发布分支/标签验证和聚焦重跑组保持 `cancel-in-progress: false`
`ref=main` `rerun_group=all` 的重复 `Full Release Validation` 运行会取代较旧的总控运行。父监视器在父运行被取消时,会取消它已分派的任何子工作流,因此较新的 main 验证不会排在一个过期的两小时发布检查运行之后。发布分支/标签验证和聚焦重跑组保持 `cancel-in-progress: false`
## Live 和 E2E 分片
发布 live/E2E 子项保留宽泛的原生 `pnpm test:live` 覆盖范围,但它通过 `scripts/test-live-shard.mjs` 以命名分片运行,而不是一个串行作业
发布 live/E2E 子工作流保留广泛的原生 `pnpm test:live` 覆盖范围,但它通过 `scripts/test-live-shard.mjs` 作为具名分片运行,而不是作为一个串行作业运行
- `native-live-src-agents`
- `native-live-src-gateway-core`
@ -151,33 +151,33 @@ pnpm test:perf:groups:compare .artifacts/test-perf/baseline-before.json .artifac
- `native-live-extensions-xai`
- 拆分的媒体音频/视频分片和提供商过滤的音乐分片
样在保持相同文件覆盖范围的同时,也让缓慢的 live 提供商失败更容易重跑和诊断。聚合 `native-live-extensions-o-z`、`native-live-extensions-media` 和 `native-live-extensions-media-music` 分片名称仍可用于手动一次性重跑。
会保持相同的文件覆盖范围,同时让缓慢的 live 提供商失败更容易重跑和诊断。聚合 `native-live-extensions-o-z`、`native-live-extensions-media` 和 `native-live-extensions-media-music` 分片名称仍可用于手动一次性重跑。
原生 live 媒体分片在 `ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04` 中运行,该镜像由 `Live Media Runner Image` 工作流构建。该镜像预装 `ffmpeg``ffprobe`;媒体作业只会在设置前验证这些二进制文件。将 Docker 支持的 live 套件保留在普通 Blacksmith 运行器上,容器作业不是启动嵌套 Docker 测试的合适位置
原生 live 媒体分片在 `ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04` 中运行,该镜像由 `Live Media Runner Image` 工作流构建。该镜像预装 `ffmpeg``ffprobe`;媒体作业只会在设置前验证二进制文件。将 Docker 支持的 live 套件保留在普通 Blacksmith 运行器上,容器作业不适合启动嵌套 Docker 测试
Docker 支持的 live 模型/后端分片会为每个选提交使用单独的共享 `ghcr.io/openclaw/openclaw-live-test:<sha>` 镜像。live 发布工作流构建并推送该镜像一次,然后 Docker live 模型、按提供商分片的 Gateway 网关、CLI 后端、ACP bind 和 Codex harness 分片会使用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行。Gateway 网关 Docker 分片带显式脚本级 `timeout` 上限,低于工作流作业超时,因此卡住的容器或清理路径会快速失败,而不是消耗整个发布检查预算。如果这些分片独立重建完整源码 Docker 目标,则说明发布运行配置错误,并会在重复镜像构建上浪费实际时间
Docker 支持的 live 模型/后端分片会为每个选提交使用单独的共享 `ghcr.io/openclaw/openclaw-live-test:<sha>` 镜像。live 发布工作流构建并推送该镜像一次,然后 Docker live 模型、按提供商分片的 Gateway 网关、CLI 后端、ACP bind 和 Codex harness 分片会使用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行。Gateway 网关 Docker 分片带显式脚本级 `timeout` 上限,低于工作流作业超时,因此卡住的容器或清理路径会快速失败,而不是消耗整个发布检查预算。如果这些分片独立重建完整源 Docker 目标,则表示发布运行配置错误,并会把挂钟时间浪费在重复镜像构建上
## 软件包验收
## 包验收
当问题是“这个可安装的 OpenClaw 软件包作为产品是否可用?”时,使用 `Package Acceptance`。它不同于普通 CI普通 CI 验证源码树,而软件包验收通过用户安装或更新后会执行的同一套 Docker E2E harness 来验证单个 tarball。
当问题是“这个可安装的 OpenClaw 包作为产品是否可用?”时,使用 `Package Acceptance`。它不同于普通 CI普通 CI 验证源代码树,而包验收会通过用户在安装或更新后执行的同一个 Docker E2E harness 来验证单个 tarball。
### 作业
1. `resolve_package` 检出 `workflow_ref`,解析一个包候选项,写入 `.artifacts/docker-e2e-package/openclaw-current.tgz`,写入 `.artifacts/docker-e2e-package/package-candidate.json`,将两者作为 `package-under-test` 工件上传,并在 GitHub 步骤摘要中打印源、工作流 ref、包 ref、版本、SHA-256 和 profile
2. `docker_acceptance` 会以 `ref=workflow_ref``package_artifact_name=package-under-test` 调用 `openclaw-live-and-e2e-checks-reusable.yml`。可复用工作流会下载该工件,验证 tarball 清单,在需要时准备 package-digest Docker 镜像,并针对该包运行选定的 Docker lane而不是打包工作流检出内容。当某个 profile 选择了多个目标 `docker_lanes` 时,可复用工作流会准备一次包和共享镜像,然后将这些 lane 扇出为并行的目标 Docker 作业,并使用唯一工件。
3. `package_telegram` 可选调用 `NPM Telegram Beta E2E`。当 `telegram_mode` 不是 `none`它会运行;如果包验收已解析出一个包,它会安装同一个 `package-under-test` 工件;独立的 Telegram 分发仍可安装已发布的 npm spec
4. 如果包解析、Docker 验收或可选 Telegram lane 失败,`summary` 会使工作流失败。
1. `resolve_package` 检出 `workflow_ref`,解析一个包候选项,写入 `.artifacts/docker-e2e-package/openclaw-current.tgz`,写入 `.artifacts/docker-e2e-package/package-candidate.json`,将两者作为 `package-under-test` 工件上传,并在 GitHub 步骤摘要中打印源、工作流 ref、包 ref、版本、SHA-256 和配置档
2. `docker_acceptance` 使用 `ref=workflow_ref``package_artifact_name=package-under-test` 调用 `openclaw-live-and-e2e-checks-reusable.yml`。可复用工作流会下载该工件,验证 tarball 清单,在需要时准备 package-digest Docker 镜像,并针对该包运行所选 Docker lane而不是打包工作流检出的内容。当某个配置档选择多个定向 `docker_lanes` 时,可复用工作流会准备一次包和共享镜像,然后将这些 lane 扇出为并行的定向 Docker 作业,并使用唯一工件。
3. `package_telegram` 可选调用 `NPM Telegram Beta E2E`。当 `telegram_mode` 不是 `none`运行;如果 Package Acceptance 解析出了 `package-under-test` 工件,它会安装同一个工件;独立 Telegram 调度仍可安装已发布的 npm 规格
4. 如果包解析、Docker acceptance 或可选 Telegram lane 失败,`summary` 会使工作流失败。
### 候选
### 候选源
- `source=npm` 接受 `openclaw@beta`、`openclaw@latest`,或精确的 OpenClaw 发布版本,例如 `openclaw@2026.4.27-beta.2`。将用于已发布 beta/稳定版验收。
- `source=ref` 会打包受信任的 `package_ref` 分支、标签或完整 commit SHA。解析器会获取 OpenClaw 分支/标签,验证所选 commit 可从仓库分支历史或发布标签到达,在分离 worktree 中安装依赖,并用 `scripts/package-openclaw-for-docker.mjs` 打包。
- `source=url` 会下载 HTTPS `.tgz`;必须提供 `package_sha256`
- `source=artifact` `artifact_run_id``artifact_name` 下载一个 `.tgz``package_sha256` 可选,但对于外部共享工件应提供。
- `source=npm` 接受 `openclaw@beta`、`openclaw@latest`,或精确的 OpenClaw 发布版本,例如 `openclaw@2026.4.27-beta.2`。将用于已发布 beta/稳定版验收。
- `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` 可选,但对于外部共享工件应提供。
请将 `workflow_ref``package_ref` 分开。`workflow_ref` 是运行测试的受信任工作流/harness 代码。`package_ref` 是在 `source=ref` 时被打包的源 commit。这样当前测试 harness 就能验证较旧的受信任源 commit而无需运行旧的工作流逻辑。
保持 `workflow_ref``package_ref` 分离。`workflow_ref` 是运行测试的受信任工作流/测试框架代码。`package_ref` 是 `source=ref` 时被打包的源提交。这让当前测试框架可以验证较早的受信任源提交,而无需运行旧工作流逻辑。
### 套件 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`、`bundled-channel-deps-compat`、`plugins-offline`、`plugin-update`
@ -185,21 +185,21 @@ Docker 支持的 live 模型/后端分片会为每个所选提交使用单独的
- `full` — 带 OpenWebUI 的完整 Docker 发布路径分块
- `custom` — 精确的 `docker_lanes`;当 `suite_profile=custom` 时必填
`package` profile 使用离线插件覆盖,因此已发布包验证不会被实时 ClawHub 可用性阻塞。可选 Telegram lane 会在 `NPM Telegram Beta E2E` 中复用 `package-under-test` 工件,同时为独立分发保留已发布 npm spec 路径。
`package` 配置档使用离线插件覆盖,因此已发布包验证不会受实时 ClawHub 可用性约束。可选 Telegram lane 在 `NPM Telegram Beta E2E` 中复用 `package-under-test` 工件,并为独立调度保留已发布 npm 规格路径。
发布检查会以 `source=ref`、`package_ref=<release-ref>`、`workflow_ref=<release workflow ref>`、`suite_profile=custom`、`docker_lanes='bundled-channel-deps-compat plugins-offline'` 和 `telegram_mode=mock-openai` 调用包验收。发布路径 Docker 分块会覆盖重叠的包/更新/插件 lane包验收则针对同一个已解析包 tarball 保留原生工件的内置渠道兼容、离线插件和 Telegram 证明。跨 OS 发布检查仍会覆盖特定于 OS 的新手引导、安装器和平台行为;包/更新产品验证应从包验收开始。Windows 打包版和安装器全新 lane 还会验证已安装包可以从原始 Windows 绝对路径导入 browser-control override。OpenAI 跨 OS 智能体回合 smoke 在设置时默认使用 `OPENCLAW_CROSS_OS_OPENAI_MODEL`,否则使用 `openai/gpt-5.4-mini`,因此安装和 Gateway 网关证保持快速且确定。
发布检查使用 `source=ref`、`package_ref=<release-ref>`、`workflow_ref=<release workflow ref>`、`suite_profile=custom`、`docker_lanes='bundled-channel-deps-compat plugins-offline'` 和 `telegram_mode=mock-openai` 调用 Package Acceptance。发布路径 Docker 分块覆盖重叠的 package/update/plugin lanePackage Acceptance 保留基于同一已解析包 tarball 的工件原生内置渠道兼容性、离线插件和 Telegram 验证。跨 OS 发布检查仍覆盖特定 OS 的新手引导、安装器和平台行为package/update 产品验证应从 Package Acceptance 开始。`published-upgrade-survivor` Docker lane 每次运行验证一个已发布包基线。在 Package Acceptance 中,已解析的 `package-under-test` tarball 始终是候选项,而 `published_upgrade_survivor_baseline` 选择已发布基线,默认值为 `openclaw@latest`;失败 lane 的重跑命令会保留该基线。本地运行可以将 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPEC` 设置为精确包,例如 `openclaw@2026.4.15`。已发布 lane 使用预置的 `openclaw config set` 命令配方配置基线,然后在 `summary.json` 中记录配方步骤。更广泛的旧版本覆盖应按精确的 `published_upgrade_survivor_baseline` 值对 Package Acceptance 分片。Windows 打包和安装器全新 lane 还会验证已安装包可以从原始绝对 Windows 路径导入 browser-control 覆盖。OpenAI 跨 OS agent-turn smoke 在设置时默认使用 `OPENCLAW_CROSS_OS_OPENAI_MODEL`,否则使用 `openai/gpt-5.4-mini`,因此安装和 Gateway 网关证保持快速且确定
### 旧版兼容窗口
包验收为已发布包提供有界的旧版兼容窗口。直到 `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` 可以跳过持久化子用例;
- `update-channel-switch` 可以从 tarball 派生的 fake git fixture 中剪除缺失的 `pnpm.patchedDependencies`,并可记录缺失的持久化 `update.channel`
- 插件 smoke 可以读取旧版安装记录位置,或接受缺 marketplace 安装记录持久化;
- `plugin-update` 可以允许配置元数据迁移,同时仍要求安装记录和重新安装行为保持不变。
- `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` 可以允许配置元数据迁移,同时仍要求安装记录和重新安装行为保持不变。
已发布的 `2026.4.26` 包也可能对已发货的本地构建元数据 stamp 文件发出警告。后续包必须满足现代契约;相同条件会失败,而不是警告或跳过。
已发布的 `2026.4.26` 包也可以对已经发布的本地构建元数据标记文件发出警告。后续包必须满足现代契约;相同条件会失败,而不是警告或跳过。
### 示例
@ -242,111 +242,111 @@ 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 日志、阶段计时和重运行命令。优先重运行失败的包 profile 或精确 Docker lane而不是重运行完整发布验证。
调试失败的包验收运行时,先查看 `resolve_package` 摘要,以确认包源、版本和 SHA-256。然后检查 `docker_acceptance` 子运行及其 Docker 工件:`.artifacts/docker-tests/**/summary.json`、`failures.json`、lane 日志、阶段耗时和重跑命令。优先重跑失败的包配置档或精确的 Docker lane而不是重跑完整发布验证。
## 安装 smoke
`Install Smoke` 工作流通过自己的 `preflight` 作业复用同一个范围脚本。它将 smoke 覆盖拆分为 `run_fast_install_smoke``run_full_install_smoke`
独的 `Install Smoke` 工作流通过自己的 `preflight` 作业复用同一个范围脚本。它将 smoke 覆盖拆分为 `run_fast_install_smoke``run_full_install_smoke`
- **快速路径**会在拉取请求触及 Docker/包表面、内置插件包/manifest 变更,或 Docker smoke 作业会执行的核心插件/渠道/Gateway 网关/插件 SDK 表面时运行。仅源码的内置插件变更、仅测试编辑和仅文档编辑不会预留 Docker worker。快速路径会构建一次根 Dockerfile 镜像,检查 CLI运行智能体删除共享工作区 CLI smoke运行容器 `gateway-network` e2e验证内置扩展构建参数并在 240 秒聚合命令超时下运行有界的内置插件 Docker profile每个场景的 Docker 运行单独设置上限)。
- **完整路径**会为夜间定时运行、手动分发、workflow-call 发布检查,以及确实触及安装器/包/Docker 表面的拉取请求保留 QR 包安装和安装器 Docker/更新覆盖。在完整模式下install-smoke 会准备或复用一个目标 SHA 的 GHCR 根 Dockerfile smoke 镜像,然后将 QR 包安装、根 Dockerfile/Gateway 网关 smoke、安装器/更新 smoke以及快速内置插件 Docker E2E 作为独立作业运行,这样安装器工作不会排在根镜像 smoke 之后等待
- **快速路径**会在 pull request 触及 Docker/包表面、内置插件包/manifest 变更,或 Docker smoke 作业会覆盖的核心插件/渠道/Gateway 网关/插件 SDK 表面时运行。仅源码的内置插件变更、仅测试编辑和仅文档编辑不会占用 Docker worker。快速路径会构建一次根 Dockerfile 镜像,检查 CLI运行 agents delete shared-workspace CLI smoke运行容器 gateway-network e2e验证内置扩展构建参数并在 240 秒聚合命令超时内运行有界的 bundled-plugin Docker 配置档(每个场景的 Docker 运行分别设置上限)。
- **完整路径**保留 QR 包安装以及安装器 Docker/update 覆盖用于夜间计划运行、手动调度、workflow-call 发布检查,以及真正触及安装器/包/Docker 表面的 pull request。在完整模式下install-smoke 会准备或复用一个目标 SHA 的 GHCR 根 Dockerfile smoke 镜像,然后将 QR 包安装、根 Dockerfile/Gateway 网关 smoke、安装器/update smoke以及快速 bundled-plugin Docker E2E 作为独立作业运行,使安装器工作无需等待根镜像 smoke
`main` 推送(包括 merge commit不会强制走完整路径;当变更范围逻辑会在推送上请求完整覆盖时,工作流会保留快速 Docker smoke把完整安装 smoke 留给夜间或发布验证。
`main` 推送(包括合并提交)不会强制完整路径;当变更范围逻辑会在推送上请求完整覆盖时,工作流会保留快速 Docker smoke将完整 install smoke 留给夜间或发布验证。
较慢的 Bun 全局安装 image-provider smoke 由 `run_bun_global_install_smoke` 单独控。它会在夜间计划和发布检查工作流中运行,手动 `Install Smoke` 分发可以选择启用它,但拉取请求和 `main` 推送不会运行。QR 和安装器 Docker 测试保留各自以安装为重点的 Dockerfile。
较慢的 Bun 全局安装 image-provider smoke 由 `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` 镜像:
- 一个裸 Node/Git runner用于安装器/更新/插件依赖 lane
- 一个功能镜像,将同一个 tarball 安装到 `/app`,用于常规功能 lane
- 用于安装器/update/plugin-dependency lane 的裸 Node/Git runner
- 将同一个 tarball 安装到 `/app`、用于正常功能 lane 的功能镜像
Docker lane 定义位于 `scripts/lib/docker-e2e-scenarios.mjs`planner 逻辑位于 `scripts/lib/docker-e2e-plan.mjs`runner 只执行所选 plan。调度器会通过 `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 | 对提供商敏感的 tail-pool slot 数。 |
| `OPENCLAW_DOCKER_ALL_PARALLELISM` | 10 | 普通 lane 的主池槽位数。 |
| `OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM` | 10 | 对提供商敏感的尾池槽位数。 |
| `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 创建风暴;设为 `0` 表示不做错峰。 |
| `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` 会打印调度器 plan而不运行 lane。 |
| `OPENCLAW_DOCKER_ALL_LANES` | unset | 逗号分隔的精确 lane 列表;跳过清理 smoke以便智能体复现一个失败 lane。 |
| `OPENCLAW_DOCKER_ALL_DRY_RUN` | 未设置 | `1` 会打印调度器计划而不运行 lane。 |
| `OPENCLAW_DOCKER_ALL_LANES` | 未设置 | 逗号分隔的精确 lane 列表;跳过 cleanup smoke以便智能体复现一个失败 lane。 |
重于其有效上限的 lane 仍可从空池启动,然后独占运行直到释放容量。本地聚合会预检 Docker移除陈旧的 OpenClaw E2E 容器,输出活跃 lane Status持久化 lane 计时以进行最长优先排序,并且默认在首次失败后停止调度新的池化 lane
重于其有效上限的泳道仍可从空池启动,然后独占运行直到释放容量。本地聚合会预检 Docker移除陈旧的 OpenClaw E2E 容器,输出活跃泳道 Status持久化泳道耗时以便按最长优先排序并且默认在首次失败后停止调度新的池化泳道
### 可复用 live/E2E 工作流
### 可复用 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 层缓存构建并推送带有包摘要标签的 bare/functional GHCR Docker E2E 镜像;并复用提供的 `docker_e2e_bare_image`/`docker_e2e_functional_image` 输入或已有的包摘要镜像而不是重新构建。Docker 镜像拉取会按每次尝试 180 秒的有界超时重试,因此卡住的 registry/cache 流会快速重试,而不是消耗 CI 关键路径的大部分时间。
可复用的 live/E2E 工作流会询问 `scripts/test-docker-all.mjs --plan-json` 需要哪些包、镜像类型、live 镜像、泳道和凭证覆盖范围。随后 `scripts/docker-e2e.mjs` 将该计划转换为 GitHub 输出和摘要。它要么通过 `scripts/package-openclaw-for-docker.mjs` 打包 OpenClaw要么下载当前运行的包构件要么从 `package_artifact_run_id` 下载包构件;校验 tarball 清单;在计划需要已安装包的泳道时,通过 Blacksmith 的 Docker 层缓存构建并推送带有包摘要标签的 bare/functional 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`,这样每个分块只拉取自己需要的镜像类型,并通过同一个加权调度器执行多个泳道
- `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 | bundled-channels`
当前发布 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`、`bundled-channels-core`、`bundled-channels-update-a`、`bundled-channels-update-discord`、`bundled-channels-update-b` 和 `bundled-channels-contracts`。聚合的 `bundled-channels` 分块仍可用于手动一次性重新运行,`plugins-runtime-core`、`plugins-runtime` 和 `plugins-integrations` 也仍作为聚合的插件/运行时别名。`install-e2e` lane 别名仍是两个提供商安装器 lane 的聚合手动重新运行别名。`bundled-channels` 分块运行拆分后的 `bundled-channel-*``bundled-channel-update-*` lane而不是串行的全合一 `bundled-channel-deps` 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`、`bundled-channels-core`、`bundled-channels-update-a`、`bundled-channels-update-discord`、`bundled-channels-update-b` 和 `bundled-channels-contracts`。聚合的 `bundled-channels` 分块仍可用于手动一次性重跑,而 `plugins-runtime-core`、`plugins-runtime` 和 `plugins-integrations` 仍保留为聚合插件/运行时别名。`install-e2e` 泳道别名仍是两个提供商安装器泳道的聚合手动重跑别名。`bundled-channels` 分块运行拆分后的 `bundled-channel-*``bundled-channel-update-*` 泳道,而不是串行的一体化 `bundled-channel-deps` 泳道
当完整发布路径覆盖范围请求 OpenWebUI 时OpenWebUI 会并入 `plugins-runtime-services`,并且只为仅 OpenWebUI 的调度保留独立的 `openwebui` 分块。内置渠道更新 lane 会针对临时 npm 网络失败重试一次。
当完整发布路径覆盖请求 OpenWebUI 时OpenWebUI 会并入 `plugins-runtime-services`,并且仅在只调度 OpenWebUI 时保留独立的 `openwebui` 分块。内置渠道更新泳道会针对临时 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/`,其中包含泳道日志、耗时、`summary.json`、`failures.json`、阶段耗时、调度器计划 JSON、慢泳道表以及每个泳道的重跑命令。工作流 `docker_lanes` 输入会针对已准备的镜像运行选定泳道,而不是运行分块任务,这会把失败泳道的调试限制在一个有针对性的 Docker 任务内,并为该次运行准备、下载或复用包构件;如果选定泳道是 live Docker 泳道,目标任务会在本地为该次重跑构建 live-test 镜像。生成的每泳道 GitHub 重跑命令会在这些值存在时包含 `package_artifact_run_id`、`package_artifact_name` 和已准备的镜像输入,因此失败泳道可以复用失败运行中的确切包和镜像。
```bash
pnpm test:docker:rerun <run-id> # download Docker artifacts and print combined/per-lane targeted rerun commands
pnpm test:docker:timings <summary> # slow-lane and phase critical-path summaries
pnpm test:docker:rerun <run-id> # 下载 Docker 构件并打印组合/每泳道定向重跑命令
pnpm test:docker:timings <summary> # 慢泳道和阶段关键路径摘要
```
定时 live/E2E 工作流每天运行完整的发布路径 Docker 套件。
计划任务 live/E2E 工作流每天运行完整的发布路径 Docker 套件。
## 插件预发布
`Plugin Prerelease` 是成本更高的产品/包覆盖范围,因此它是一个独立工作流,由 `Full Release Validation` 或显式操作员调度。普通拉取请求、`main` 推送和独立手动 CI 调度不会开启该套件。它会在八个插件工作器之间均衡内置插件测试;这些插件分片作业一次最多运行两个插件配置组,每组一个 Vitest 工作器,并使用更大的 Node 堆,因此导入负载较重的插件批次不会创建额外的 CI 作业。仅发布 Docker 预发布路径会把有针对性的 Docker lane 分成小组批处理,以避免为一到三分钟的作业保留数十个运行器。
`Plugin Prerelease` 是成本更高的产品/包覆盖,因此它是一个单独的工作流,由 `Full Release Validation` 或显式操作员调度。普通拉取请求、`main` 推送和独立手动 CI 调度都会关闭该套件。它会把内置插件测试均衡分配到八个扩展工作器;这些扩展分片任务每次最多运行两个插件配置组,每组使用一个 Vitest 工作器和更大的 Node 堆,因此导入密集型插件批次不会创建额外的 CI 任务。仅发布使用的 Docker 预发布路径会以小组批处理目标 Docker 泳道,避免为一到三分钟的任务预留几十个运行器。
## QA 实验室
QA 实验室在主智能范围化工作流之外有专用 CI lane
QA 实验室在主智能作用域工作流之外有专用 CI 泳道
- `Parity gate` 工作流会在匹配的 PR 更改和手动调度时运行;它构建私有 QA 运行时,并比较 mock GPT-5.5 和 Opus 4.6 agentic 包。
- `QA-Lab - All Lanes` 工作流会`main` 上每晚运行,也会在手动调度时运行;它会把 mock parity gate、live Matrix lane以及 live Telegram 和 Discord lane 作为并行作业展开。Live 作业使用 `qa-live-shared` 环境Telegram/Discord 使用 Convex 租约。
- `Parity gate` 工作流会在匹配的 PR 变更和手动调度时运行;它会构建私有 QA 运行时,并比较模拟 GPT-5.5 和 Opus 4.6 的 agentic 包。
- `QA-Lab - All Lanes` 工作流会每晚在 `main` 上运行,也可手动调度;它会把模拟 parity gate、live Matrix 泳道,以及 live Telegram 和 Discord 泳道扇出为并行任务。Live 任务使用 `qa-live-shared` 环境Telegram/Discord 使用 Convex 租约。
发布检查会使用确定性的 mock 提供商和 mock 限定模型(`mock-openai/gpt-5.5` 和 `mock-openai/gpt-5.5-alt`)运行 Matrix 和 Telegram live 传输 lane因此渠道契约会与 live 模型延迟和普通提供商插件启动隔离开。Live 传输 Gateway 网关会禁用记忆搜索,因为 QA parity 会单独覆盖记忆行为;提供商连性由单独的 live 模型、原生提供商和 Docker 提供商套件覆盖。
发布检查会使用确定性的模拟提供商和模拟限定模型(`mock-openai/gpt-5.5` 和 `mock-openai/gpt-5.5-alt`)运行 Matrix 和 Telegram live 传输泳道,因此渠道契约会与 live 模型延迟和正常提供商插件启动隔离。live 传输 Gateway 网关会禁用记忆搜索,因为 QA parity 会单独覆盖记忆行为;提供商连性由单独的 live 模型、原生提供商和 Docker 提供商套件覆盖。
Matrix 在定时和发布门禁中使用 `--profile fast`,并且只在检出的 CLI 支持时添加 `--fail-fast`。CLI 默认值和手动工作流输入仍为 `all`;手动 `matrix_profile=all` 调度始终会把完整 Matrix 覆盖范围分片为 `transport`、`media`、`e2ee-smoke`、`e2ee-deep` 和 `e2ee-cli` 作业
Matrix 对计划任务和发布门禁使用 `--profile fast`,仅在检出的 CLI 支持时添加 `--fail-fast`。CLI 默认值和手动工作流输入仍为 `all`;手动 `matrix_profile=all` 调度始终会把完整 Matrix 覆盖分片为 `transport`、`media`、`e2ee-smoke`、`e2ee-deep` 和 `e2ee-cli` 任务
`OpenClaw Release Checks` 也会在发布批准前运行发布关键的 QA 实验室 lane它的 QA parity gate 会把候选包和基线包作为并行 lane 作业运行,然后把两个构件下载到一个小型报告作业中进行最终 parity 比较。
`OpenClaw Release Checks` 还会在发布批准前运行发布关键的 QA 实验室泳道;它的 QA parity gate 会把候选包和基线包作为并行泳道任务运行,然后将两个构件都下载到一个小型报告任务中,用于最终 parity 比较。
不要把 PR 落地路径置于 `Parity gate` 之后,除非更改确实触及 QA 运行时、模型包 parity或 parity 工作流拥有的表面。对于普通渠道、配置、文档或单元测试修复,请将其视为可选信号,并遵循范围化 CI/检查证据。
不要把 PR 合入路径放在 `Parity gate` 之后,除非该变更确实触及 QA 运行时、模型包 parity或 parity 工作流拥有的表面。对于普通渠道、配置、文档或单元测试修复,应将它视为可选信号,并遵循作用域化的 CI/检查证据。
## CodeQL
`CodeQL` 工作流有意作为狭窄的第一轮安全扫描器,而不是完整仓库扫描。每日、手动和非草稿拉取请求守护运行会扫描 Actions 工作流代码,以及风险最高的 JavaScript/TypeScript 表面,并使用筛选到高/严重 `security-severity` 的高置信度安全查询。
`CodeQL` 工作流有意作为范围狭窄的第一轮安全扫描器,而不是完整仓库扫描。每日、手动和非草稿拉取请求守护运行会扫描 Actions 工作流代码,以及风险最高的 JavaScript/TypeScript 表面,并使用过滤到高/严重 `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/core-auth-secrets` | 凭证、密钥、沙箱、cron 和 Gateway 网关基线 |
| `/codeql-security-high/channel-runtime-boundary` | 核心渠道实现契约以及渠道插件运行时、Gateway 网关、插件 SDK、密钥、审计触点 |
| `/codeql-security-high/network-ssrf-boundary` | 核心 SSRF、IP 解析、网络防护、web-fetch 和插件 SDK SSRF 策略表面 |
| `/codeql-security-high/mcp-process-tool-boundary` | MCP 服务器、进程执行辅助工具、出站投递和智能体工具执行门禁 |
| `/codeql-security-high/network-ssrf-boundary` | 核心 SSRF、IP 解析、网络防护、web-fetch 和插件 SDK SSRF 策略表面 |
| `/codeql-security-high/mcp-process-tool-boundary` | MCP 服务器、进程执行辅助工具、出站投递和 agent 工具执行门禁 |
| `/codeql-security-high/plugin-trust-boundary` | 插件安装、加载器、清单、registry、运行时依赖暂存、源码加载和插件 SDK 包契约信任表面 |
### 平台特定安全分片
- `CodeQL Android Critical Security`定时 Android 安全分片。在 workflow sanity 接受的最小 Blacksmith Linux 运行器上为 CodeQL 手动构建 Android 应用。上传到 `/codeql-critical-security/android` 下。
- `CodeQL macOS Critical Security` — 每周/手动 macOS 安全分片。在 Blacksmith macOS 上为 CodeQL 手动构建 macOS 应用,从上传的 SARIF 中过滤依赖构建结果,并上传到 `/codeql-critical-security/macos` 下。它保留在每日默认项之外因为即使在干净状态下macOS 构建也会主导运行时间
- `CodeQL Android Critical Security`计划任务 Android 安全分片。在工作流完整性检查接受的最小 Blacksmith Linux 运行器上,为 CodeQL 手动构建 Android 应用。上传到 `/codeql-critical-security/android` 下。
- `CodeQL macOS Critical Security` — 每周/手动 macOS 安全分片。在 Blacksmith macOS 上为 CodeQL 手动构建 macOS 应用,从上传的 SARIF 中过滤依赖构建结果,并上传到 `/codeql-critical-security/macos` 下。由于 macOS 构建即使干净也主导运行时,因此保持在每日默认项之外
### 关键质量类别
`CodeQL Critical Quality` 是对应的非安全分片。它只在较小的 Blacksmith Linux 运行器上,对狭窄的高价值表面运行错误严重级别、非安全 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 运行器上,对狭窄的高价值表面运行 error-severity、非安全 JavaScript/TypeScript 质量查询。它的拉取请求守护有意比计划任务配置文件更小:非草稿 PR 只会针对 agent 命令/模型/工具执行和回复分发代码、配置 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 质量分片。
手动调度接受:
@ -354,40 +354,40 @@ Matrix 在定时和发布门禁中使用 `--profile fast`,并且只在检出
profile=all|agent-runtime-boundary|config-boundary|core-auth-secrets|channel-runtime-boundary|gateway-runtime-boundary|memory-runtime-boundary|mcp-process-runtime-boundary|plugin-boundary|plugin-sdk-package-contract|plugin-sdk-reply-runtime|provider-runtime-boundary|session-diagnostics-boundary
```
狭窄配置是用于单独运行一个质量分片的教学/迭代钩子。
这些窄配置文件是用于单独运行一个质量分片的教学/迭代钩子。
| 类别 | 表面 |
| ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `/codeql-critical-quality/core-auth-secrets` | 证、密钥、沙箱、cron 和 Gateway 网关安全边界代码 |
| `/codeql-critical-quality/config-boundary` | 配置架构、迁移、规范化和 IO 契约 |
| `/codeql-critical-quality/gateway-runtime-boundary` | Gateway 网关协议架构和服务器方法契约 |
| `/codeql-critical-quality/channel-runtime-boundary` | 核心渠道和内置渠道插件实现契约 |
| `/codeql-critical-quality/agent-runtime-boundary` | 命令执行、模型/提供商分发、自动回复分发和队列,以及 ACP 控制平面运行时契约 |
| `/codeql-critical-quality/mcp-process-runtime-boundary` | MCP 服务器和工具桥接、进程监督辅助工具,以及出站投递契约 |
| `/codeql-critical-quality/memory-runtime-boundary` | 记忆宿主 SDK、记忆运行时门面、记忆插件 SDK 别名、记忆运行时激活粘合代码,以及记忆 Doctor 命令 |
| `/codeql-critical-quality/session-diagnostics-boundary` | 回复队列内部机制、会话投递队列、出站会话绑定/投递辅助工具、诊断事件/日志包表面,以及会话 Doctor CLI 契约 |
| `/codeql-critical-quality/plugin-sdk-reply-runtime` | 插件 SDK 入站回复分、回复载荷/分块/运行时辅助工具、渠道回复选项、投递队列,以及会话/线程绑定辅助工具 |
| `/codeql-critical-quality/provider-runtime-boundary` | 模型目录规范化、提供商证和设备发现、提供商运行时注册、提供商默认值/目录,以及 Web/搜索/抓取/嵌入注册表 |
| `/codeql-critical-quality/ui-control-plane` | 控制 UI 引导、本地持久化、Gateway 网关控制流,以及任务控制平面运行时契约 |
| `/codeql-critical-quality/web-media-runtime-boundary` | 核心 Web 抓取/搜索、媒体 IO、媒体理解、图像生成和媒体生成运行时契约 |
| `/codeql-critical-quality/plugin-boundary` | 加载器、注册表、公共表面和插件 SDK 入口点契约 |
| `/codeql-critical-quality/plugin-sdk-package-contract` | 已发布包侧插件 SDK 源码和插件包契约辅助工具 |
| 类别 | 表面 |
| ------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `/codeql-critical-quality/core-auth-secrets` | 证、密钥、沙箱、cron 和 Gateway 网关安全边界代码 |
| `/codeql-critical-quality/config-boundary` | 配置架构、迁移、规范化和 IO 契约 |
| `/codeql-critical-quality/gateway-runtime-boundary` | Gateway 网关协议架构和服务器方法契约 |
| `/codeql-critical-quality/channel-runtime-boundary` | 核心渠道和内置渠道插件实现契约 |
| `/codeql-critical-quality/agent-runtime-boundary` | 命令执行、模型/提供商分派、自动回复分派和队列,以及 ACP 控制平面运行时契约 |
| `/codeql-critical-quality/mcp-process-runtime-boundary` | MCP 服务器和工具桥接、进程监督辅助工具,以及出站投递契约 |
| `/codeql-critical-quality/memory-runtime-boundary` | 记忆宿主 SDK、记忆运行时门面、记忆插件 SDK 别名、记忆运行时激活胶水代码,以及记忆 Doctor 命令 |
| `/codeql-critical-quality/session-diagnostics-boundary` | 回复队列内部机制、会话投递队列、出站会话绑定/投递辅助工具、诊断事件/日志包表面,以及会话 Doctor CLI 契约 |
| `/codeql-critical-quality/plugin-sdk-reply-runtime` | 插件 SDK 入站回复分、回复载荷/分块/运行时辅助工具、渠道回复选项、投递队列,以及会话/线程绑定辅助工具 |
| `/codeql-critical-quality/provider-runtime-boundary` | 模型目录规范化、提供商证和设备发现、提供商运行时注册、提供商默认值/目录,以及 Web/搜索/抓取/嵌入注册表 |
| `/codeql-critical-quality/ui-control-plane` | 控制 UI 引导、本地持久化、Gateway 网关控制流,以及任务控制平面运行时契约 |
| `/codeql-critical-quality/web-media-runtime-boundary` | 核心 Web 抓取/搜索、媒体 IO、媒体理解、图像生成,以及媒体生成运行时契约 |
| `/codeql-critical-quality/plugin-boundary` | 加载器、注册表、公开表面和插件 SDK 入口点契约 |
| `/codeql-critical-quality/plugin-sdk-package-contract` | 已发布包侧插件 SDK 源码和插件包契约辅助工具 |
质量与安全保持分离,这样质量发现项可以被调度、度量、禁用或扩展而不会模糊安全信号。Swift、Python 和内置插件 CodeQL 扩展只应在窄配置文件具备稳定运行时和信号后,作为有范围或分片的后续工作加回。
质量与安全保持分离,这样质量发现就可以被排期、度量、禁用或扩展而不会掩盖安全信号。Swift、Python 和内置插件 CodeQL 扩展只应在这些窄配置文件拥有稳定的运行时和信号之后,作为有作用域或分片的后续工作加回。
## 维护工作流
### 文档智能体
### Docs Agent
`Docs Agent` 工作流是一个事件驱动的 Codex 维护通道,用于让现有文档与最近落地的更改保持一致。它没有纯定时计划:`main` 上成功的非机器人 push CI 运行可以触发它,手动分发也可以直接运行它。当 `main` 已经继续推进,或过去一小时内已经创建了另一个未跳过的 Docs Agent 运行时,工作流运行调用会跳过。运行时,它会审查从上一个未跳过的 Docs Agent 源 SHA 到当前 `main` 的提交范围,因此一次每小时运行可以覆盖自上次文档处理以来累的所有 main 更改。
`Docs Agent` 工作流是一个事件驱动的 Codex 维护通道,用于让现有文档与最近落地的更改保持一致。它没有纯定时计划:`main` 上一次成功的非 bot 推送 CI 运行可以触发它,手动派发也可以直接运行它。当 `main` 已经继续前进,或者过去一小时内已经创建了另一次未跳过的 Docs Agent 运行时workflow-run 调用会跳过。运行时,它会审阅从上一个未跳过的 Docs Agent 源 SHA 到当前 `main` 的提交范围,因此一次每小时运行可以覆盖自上次文档处理以来累的所有 main 更改。
### 测试性能智能体
### Test Performance Agent
`Test Performance Agent` 工作流是一个事件驱动的 Codex 维护通道,用于处理慢速测试。它没有纯定时计划:`main` 上成功的非机器人 push CI 运行可以触发它,但如果当天 UTC 已经有另一个工作流运行调用已运行或正在运行,它会跳过。手动分发会绕过该每日活动门禁。该通道会构建全套分组 Vitest 性能报告,让 Codex 只做小型且保持覆盖率的测试性能修复而不是大范围重构然后重新运行全套报告并拒绝会减少通过基线测试数量的更改。如果基线存在失败测试Codex 只能修复显而易见的失败,并且智能体后的全套报告必须通过后才会提交任何内容。当机器人 push 落地前 `main` 前进时,该通道会 rebase 已验证的补丁,重新运行 `pnpm check:changed`,并重试 push冲突的过期补丁会被跳过。它使用 GitHub 托管的 Ubuntu因此 Codex action 可以保持与文档智能体相同的 drop-sudo 安全姿态。
`Test Performance Agent` 工作流是一个事件驱动的 Codex 维护通道,用于慢测试。它没有纯定时计划:`main` 上一次成功的非 bot 推送 CI 运行可以触发它,但如果当天 UTC 已经有另一个 workflow-run 调用运行过或正在运行,它会跳过。手动派发会绕过这个每日活动门禁。该通道会构建完整套件分组 Vitest 性能报告,让 Codex 只做保留覆盖率的小型测试性能修复而不是大范围重构然后重新运行完整套件报告并拒绝会降低通过基线测试数量的更改。如果基线存在失败测试Codex 只能修复明显失败,且 agent 之后的完整套件报告必须通过,才会提交任何内容。当 `main` 在 bot 推送落地前前进时,该通道会 rebase 已验证的补丁,重新运行 `pnpm check:changed`,并重试推送;有冲突的过期补丁会被跳过。它使用 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 已合并,并验证每个重复 PR 要么共享引用的问题,要么有重叠的变更 hunk。
```bash
gh workflow run duplicate-after-merge.yml \
@ -398,25 +398,25 @@ gh workflow run duplicate-after-merge.yml \
## 本地检查门禁和变更路由
本地变更通道逻辑位于 `scripts/changed-lanes.mjs`,并由 `scripts/check-changed.mjs` 执行。该本地检查门禁对架构边界的要求比宽泛的 CI 平台范围更严格:
本地 changed-lane 逻辑位于 `scripts/changed-lanes.mjs`,并由 `scripts/check-changed.mjs` 执行。该本地检查门禁在架构边界上比宽泛的 CI 平台作用域更严格:
- 核心生产更改运行核心生产和核心测试类型检查,以及核心 lint/guard
- 仅核心测试更改只运行核心测试类型检查以及核心 lint
- 插件生产更改运行插件生产和插件测试类型检查,以及插件 lint
- 仅插件测试更改运行插件测试类型检查以及插件 lint
- 公插件 SDK 或插件契约更改会扩展到插件类型检查因为插件依赖这些核心契约Vitest 插件扫测仍然是显式测试工作);
- 仅发布元数据的版本 bump 运行有针对性的版本/配置/根依赖检查;
- 未知的根/配置更改会故障安全地进入所有检查通道。
- 核心生产更改运行核心生产和核心测试类型检查,以及核心 lint/防护
- 仅核心测试更改只运行核心测试类型检查以及核心 lint
- 插件生产更改运行插件生产和插件测试类型检查,以及插件 lint
- 仅插件测试更改运行插件测试类型检查以及插件 lint
- 公插件 SDK 或插件契约更改会扩展到插件类型检查因为插件依赖这些核心契约Vitest 插件扫测仍然是显式测试工作);
- 仅发布元数据的版本号提升会运行有针对性的版本/配置/根依赖检查;
- 未知的根目录/配置更改会 fail safe 到所有检查通道。
本地变更测试路由位于 `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` 更便宜:直接测试编辑会运行自身,源码编辑优先使用显式映射,然后是兄弟测试和导入图依赖项。共享群组房间投递配置是显式映射之一:对群组可见回复配置、源回复投递模式或 message-tool 系统提示词的更改,会经过核心回复测试以及 Discord 和 Slack 投递回归测试,因此共享默认值更改会在第一次 PR 推送前失败。只有当变更影响范围足够覆盖整个 harness便宜的映射集合不再是可信代理时,才使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`
## Testbox 验证
从仓库根目录运行 Testbox并优先为宽泛证明使用新预热的 box。在把慢速门禁花到一个复用、过期或刚报告异常大同步的 box 上之前,先在该 box 内运行 `pnpm testbox:sanity`
从仓库根目录运行 Testbox并优先为宽泛证明使用一个新预热的 box。在对一个被复用、已过期或刚报告了意外大同步的 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 个已跟踪删除时,完整性检查会快速失败。这通常意味着远程同步状态不是 PR 的可信副本;请停止该 box并预热一个新的而不是调试产品测试失败。对于有意的大删除 PR为那次完整性运行设置 `OPENCLAW_TESTBOX_ALLOW_MASS_DELETIONS=1`
`pnpm testbox:run` 还会终止本地 Blacksmith CLI 调用,如果它在同步阶段停留超过五分钟且没有同步后输出。设置 `OPENCLAW_TESTBOX_SYNC_TIMEOUT_MS=0` 可禁用该 guard,或者为异常大的本地 diff 使用更大的毫秒值。
如果本地 Blacksmith CLI 调用停留在同步阶段超过五分钟且没有同步后输出,`pnpm testbox:run` 也会终止该调用。设置 `OPENCLAW_TESTBOX_SYNC_TIMEOUT_MS=0` 可禁用该防护,或者为异常大的本地 diff 使用更大的毫秒值。
## 相关

View File

@ -1,27 +1,27 @@
---
read_when:
- 配置渠道插件(认证、访问控制、多账号
- 按渠道的配置键名故障排除
- 配置渠道插件(身份验证、访问控制、多账户
- 排查各渠道配置键
- 审计私信策略、群组策略或提及门控
summary: 渠道配置Slack、Discord、Telegram、WhatsApp、Matrix、iMessage 等的访问控制、配对和各渠道密钥
title: 配置 — 渠道
x-i18n:
generated_at: "2026-04-30T13:59:04Z"
generated_at: "2026-05-01T03:00:03Z"
model: gpt-5.5
provider: openai
source_hash: aba14cb43e1fe914cc7c03f41bed1b5915cc6b2ad8e0f1d47f58b7e98c1b3915
source_hash: ce1571d51e026182d49b935780a986780a90b05afc0acca027b2541b80a1aac2
source_path: gateway/config-channels.md
workflow: 16
---
`channels.*` 下的渠道配置键。涵盖私信和群组访问、多账号设置、提及门控,以及 Slack、Discord、Telegram、WhatsApp、Matrix、iMessage 和其他内置渠道插件的按渠道键名
`channels.*` 下的渠道配置键。涵盖私信和群组访问、多账号设置、提及门控,以及 Slack、Discord、Telegram、WhatsApp、Matrix、iMessage 和其他内置渠道插件的各渠道键
对于智能体、工具、Gateway 网关运行时和其他顶键,请参阅
对于智能体、工具、Gateway 网关运行时和其他顶键,请参阅
[配置参考](/zh-CN/gateway/configuration-reference)。
## 渠道
每个渠道会在其配置段存在时自动启动(除非 `enabled: false`)。
每个渠道会在其配置段存在时自动启动(除非设置了 `enabled: false`)。
### 私信和群组访问
@ -31,8 +31,8 @@ x-i18n:
| ------------------- | --------------------------------------------------------------- |
| `pairing`(默认) | 未知发送者会收到一次性配对码;所有者必须批准 |
| `allowlist` | 仅允许 `allowFrom`(或已配对允许存储)中的发送者 |
| `open` | 允许所有入私信(需要 `allowFrom: ["*"]` |
| `disabled` | 忽略所有入私信 |
| `open` | 允许所有入私信(需要 `allowFrom: ["*"]` |
| `disabled` | 忽略所有入私信 |
| 群组策略 | 行为 |
| --------------------- | ------------------------------------------------------ |
@ -42,13 +42,13 @@ x-i18n:
<Note>
`channels.defaults.groupPolicy` 会在提供商的 `groupPolicy` 未设置时设置默认值。
配对码会在 1 小时后过期。待处理的私信配对请求上限为**每个渠道 3 个**。
如果提供商块完全缺失(不存在 `channels.<provider>`),运行时群组策略会回退到 `allowlist`默认拒绝),并在启动时发出警告。
配对码会在 1 小时后过期。待处理的私信配对请求上限为 **每个渠道 3 个**
如果提供商块完全缺失(不存在 `channels.<provider>`),运行时群组策略会回退到 `allowlist`故障关闭),并在启动时发出警告。
</Note>
### 渠道模型覆盖
使用 `channels.modelByChannel` 将特定渠道 ID 固定到某个模型。值接受 `provider/model` 或已配置的模型别名。当会话尚未有模型覆盖时(例如通过 `/model` 设置),会应用渠道映射。
使用 `channels.modelByChannel` 将特定渠道 ID 固定到某个模型。值接受 `provider/model` 或已配置的模型别名。当会话尚未有模型覆盖时(例如通过 `/model` 设置),会应用渠道映射。
```json5
{
@ -89,15 +89,15 @@ x-i18n:
}
```
- `channels.defaults.groupPolicy`当提供商级别的 `groupPolicy` 未设置时使用的回退群组策略。
- `channels.defaults.contextVisibility`:所有渠道的默认补充上下文可见性模式。值:`all`(默认,包含所有引用/线程/历史上下文)、`allowlist`(仅包含来自允许列表发送者的上下文)、`allowlist_quote`(与允许列表相同,但保留显式引用/回复上下文)。按渠道覆盖:`channels.<channel>.contextVisibility`。
- `channels.defaults.heartbeat.showOk`:在 Heartbeat 输出中包含健康的渠道状态
- `channels.defaults.heartbeat.showAlerts`:在 Heartbeat 输出中包含降级/错误状态
- `channels.defaults.heartbeat.useIndicator`:渲染紧凑指示器样式 Heartbeat 输出。
- `channels.defaults.groupPolicy`提供商级 `groupPolicy` 未设置时的备用群组策略。
- `channels.defaults.contextVisibility`:所有渠道的默认补充上下文可见性模式。值:`all`(默认,包含所有引用/话题串/历史上下文)、`allowlist`(仅包含来自允许列表发送者的上下文)、`allowlist_quote`(与允许列表相同,但保留显式引用/回复上下文)。按渠道覆盖:`channels.<channel>.contextVisibility`。
- `channels.defaults.heartbeat.showOk`:在 Heartbeat 输出中包含健康的渠道 Status
- `channels.defaults.heartbeat.showAlerts`:在 Heartbeat 输出中包含降级/错误 Status
- `channels.defaults.heartbeat.useIndicator`:渲染紧凑指示器样式 Heartbeat 输出。
### WhatsApp
WhatsApp 通过 Gateway 网关的 Web 渠道Baileys Web运行。当已存在链接会话时,它会自动启动。
WhatsApp 通过 Gateway 网关的 Web 渠道Baileys Web运行。存在链接会话时,它会自动启动。
```json5
{
@ -137,7 +137,7 @@ WhatsApp 通过 Gateway 网关的 Web 渠道Baileys Web运行。当已存
}
```
<Accordion title="Multi-account WhatsApp">
<Accordion title="多账号 WhatsApp">
```json5
{
@ -155,9 +155,9 @@ WhatsApp 通过 Gateway 网关的 Web 渠道Baileys Web运行。当已存
}
```
- 出站命令默认使用账号 `default`(如果存在);否则使用第一个已配置账号 ID排序后
- 可选的 `channels.whatsapp.defaultAccount` 会在其匹配已配置账号 ID 时覆盖该回退默认账号选择。
- 旧版单账号 Baileys 证目录会由 `openclaw doctor` 迁移到 `whatsapp/default`
- 出站命令默认使用 `default` 账号(如果存在);否则使用第一个已配置账号 ID排序后
- 可选的 `channels.whatsapp.defaultAccount` 会在匹配已配置账号 ID 时覆盖该备用默认账号选择。
- 旧版单账号 Baileys 证目录会由 `openclaw doctor` 迁移到 `whatsapp/default`
- 按账号覆盖:`channels.whatsapp.accounts.<id>.sendReadReceipts`、`channels.whatsapp.accounts.<id>.dmPolicy`、`channels.whatsapp.accounts.<id>.allowFrom`。
</Accordion>
@ -217,13 +217,13 @@ WhatsApp 通过 Gateway 网关的 Web 渠道Baileys Web运行。当已存
}
```
- Bot token`channels.telegram.botToken` 或 `channels.telegram.tokenFile`(仅限普通文件;会拒绝符号链接),默认账号以 `TELEGRAM_BOT_TOKEN` 作为回退
- `apiRoot` 仅是 Telegram Bot API 根地址。使用 `https://api.telegram.org` 或你的自托管/代理根地址,不要使用 `https://api.telegram.org/bot<TOKEN>``openclaw doctor --fix` 会移除意外尾随 `/bot<TOKEN>` 后缀。
- 可选的 `channels.telegram.defaultAccount` 会在匹配已配置账号 ID 时覆盖默认账号选择。
- 在多账号设置2 个以上账号 ID设置显式默认值`channels.telegram.defaultAccount` 或 `channels.telegram.accounts.default`)以避免回退路由;当缺失或无效时,`openclaw doctor` 会发出警告。
- 机器人令牌:`channels.telegram.botToken` 或 `channels.telegram.tokenFile`(仅常规文件;拒绝符号链接),默认账号以 `TELEGRAM_BOT_TOKEN` 作为备用
- `apiRoot` 只是 Telegram Bot API 根地址。使用 `https://api.telegram.org` 或你自托管/代理的根地址,而不是 `https://api.telegram.org/bot<TOKEN>``openclaw doctor --fix` 会移除意外尾随 `/bot<TOKEN>` 后缀。
- 可选的 `channels.telegram.defaultAccount` 会在匹配已配置账号 ID 时覆盖默认账号选择。
- 在多账号设置2 个以上账号 ID设置显式默认值`channels.telegram.defaultAccount` 或 `channels.telegram.accounts.default`)以避免备用路由;缺失或无效时,`openclaw doctor` 会发出警告。
- `configWrites: false` 会阻止由 Telegram 发起的配置写入(超级群组 ID 迁移、`/config set|unset`)。
- 顶层 `bindings[]` 条目使用 `type: "acp"` 为论坛话题配置持久 ACP 绑定(在 `match.peer.id` 中使用规范的 `chatId:topic:topicId`)。字段语义在 [ACP 智能体](/zh-CN/tools/acp-agents#channel-specific-settings) 中共享。
- Telegram 流式预览使用 `sendMessage` + `editMessageText`(适用于直接聊天和群)。
- 带有 `type: "acp"` 的顶级 `bindings[]` 条目会为论坛话题配置持久 ACP 绑定(在 `match.peer.id` 中使用规范的 `chatId:topic:topicId`)。字段语义在 [ACP 智能体](/zh-CN/tools/acp-agents#channel-specific-settings) 中共享。
- Telegram 流式预览使用 `sendMessage` + `editMessageText`(适用于直接聊天和群聊)。
- 重试策略:参阅[重试策略](/zh-CN/concepts/retry)。
### Discord
@ -326,34 +326,34 @@ WhatsApp 通过 Gateway 网关的 Web 渠道Baileys Web运行。当已存
}
```
- Token`channels.discord.token`,默认账号可回退到 `DISCORD_BOT_TOKEN`
- 提供显式 Discord `token` 的直接出站调用会使用该 token 执行调用;账号重试/策略设置仍来自活动运行时快照中选中的账号。
- 可选的 `channels.discord.defaultAccount` 在匹配已配置账号 ID 时会覆盖默认账号选择。
- 令牌:`channels.discord.token`,默认账号的备用值为 `DISCORD_BOT_TOKEN`
- 提供显式 Discord `token` 的直接出站调用会使用该令牌执行调用;账号重试/策略设置仍来自活动运行时快照中选定的账号。
- 可选的 `channels.discord.defaultAccount` 在匹配已配置账号 ID 时会覆盖默认账号选择。
- 使用 `user:<id>`(私信)或 `channel:<id>`(服务器频道)作为投递目标;裸数字 ID 会被拒绝。
- 服务器 slug 为小写,并将空格替换为 `-`;频道键使用 slug 化的名称(不含 `#`)。优先使用服务器 ID。
- 默认会忽略机器人发出的消息。`allowBots: true` 会启用它们;使用 `allowBots: "mentions"` 仅接受提及该机器人的机器人消息(自己的消息仍会被过滤)。
- `channels.discord.guilds.<id>.ignoreOtherMentions`(以及频道覆盖)会丢弃提及其他用户或角色但未提及该机器人的消息(不包括 @everyone/@here)。
- `maxLinesPerMessage`(默认 17即使在 2000 个字符以内,也会拆分行数过多的消息。
- `channels.discord.threadBindings` 控制 Discord 话题串绑定路由:
- `enabled`Discord 对话题串绑定会话功能(`/focus`、`/unfocus`、`/agents`、`/session idle`、`/session max-age`,以及绑定投递/路由)的覆盖值
- `idleHours`Discord 对按小时计的不活动自动取消聚焦的覆盖值`0` 表示禁用)
- `maxAgeHours`Discord 对按小时计的硬性最大时长的覆盖值`0` 表示禁用)
- `spawnSubagentSessions`:用于 `sessions_spawn({ thread: true })` 自动创建/绑定话题串的选择启用开关
- 带有 `type: "acp"` 的顶层 `bindings[]` 条目会为渠道和话题串配置持久 ACP 绑定(在 `match.peer.id` 中使用频道/话题串 ID。字段语义在 [ACP 智能体](/zh-CN/tools/acp-agents#channel-specific-settings) 中共享。
- 服务器 slug 为小写,并将空格替换为 `-`;频道键使用 slug 化的名称(不含 `#`)。优先使用服务器 ID。
- 默认忽略机器人发送的消息。`allowBots: true` 会启用它们;使用 `allowBots: "mentions"` 仅接受提及该机器人的机器人消息(仍会过滤自己的消息)。
- `channels.discord.guilds.<id>.ignoreOtherMentions`(以及频道覆盖)会丢弃提及其他用户或角色但未提及该机器人的消息(不包括 @everyone/@here)。
- `maxLinesPerMessage`(默认 17即使在低于 2000 个字符时,也会拆分过高的消息。
- `channels.discord.threadBindings` 控制 Discord 线程绑定路由:
- `enabled`用于线程绑定会话功能(`/focus`、`/unfocus`、`/agents`、`/session idle`、`/session max-age`,以及绑定投递/路由)的 Discord 覆盖项
- `idleHours`Discord 的非活动自动取消聚焦覆盖项,单位为小时`0` 表示禁用)
- `maxAgeHours`Discord 的硬性最大时长覆盖项,单位为小时`0` 表示禁用)
- `spawnSubagentSessions`:用于 `sessions_spawn({ thread: true })` 自动创建/绑定线程的选择性开关
- 顶层 `bindings[]` 条目中带 `type: "acp"` 的配置用于为渠道和线程配置持久 ACP 绑定(在 `match.peer.id` 中使用频道/线程 ID。字段语义在 [ACP Agents](/zh-CN/tools/acp-agents#channel-specific-settings) 中共享。
- `channels.discord.ui.components.accentColor` 设置 Discord components v2 容器的强调色。
- `channels.discord.voice` 启用 Discord 语音频道对话,以及可选的自动加入 + LLM + TTS 覆盖项。
- `channels.discord.voice.model` 可选择覆盖用于 Discord 语音频道响应的 LLM 模型。
- `channels.discord.voice.daveEncryption``channels.discord.voice.decryptionFailureTolerance` 会透传 `@discordjs/voice` DAVE 选项(默认分别为 `true``24`)。
- OpenClaw 还会在反复解密失败后通过离开/重新加入语音会话来尝试语音接收恢复
- `channels.discord.streaming` 是规范流模式键。旧版 `streamMode` 和布尔`streaming` 会自动迁移。
- `channels.discord.autoPresence` 将运行时可用性映射到机器人状态healthy => online、degraded => idle、exhausted => dnd并允许可选的状态文本覆盖
- `channels.discord.voice.daveEncryption``channels.discord.voice.decryptionFailureTolerance` 会透传 `@discordjs/voice` DAVE 选项(默认分别为 `true``24`)。
- OpenClaw 还会在反复解密失败后通过离开/重新加入语音会话来尝试恢复语音接收。
- `channels.discord.streaming` 是规范流模式键。旧版 `streamMode` 和布尔`streaming`会自动迁移。
- `channels.discord.autoPresence` 将运行时可用性映射到机器人在线状态healthy => online、degraded => idle、exhausted => dnd并允许可选的状态文本覆盖。
- `channels.discord.dangerouslyAllowNameMatching` 会重新启用可变名称/标签匹配(破窗兼容模式)。
- `channels.discord.execApprovals`Discord 原生 exec 审批投递和审批人授权。
- `enabled``true`、`false` 或 `"auto"`(默认)。在自动模式下,当可从 `approvers``commands.ownerAllowFrom` 解析审批人时,会激活 exec 审批。
- `approvers`:允许批 exec 请求的 Discord 用户 ID。省略时回退到 `commands.ownerAllowFrom`
- `agentFilter`:可选的智能体 ID allowlist。省略则转发所有智能体的审批。
- `enabled``true`、`false` 或 `"auto"`(默认)。在自动模式下,当可`approvers``commands.ownerAllowFrom` 解析审批人时,会激活 exec 审批。
- `approvers`:允许批 exec 请求的 Discord 用户 ID。省略时回退到 `commands.ownerAllowFrom`
- `agentFilter`:可选的智能体 ID 允许列表。省略时转发所有智能体的审批。
- `sessionFilter`:可选的会话键模式(子字符串或正则表达式)。
- `target`:发送审批提示的位置。`"dm"`(默认)发送到审批人私信,`"channel"` 发送到来源频道,`"both"` 同时发送到两者。当 target 包含 `"channel"` 时,按钮仅可由已解析的审批人使用。
- `target`:发送审批提示的位置。`"dm"`(默认)发送到审批人私信,`"channel"` 发送到来源频道,`"both"` 同时发送到两者。当目标包含 `"channel"` 时,按钮仅可由已解析的审批人使用。
- `cleanupAfterResolve`:为 `true` 时,在批准、拒绝或超时后删除审批私信。
**反应通知模式:** `off`(无)、`own`(机器人的消息,默认)、`all`(所有消息)、`allowlist`(来自所有消息上的 `guilds.<id>.users`)。
@ -389,9 +389,9 @@ WhatsApp 通过 Gateway 网关的 Web 渠道Baileys Web运行。当已存
- 服务账号 JSON内联`serviceAccount`)或基于文件(`serviceAccountFile`)。
- 也支持服务账号 SecretRef`serviceAccountRef`)。
- 环境变量回退项`GOOGLE_CHAT_SERVICE_ACCOUNT` 或 `GOOGLE_CHAT_SERVICE_ACCOUNT_FILE`
- 环境备用值`GOOGLE_CHAT_SERVICE_ACCOUNT` 或 `GOOGLE_CHAT_SERVICE_ACCOUNT_FILE`
- 使用 `spaces/<spaceId>``users/<userId>` 作为投递目标。
- `channels.googlechat.dangerouslyAllowNameMatching` 会重新启用可变电子邮件主体匹配(破窗兼容模式)。
- `channels.googlechat.dangerouslyAllowNameMatching` 会重新启用可变邮箱主体匹配(破窗兼容模式)。
### Slack
@ -463,35 +463,35 @@ WhatsApp 通过 Gateway 网关的 Web 渠道Baileys Web运行。当已存
}
```
- **Socket 模式**需要同时提供 `botToken``appToken`(默认账号环境变量回退项`SLACK_BOT_TOKEN` + `SLACK_APP_TOKEN`)。
- **HTTP 模式**需要 `botToken` `signingSecret`(位于根级或每个账号中)。
- `socketMode` 会将 Slack SDK Socket Mode 传输调优透传到公共 Bolt 接收器 API。仅在调查 ping/pong 超时或陈旧 websocket 行为时使用。
- **Socket 模式**需要同时提供 `botToken``appToken`(默认账号环境备用值`SLACK_BOT_TOKEN` + `SLACK_APP_TOKEN`)。
- **HTTP 模式**需要 `botToken` 以及 `signingSecret`(位于根级别或每个账号中)。
- `socketMode` 会将 Slack SDK Socket Mode 传输调优透传给公开的 Bolt receiver API。仅在调查 ping/pong 超时或陈旧 websocket 行为时使用
- `botToken`、`appToken`、`signingSecret` 和 `userToken` 接受明文字符串或 SecretRef 对象。
- Slack 账号快照会暴露每个凭证的来源/状态字段,例如 `botTokenSource`、`botTokenStatus`、`appTokenStatus`,以及在 HTTP 模式下的 `signingSecretStatus`。`configured_unavailable` 表示账号通过 SecretRef 配置,但当前命令/运行时路径无法解析 secret 值。
- `configWrites: false` 会阻止 Slack 发起的配置写入。
- 可选的 `channels.slack.defaultAccount` 在匹配已配置账号 ID 时会覆盖默认账号选择。
- `channels.slack.streaming.mode` 是规范 Slack 流模式键。`channels.slack.streaming.nativeTransport` 控制 Slack 的原生流式传输。旧版 `streamMode`、布尔 `streaming``nativeStreaming` 会自动迁移。
- Slack 账号快照会公开每个凭证的来源/状态字段,例如 `botTokenSource`、`botTokenStatus`、`appTokenStatus`,以及在 HTTP 模式下的 `signingSecretStatus`。`configured_unavailable` 表示账号通过 SecretRef 配置,但当前命令/运行时路径无法解析密钥值。
- `configWrites: false` 会阻止 Slack 发起的配置写入。
- 可选的 `channels.slack.defaultAccount` 在匹配已配置账号 ID 时会覆盖默认账号选择。
- `channels.slack.streaming.mode` 是规范 Slack 流模式键。`channels.slack.streaming.nativeTransport` 控制 Slack 的原生流式传输。旧版 `streamMode`、布尔 `streaming``nativeStreaming` 会自动迁移。
- 使用 `user:<id>`(私信)或 `channel:<id>` 作为投递目标。
**反应通知模式:** `off`、`own`(默认)、`all`、`allowlist`(来自 `reactionAllowlist`)。
**话题串会话隔离:** `thread.historyScope` 是按话题串(默认)或跨频道共享。`thread.inheritParent` 会将父频道转录复制到新话题串
**线程会话隔离:** `thread.historyScope` 是按线程(默认)或跨频道共享。`thread.inheritParent` 会将父频道转录复制到新线程
- Slack 原生流式传输加上 Slack assistant 风格的“正在输入...”话题串状态需要一个回复话题串目标。顶层私信默认保持在话题串之外,因此会使用 `typingReaction` 或正常投递,而不是话题串风格预览。
- `typingReaction` 会在回复运行期间向传入 Slack 消息添加临时反应,然后在完成时移除。使用 Slack emoji 短代码,例如 `"hourglass_flowing_sand"`
- Slack 原生流式传输以及 Slack 助手风格的 “is typing...” 线程状态需要回复线程目标。顶层私信默认保持非线程状态,因此它们会使用 `typingReaction` 或普通投递,而不是线程风格预览。
- `typingReaction` 会在回复运行期间向入站 Slack 消息添加临时反应,并在完成时移除它。使用 Slack emoji 短代码,例如 `"hourglass_flowing_sand"`
- `channels.slack.execApprovals`Slack 原生 exec 审批投递和审批人授权。架构与 Discord 相同:`enabled``true`/`false`/`"auto"`)、`approvers`Slack 用户 ID、`agentFilter`、`sessionFilter` 和 `target``"dm"`、`"channel"` 或 `"both"`)。
| 操作组 | 默认 | 备注 |
| ------------ | ------ | ---------------- |
| 操作组 | 默认值 | 备注 |
| ------------ | ------- | ---------------------- |
| reactions | 已启用 | 反应 + 列出反应 |
| messages | 已启用 | 读取/发送/编辑/删除 |
| pins | 已启用 | 置顶/取消置顶/列出 |
| memberInfo | 已启用 | 成员信息 |
| emojiList | 已启用 | 自定义 emoji 列表 |
| messages | 已启用 | 读取/发送/编辑/删除 |
| pins | 已启用 | 置顶/取消置顶/列出 |
| memberInfo | 已启用 | 成员信息 |
| emojiList | 已启用 | 自定义 emoji 列表 |
### Mattermost
在当前 OpenClaw 版本中Mattermost 作为内置插件发布。较旧或自定义构建可以使用 `openclaw plugins install @openclaw/mattermost` 安装当前 npm 包;如果 npm 报告 OpenClaw 拥有的包已弃用,请使用内置插件或本地 checkout,直到发布更新的 npm 包。
Mattermost 在当前 OpenClaw 版本中作为内置插件发布。较旧版本或自定义构建可以使用 `openclaw plugins install @openclaw/mattermost` 安装当前 npm 包;如果 npm 报告 OpenClaw 拥有的包已弃用,请使用内置插件或本地检出,直到发布更新的 npm 包。
```json5
{
@ -525,14 +525,14 @@ WhatsApp 通过 Gateway 网关的 Web 渠道Baileys Web运行。当已存
启用 Mattermost 原生命令时:
- `commands.callbackPath` 必须是路径(例如 `/api/channels/mattermost/command`),不是完整 URL。
- `commands.callbackUrl` 必须解析到 OpenClaw Gateway 网关端点,并且 Mattermost 服务器可以访问。
- 原生斜杠回调使用 Mattermost 在斜杠命令注册期间返回的每命令 token 进行身份验证。如果注册失败或没有命令被激活OpenClaw 会以 `Unauthorized: invalid command token.` 拒绝回调。
- 对于私有/tailnet/内部回调主机Mattermost 可能`ServiceSettings.AllowedUntrustedInternalConnections` 包含回调主机/域名。使用主机/域名值,而不是完整 URL。
- `channels.mattermost.configWrites`:允许或拒绝 Mattermost 发起的配置写入。
- `commands.callbackPath` 必须是路径(例如 `/api/channels/mattermost/command`不是完整 URL。
- `commands.callbackUrl` 必须解析为 OpenClaw Gateway 网关端点,并且可由 Mattermost 服务器访问。
- 原生 slash 回调使用 Mattermost 在 slash 命令注册期间返回的每命令令牌进行认证。如果注册失败或没有激活命令OpenClaw 会以 `Unauthorized: invalid command token.` 拒绝回调。
- 对于私有/tailnet/内部回调主机Mattermost 可能要 `ServiceSettings.AllowedUntrustedInternalConnections` 包含回调主机/域名。使用主机/域名值,而不是完整 URL。
- `channels.mattermost.configWrites`:允许或拒绝 Mattermost 发起的配置写入。
- `channels.mattermost.requireMention`:在频道中回复前要求 `@mention`
- `channels.mattermost.groups.<channelId>.requireMention`:按频道的提及门控覆盖项(`"*"` 表示默认值)。
- 可选的 `channels.mattermost.defaultAccount` 在匹配已配置账号 ID 时会覆盖默认账号选择。
- 可选的 `channels.mattermost.defaultAccount` 在匹配已配置账号 ID 时会覆盖默认账号选择。
### Signal
@ -553,11 +553,11 @@ WhatsApp 通过 Gateway 网关的 Web 渠道Baileys Web运行。当已存
}
```
**回应通知模式:**`off`、`own`(默认)、`all`、`allowlist`(来自 `reactionAllowlist`)。
**响应通知模式:** `off`、`own`(默认)、`all`、`allowlist`(来自 `reactionAllowlist`)。
- `channels.signal.account`:将渠道启动固定到特定的 Signal 账号身份。
- `channels.signal.account`:将渠道启动固定到特定 Signal 账户身份。
- `channels.signal.configWrites`:允许或拒绝由 Signal 发起的配置写入。
- 可选的 `channels.signal.defaultAccount` 会在匹配已配置账号 ID 时覆盖默认账号选择。
- 可选的 `channels.signal.defaultAccount` 会在匹配已配置账户 ID 时覆盖默认账户选择。
### BlueBubbles
@ -577,13 +577,13 @@ BlueBubbles 是推荐的 iMessage 路径(由插件支持,在 `channels.blueb
```
- 此处涵盖的核心键路径:`channels.bluebubbles`、`channels.bluebubbles.dmPolicy`。
- 可选的 `channels.bluebubbles.defaultAccount` 会在匹配已配置账号 ID 时覆盖默认账号选择。
- 带有 `type: "acp"`顶层 `bindings[]` 条目可将 BlueBubbles 对话绑定到持久 ACP 会话。在 `match.peer.id` 中使用 BlueBubbles handle 或目标字符串(`chat_id:*`、`chat_guid:*`、`chat_identifier:*`)。共享字段语义:[ACP Agents](/zh-CN/tools/acp-agents#channel-specific-settings)。
- 完整的 BlueBubbles 渠道配置记录在 [BlueBubbles](/zh-CN/channels/bluebubbles)
- 可选的 `channels.bluebubbles.defaultAccount` 会在匹配已配置账户 ID 时覆盖默认账户选择。
- 顶层 `bindings[]` 条目如果带有 `type: "acp"`可将 BlueBubbles 对话绑定到持久 ACP 会话。在 `match.peer.id` 中使用 BlueBubbles 句柄或目标字符串(`chat_id:*`、`chat_guid:*`、`chat_identifier:*`)。共享字段语义:[ACP 智能体](/zh-CN/tools/acp-agents#channel-specific-settings)。
- 完整的 BlueBubbles 渠道配置记录在 [BlueBubbles](/zh-CN/channels/bluebubbles)。
### iMessage
OpenClaw 会生成 `imsg rpc`(通过 stdio 的 JSON-RPC。不需要守护进程或端口。
OpenClaw 会启动 `imsg rpc`(通过 stdio 运行的 JSON-RPC。不需要守护进程或端口。
```json5
{
@ -607,15 +607,15 @@ OpenClaw 会生成 `imsg rpc`(通过 stdio 的 JSON-RPC。不需要守护
}
```
- 可选的 `channels.imessage.defaultAccount` 会在匹配已配置账号 ID 时覆盖默认账号选择。
- 可选的 `channels.imessage.defaultAccount` 会在匹配已配置账户 ID 时覆盖默认账户选择。
- 需要对 Messages 数据库授予完全磁盘访问权限。
- 需要对 Messages DB 授予完整磁盘访问权限。
- 优先使用 `chat_id:<id>` 目标。使用 `imsg chats --limit 20` 列出聊天。
- `cliPath` 可以指向 SSH 包装器;设置 `remoteHost``host` 或 `user@host`用于通过 SCP 获取附件。
- `attachmentRoots``remoteAttachmentRoots` 会限制入附件路径(默认:`/Users/*/Library/Messages/Attachments`)。
- SCP 使用严格主机密钥检查,因此请确保中继主机密钥已存在于 `~/.ssh/known_hosts` 中。
- `cliPath` 可以指向 SSH 包装器;设置 `remoteHost``host` 或 `user@host`通过 SCP 获取附件。
- `attachmentRoots``remoteAttachmentRoots` 会限制入附件路径(默认:`/Users/*/Library/Messages/Attachments`)。
- SCP 使用严格主机密钥检查,因此请确保中继主机密钥已存在于 `~/.ssh/known_hosts` 中。
- `channels.imessage.configWrites`:允许或拒绝由 iMessage 发起的配置写入。
- 带有 `type: "acp"`顶层 `bindings[]` 条目可将 iMessage 对话绑定到持久 ACP 会话。在 `match.peer.id` 中使用规范化 handle 或显式聊天目标(`chat_id:*`、`chat_guid:*`、`chat_identifier:*`)。共享字段语义:[ACP Agents](/zh-CN/tools/acp-agents#channel-specific-settings)。
- 顶层 `bindings[]` 条目如果带有 `type: "acp"`可将 iMessage 对话绑定到持久 ACP 会话。在 `match.peer.id` 中使用规范化句柄或显式聊天目标(`chat_id:*`、`chat_guid:*`、`chat_identifier:*`)。共享字段语义:[ACP 智能体](/zh-CN/tools/acp-agents#channel-specific-settings)。
<Accordion title="iMessage SSH 包装器示例">
@ -658,21 +658,21 @@ Matrix 由插件支持,并在 `channels.matrix` 下配置。
}
```
- Token 认证使用 `accessToken`;密码认证使用 `userId` + `password`
- `channels.matrix.proxy` 会通过显式 HTTP(S) 代理路由 Matrix HTTP 流量。命名账号可以通过 `channels.matrix.accounts.<id>.proxy` 覆盖它。
- `channels.matrix.network.dangerouslyAllowPrivateNetwork` 允许私有/内部 homeserver。`proxy` 和这个网络选择加入是独立控制项。
- `channels.matrix.defaultAccount` 在多账号设置中选择首选账号
- `channels.matrix.autoJoin` 默认为 `off`,因此邀请的房间和新的私信式邀请会被忽略,直到你设置带有 `autoJoinAllowlist``autoJoin: "allowlist"``autoJoin: "always"`
- `channels.matrix.execApprovals`Matrix 原生 exec 批投递和批者授权。
- `enabled``true`、`false` 或 `"auto"`(默认)。在自动模式下,当可`approvers``commands.ownerAllowFrom` 解析批者时exec 批会激活。
- 令牌认证使用 `accessToken`;密码认证使用 `userId` + `password`
- `channels.matrix.proxy` 会通过显式 HTTP(S) 代理路由 Matrix HTTP 流量。具名账户可以用 `channels.matrix.accounts.<id>.proxy` 覆盖它。
- `channels.matrix.network.dangerouslyAllowPrivateNetwork` 允许私有/内部 homeserver。`proxy` 和此网络选择加入是相互独立的控制项。
- `channels.matrix.defaultAccount` 会在多账户设置中选择首选账户
- `channels.matrix.autoJoin` 默认为 `off`,因此受邀房间和新的私信风格邀请会被忽略,直到你设置带 `autoJoinAllowlist``autoJoin: "allowlist"``autoJoin: "always"`
- `channels.matrix.execApprovals`Matrix 原生 exec 批投递和批者授权。
- `enabled``true`、`false` 或 `"auto"`(默认)。在自动模式下,当可从 `approvers``commands.ownerAllowFrom` 解析批者时exec 批会激活。
- `approvers`:允许批准 exec 请求的 Matrix 用户 ID例如 `@owner:example.org`)。
- `agentFilter`:可选的智能体 ID 允许列表。省略则转发所有智能体的批
- `agentFilter`:可选的智能体 ID 允许列表。省略则转发所有智能体的批。
- `sessionFilter`:可选的会话键模式(子字符串或正则表达式)。
- `target`:发送批提示的位置。`"dm"`(默认)、`"channel"`(来源房间)或 `"both"`
- 按账覆盖:`channels.matrix.accounts.<id>.execApprovals`。
- `channels.matrix.dm.sessionScope` 控制 Matrix 私信如何分组到会话中:`per-user`(默认)按路由后的对端共享,而 `per-room` 会隔离每个私信房间。
- `target`:发送批提示的位置。`"dm"`(默认)、`"channel"`(来源房间)或 `"both"`
- 按账覆盖:`channels.matrix.accounts.<id>.execApprovals`。
- `channels.matrix.dm.sessionScope` 控制 Matrix 私信如何分组为会话:`per-user`(默认)按路由后的对等方共享,而 `per-room` 会隔离每个私信房间。
- Matrix Status 探测和实时目录查找使用与运行时流量相同的代理策略。
- 完整的 Matrix 配置、目标规则和设置示例记录在 [Matrix](/zh-CN/channels/matrix)
- 完整的 Matrix 配置、目标规则和设置示例记录在 [Matrix](/zh-CN/channels/matrix)。
### Microsoft Teams
@ -692,7 +692,7 @@ Microsoft Teams 由插件支持,并在 `channels.msteams` 下配置。
```
- 此处涵盖的核心键路径:`channels.msteams`、`channels.msteams.configWrites`。
- 完整的 Teams 配置(凭证、webhook、私信/群组策略、按团队/按渠道覆盖)记录在 [Microsoft Teams](/zh-CN/channels/msteams)
- 完整的 Teams 配置(凭据、webhook、私信/群组策略、按团队/按频道覆盖)记录在 [Microsoft Teams](/zh-CN/channels/msteams)。
### IRC
@ -718,12 +718,12 @@ IRC 由插件支持,并在 `channels.irc` 下配置。
```
- 此处涵盖的核心键路径:`channels.irc`、`channels.irc.dmPolicy`、`channels.irc.configWrites`、`channels.irc.nickserv.*`。
- 可选的 `channels.irc.defaultAccount` 会在匹配已配置账号 ID 时覆盖默认账号选择。
- 完整的 IRC 渠道配置(host/port/TLS/channels/允许列表/提及门控)记录在 [IRC](/zh-CN/channels/irc)
- 可选的 `channels.irc.defaultAccount` 会在匹配已配置账户 ID 时覆盖默认账户选择。
- 完整的 IRC 渠道配置(主机/端口/TLS/频道/允许列表/提及门控)记录在 [IRC](/zh-CN/channels/irc)。
### 多账(所有渠道)
### 多账(所有渠道)
每个渠道运行多个账号(每个账号都有自己的 `accountId`
每个渠道运行多个账户(每个账户都有自己的 `accountId`
```json5
{
@ -744,32 +744,34 @@ IRC 由插件支持,并在 `channels.irc` 下配置。
}
```
- 省略 `accountId` 时会使用 `default`CLI + 路由)。
- 环境变量 token 只应用于**默认**账号
- 基础渠道设置会应用于所有账号,除非按账号覆盖。
- 使用 `bindings[].match.accountId` 将每个账路由到不同的智能体。
- 如果你仍在使用单账号顶层渠道配置时,通过 `openclaw channels add`(或渠道新手引导)添加非默认账OpenClaw 会先将账号作用域的顶层单账号值提升到渠道账号映射中,以便原始账号继续工作。大多数渠道会把它们移入 `channels.<channel>.accounts.default`Matrix 则可以保留现有匹配的命名/默认目标。
- 现有仅渠道绑定(没有 `accountId`)会继续匹配默认账号;账号作用域绑定仍然是可选的。
- `openclaw doctor --fix` 也会通过将账号作用域的顶层单账号值移动到为该渠道选择的提升账号中来修复混合形态。大多数渠道使用 `accounts.default`Matrix 则可以保留现有匹配的命名/默认目标。
- 省略 `accountId` 时会使用 `default`CLI + 路由)。
- 环境变量令牌只应用于**默认**账户
- 基础渠道设置会应用于所有账户,除非按账户覆盖。
- 使用 `bindings[].match.accountId` 将每个账路由到不同的智能体。
- 如果你在仍使用单账户顶层渠道配置时,通过 `openclaw channels add`(或渠道新手引导)添加非默认账OpenClaw 会先将账户范围的顶层单账户值提升到渠道账户映射中,让原始账户继续工作。大多数渠道会将它们移动到 `channels.<channel>.accounts.default`Matrix 可以改为保留现有的匹配具名/默认目标。
- 现有仅渠道绑定(没有 `accountId`)会继续匹配默认账户;账户范围绑定仍然是可选的。
- `openclaw doctor --fix` 也会通过将账户范围的顶层单账户值移动到为该渠道选择的提升账户来修复混合形态。大多数渠道使用 `accounts.default`Matrix 可以改为保留现有的匹配具名/默认目标。
### 其他插件渠道
许多插件渠道配置为 `channels.<id>`,并记录在各自专用的渠道页面中(例如 Feishu、Matrix、LINE、Nostr、Zalo、Nextcloud Talk、Synology Chat 和 Twitch
查看完整渠道索引:[Channels](/zh-CN/channels)。
许多插件渠道配置为 `channels.<id>`,并记录在其专用渠道页面中(例如 Feishu、Matrix、LINE、Nostr、Zalo、Nextcloud Talk、Synology Chat 和 Twitch
查看完整渠道索引:[渠道](/zh-CN/channels)。
### 群聊提及门控
群组消息默认**需要提及**(元数据提及或安全正则表达式模式)。适用于 WhatsApp、Telegram、Discord、Google Chat 和 iMessage 群聊。
群组消息默认**需要提及**(元数据提及或安全正则表达式模式)。适用于 WhatsApp、Telegram、Discord、Google Chat 和 iMessage 群聊。
可见回复由单独的设置控制。群组/渠道房间默认为 `messages.groupChat.visibleReplies: "message_tool"`OpenClaw 仍会处理该轮次,但普通最终回复保持私密,可见房间输出需要 `message(action=send)`只有当你想要旧版行为,即普通回复会发布回房间时,才设置为 `"automatic"`。若要把相同的仅工具可见回复行为也应用到直接聊天,请设置 `messages.visibleReplies: "message_tool"`
可见回复单独控制。群组/频道房间默认为 `messages.groupChat.visibleReplies: "message_tool"`OpenClaw 仍会处理该轮次,但普通最终回复保持私密,可见房间输出需要 `message(action=send)`仅当你想要旧行为,也就是普通回复会发布回房间时,才设置为 `"automatic"`。如果也要对直接聊天应用相同的仅工具可见回复行为,请设置 `messages.visibleReplies: "message_tool"`
保存文件后Gateway 网关会热重载 `messages` 配置。只有在部署中禁用文件监听或配置重载时才需要重启。
如果消息工具在当前工具策略下不可用OpenClaw 会回退到自动可见回复,而不是静默抑制响应。`openclaw doctor` 会对此不匹配发出警告。
Gateway 网关会在文件保存后热重载 `messages` 配置。仅当部署中禁用文件监听或配置重载时才需要重启。
**提及类型:**
- **元数据提及**:原生平台 @-mentions。在 WhatsApp 自聊模式中会被忽略。
- **元数据提及**:原生平台 @ 提及。在 WhatsApp 自聊模式中会被忽略。
- **文本模式**`agents.list[].groupChat.mentionPatterns` 中的安全正则表达式模式。无效模式和不安全的嵌套重复会被忽略。
- 只有在可以检测时(原生提及或至少一个模式),才会执行提及门控。
- 仅在可以检测时(原生提及或至少一个模式)强制执行提及门控。
```json5
{
@ -786,9 +788,9 @@ IRC 由插件支持,并在 `channels.irc` 下配置。
}
```
`messages.groupChat.historyLimit` 设置全局默认值。渠道可以通过 `channels.<channel>.historyLimit`(或按账号)覆盖。设置为 `0` 可禁用。
`messages.groupChat.historyLimit` 设置全局默认值。渠道可以`channels.<channel>.historyLimit`(或按账户)覆盖。设置为 `0` 可禁用。
`messages.visibleReplies` 是全局来源轮次默认值;`messages.groupChat.visibleReplies` 会为群组/渠道来源轮次覆盖它。渠道允许列表和提及门控仍然决定是否处理某个轮次。
`messages.visibleReplies` 是全局来源轮次默认值;`messages.groupChat.visibleReplies` 会为群组/频道来源轮次覆盖它。渠道允许列表和提及门控仍会决定是否处理某个轮次。
#### 私信历史限制
@ -811,7 +813,7 @@ IRC 由插件支持,并在 `channels.irc` 下配置。
#### 自聊模式
`allowFrom` 中包含你自己的号码以启用自聊模式(忽略原生 @-mentions,只响应文本模式):
`allowFrom` 中包含你自己的号码以启用自聊模式(忽略原生 @ 提及,只响应文本模式):
```json5
{
@ -861,28 +863,28 @@ IRC 由插件支持,并在 `channels.irc` 下配置。
<Accordion title="命令详情">
- 此代码块用于配置命令界面。当前的内置 + 捆绑命令目录见 [Slash Commands](/zh-CN/tools/slash-commands)。
- 本页是**配置键参考**,不是完整命令目录。渠道/插件拥有的命令,例如 QQ Bot `/bot-ping` `/bot-help` `/bot-logs`、LINE `/card`、设备配对 `/pair`、记忆 `/dreaming`、手机控制 `/phone` 和 Talk `/voice`,记录在其渠道/插件页面以及 [Slash Commands](/zh-CN/tools/slash-commands) 中。
- 文本命令必须是带有前导 `/` 的**独立**消息。
- `native: "auto"` 会为 Discord/Telegram 启用原生命令,并让 Slack 保持关闭。
- `nativeSkills: "auto"` 会为 Discord/Telegram 启用原生 Skills 命令,并让 Slack 保持关闭。
- 按渠道覆盖:`channels.discord.commands.native`(布尔值或 `"auto"`)。`false` 会清除前注册的命令。
- 此块配置命令入口。当前内置 + 捆绑命令目录见[斜杠命令](/zh-CN/tools/slash-commands)。
- 本页是**配置键参考**,不是完整命令目录。渠道/插件拥有的命令,例如 QQ Bot `/bot-ping` `/bot-help` `/bot-logs`、LINE `/card`、设备配对 `/pair`、记忆 `/dreaming`、手机控制 `/phone` 和 Talk `/voice`,记录在各自的渠道/插件页面以及[斜杠命令](/zh-CN/tools/slash-commands)中。
- 文本命令必须是`/` 开头的**独立**消息。
- `native: "auto"` 会为 Discord/Telegram 启用原生命令Slack 保持关闭。
- `nativeSkills: "auto"` 会为 Discord/Telegram 启用原生 Skills 命令Slack 保持关闭。
- 按渠道覆盖:`channels.discord.commands.native`(布尔值或 `"auto"`)。`false` 会清除前注册的命令。
- 使用 `channels.<provider>.commands.nativeSkills` 按渠道覆盖原生 Skills 注册。
- `channels.telegram.customCommands` 会添加额外的 Telegram 机器人菜单条目
- `bash: true` 为主 shell 启用 `! <cmd>`。需要 `tools.elevated.enabled`,且发送者位于 `tools.elevated.allowFrom.<channel>` 中。
- `config: true` 启用 `/config`(读取/写入 `openclaw.json`)。对于 Gateway 网关 `chat.send` 客户端,持久化 `/config set|unset` 写入还需要 `operator.admin`;只读`/config show` 仍可供普通写入范围的 operator 客户端使用。
- `mcp: true` `mcp.servers` 下由 OpenClaw 管理的 MCP 服务器配置启用 `/mcp`
- `plugins: true` 启用 `/plugins`,用于插件发现、安装以及启用/禁用控制
- `channels.<provider>.configWrites` 按渠道制配置变更默认true
- 对于多账号渠道,`channels.<provider>.accounts.<id>.configWrites` 也会制针对该账号的写入(例如 `/allowlist --config --account <id>``/config set channels.<provider>.accounts.<id>...`)。
- `restart: false` 会禁用 `/restart` 和 Gateway 网关重启工具操作。默认:`true`。
- `ownerAllowFrom` 是仅限所有者命令/工具的显式所有者允许列表。它`allowFrom` 分开
- `ownerDisplay: "hash"` 会在系统提示中哈希所有者 ID。设置 `ownerDisplaySecret`控制哈希。
- `allowFrom` provider 配置。设置后,它是**唯一**授权来源(渠道允许列表/配对和 `useAccessGroups` 会被忽略)。
- `channels.telegram.customCommands` 会添加额外的 Telegram 机器人菜单
- `bash: true`宿主 shell 启用 `! <cmd>`。需要 `tools.elevated.enabled`,且发送者 `tools.elevated.allowFrom.<channel>` 中。
- `config: true` 启用 `/config`(读取/写入 `openclaw.json`)。对于 Gateway 网关 `chat.send` 客户端,持久化 `/config set|unset` 写入还需要 `operator.admin`;只读 `/config show` 仍可供普通写作用域的操作方客户端使用。
- `mcp: true``mcp.servers` 下由 OpenClaw 管理的 MCP 服务器配置启用 `/mcp`
- `plugins: true` 为插件发现、安装以及启用/禁用控制启用 `/plugins`
- `channels.<provider>.configWrites` 按渠道制配置变更默认true
- 对于多账号渠道,`channels.<provider>.accounts.<id>.configWrites` 也会制针对该账号的写入(例如 `/allowlist --config --account <id>``/config set channels.<provider>.accounts.<id>...`)。
- `restart: false` 会禁用 `/restart` 和 Gateway 网关重启工具操作。默认`true`。
- `ownerAllowFrom` 是仅限所有者命令/工具的显式所有者允许列表。它独立于 `allowFrom`
- `ownerDisplay: "hash"` 会在系统提示词中对所有者 ID 做哈希处理。设置 `ownerDisplaySecret`控制哈希。
- `allowFrom`提供商设置。设置后,它是**唯一**授权来源(渠道允许列表/配对和 `useAccessGroups` 会被忽略)。
- 当未设置 `allowFrom` 时,`useAccessGroups: false` 允许命令绕过访问组策略。
- 命令文档映射:
- 内置 + 捆绑目录:[Slash Commands](/zh-CN/tools/slash-commands)
- 渠道特定命令界面[渠道](/zh-CN/channels)
- 内置 + 捆绑目录:[斜杠命令](/zh-CN/tools/slash-commands)
- 渠道特定命令入口[渠道](/zh-CN/channels)
- QQ Bot 命令:[QQ Bot](/zh-CN/channels/qqbot)
- 配对命令:[配对](/zh-CN/channels/pairing)
- LINE 卡片命令:[LINE](/zh-CN/channels/line)
@ -892,7 +894,7 @@ IRC 由插件支持,并在 `channels.irc` 下配置。
---
## 相关内容
## 相关
- [配置参考](/zh-CN/gateway/configuration-reference) — 顶层键
- [配置 — 智能体](/zh-CN/gateway/config-agents)

File diff suppressed because it is too large Load Diff

View File

@ -1,146 +1,147 @@
---
read_when:
- 正在查找公发布渠道定义
- 正在查找公发布渠道定义
- 运行发布验证或软件包验收
- 查找版本命名和发布节奏
summary: 发布通道、操作员检查清单、验证框、版本命名和节奏
summary: 发布通道、操作员检查清单、验证环境、版本命名和发布节奏
title: 发布策略
x-i18n:
generated_at: "2026-05-01T02:24:12Z"
generated_at: "2026-05-01T03:00:04Z"
model: gpt-5.5
provider: openai
source_hash: bb56568bf860ba9eae47df71c5c1ebefe9eb9ae05ac4706dbb425772ff6cdcaa
source_hash: dfe579099a9580e2d0400cd0b24f26d3fa3ee917899423604ebc13aa2519b4ee
source_path: reference/RELEASING.md
workflow: 16
---
OpenClaw 有三个公开发布通道:
- stable带标签的版本,默认发布到 npm `beta`,或在明确请求时发布到 npm `latest`
- beta预发布标签发布到 npm `beta`
- dev`main` 的移动头部
- 稳定版:带标签的发布版本,默认发布到 npm `beta`,或在明确请求时发布到 npm `latest`
- 测试版:发布到 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`
- Beta 预发布版本:`YYYY.M.D-beta.N`
- 测试版预发布版本:`YYYY.M.D-beta.N`
- Git 标签:`vYYYY.M.D-beta.N`
- 不要月份或日期补零
- `latest` 表示当前已推广的稳定版 npm 发布
- `beta` 表示当前 beta 安装目标
- 稳定版和稳定修正版默认发布到 npm `beta`;发布操作员可以明确指定 `latest`,或稍后推广已审定的 beta 构建
- 不要月份或日期补零
- `latest` 表示当前已提升的稳定版 npm 发布版本
- `beta` 表示当前的测试版安装目标
- 稳定版和稳定版修正发布版本默认发布到 npm `beta`;发布操作者可以明确指定 `latest`,或稍后提升经过验证的测试版构建
- 每个稳定版 OpenClaw 发布都会同时交付 npm 包和 macOS 应用;
beta 发布通常先验证并发布 npm/package 路径,除非明确请求,否则
mac 应用构建/签名/公证保留给稳定版
测试版发布通常会先验证并发布 npm/包路径,除非明确请求,否则
mac 应用构建/签名/公证保留给稳定版
## 发布节奏
- 发布先经过 beta
- 只有在最新 beta 验证通过后才进入稳定版
- 维护者通常从当前 `main` 创建的 `release/YYYY.M.D` 分支切出发布,
- 发布先进入测试版
- 只有在最新测试版通过验证后,稳定版才会跟进
- 维护者通常基于当前 `main` 创建的 `release/YYYY.M.D` 分支切出发布,
这样发布验证和修复不会阻塞 `main` 上的新开发
- 如果 beta 标签已经推送或发布并且需要修复,维护者会切出下一个
`-beta.N` 标签,而不是删除或重新创建旧 beta 标签
- 详细发布流程、审批、凭证和恢复说明仅限维护者使用
- 如果测试版标签已经推送或发布但需要修复,维护者会切出下一个
`-beta.N` 标签,而不是删除或重新创建旧的测试版标签
- 详细发布流程、审批、凭证和恢复说明仅限维护者访问
## 发布操作检查清单
## 发布操作检查清单
此检查清单描述发布流程的公开形态。私有凭证、
此检查清单发布流程的公开形态。私有凭证、
签名、公证、dist-tag 恢复和紧急回滚细节保留在
仅限维护者使用的发布运行手册中。
仅限维护者访问的发布运行手册中。
1. 从当前 `main` 开始:拉取最新代码,确认目标提交已推送,
并确认当前 `main` CI 足够绿色,可以从它创建分支。
2. 使用 `/changelog` 根据真实提交历史重写顶部 `CHANGELOG.md` 章节,
保持条目面向用户,提交它、推送它,并在创建分支前再次 rebase/pull。
1. 从当前 `main` 开始:拉取最新内容,确认目标提交已推送,
并确认当前 `main` CI 足够健康,可以从它创建分支。
2. 使用 `/changelog` 基于真实提交历史重写顶部 `CHANGELOG.md` 章节,
保持条目面向用户,提交并推送,然后在创建分支前再次 rebase/pull。
3. 查看
`src/plugins/compat/registry.ts`
`src/commands/doctor/shared/deprecation-compat.ts` 中的发布兼容性记录。只有在升级路径仍被覆盖时才移除过期兼容性,
或记录为什么有意继续保留。
4. 从当前 `main` 创建 `release/YYYY.M.D`;不要直接在 `main` 上做常规发布工作。
5. 为目标标签更新每个必需的版本位置,然后运行本地确定性预检:
`src/commands/doctor/shared/deprecation-compat.ts` 中的发布兼容性记录。仅当升级路径仍被覆盖时才移除已过期的
兼容性,或记录为什么有意保留它。
4. 从当前 `main` 创建 `release/YYYY.M.D`;不要直接在 `main` 上进行常规发布工作。
5. 为目标标签更新每个必需的版本位置,然后运行
本地确定性预检:
`pnpm check:test-types`、`pnpm check:architecture`、
`pnpm build && pnpm ui:build``pnpm release:check`
6. 运行 `OpenClaw NPM Release`,并设置 `preflight_only=true`。在标签存在之前,
允许使用完整的 40 字符发布分支 SHA 进行仅验证预检。
保存成功的 `preflight_run_id`
6. 使用 `preflight_only=true` 运行 `OpenClaw NPM Release`。在标签存在之前,
允许使用完整的 40 字符发布分支 SHA 进行仅验证预检。保存成功的 `preflight_run_id`
7. 使用 `Full Release Validation` 为发布分支、标签或完整提交 SHA 启动所有预发布测试。
这是四个大型发布测试箱的唯一手动入口点Vitest、Docker、QA Lab 和 Package。
8. 如果验证失败,在发布分支上修复,并重新运行能够证明修复的最小失败文件、通道、工作流作业、包配置、提供商或模型允许列表。
只有在变更范围使先前证据过时时,才重新运行完整总入口。
9. 对于 beta打标签 `vYYYY.M.D-beta.N`,使用 npm dist-tag `beta` 发布,然后针对已发布的 `openclaw@YYYY.M.D-beta.N`
`openclaw@beta` 包运行发布后包验收。如果已推送或已发布的 beta 需要修复,
切出下一个 `-beta.N`;不要删除或重写旧 beta。
10. 对于稳定版,只有在已审定的 beta 或候选发布具备所需验证证据后才继续。
稳定版 npm 发布通过 `preflight_run_id` 复用成功的预检工件;稳定版 macOS 发布就绪还要求
打包的 `.zip`、`.dmg`、`.dSYM.zip` 和更新后的
`appcast.xml` 位于 `main` 上。
11. 发布后,运行 npm 发布后验证器;在需要发布后渠道证明时,可选运行独立的
已发布 npm Telegram E2E按需进行 dist-tag 推广;根据完整匹配的
`CHANGELOG.md` 章节生成 GitHub release/prerelease 说明;并执行发布公告步骤。
这是四个大型发布测试盒的唯一手动入口点Vitest、Docker、QA Lab 和 Package。
8. 如果验证失败,在发布分支上修复,并重新运行能够证明修复的最小失败
文件、通道、工作流作业、包配置、提供商或模型允许列表。仅当变更表面使
先前证据失效时,才重新运行完整总入口。
9. 对于测试版,标记 `vYYYY.M.D-beta.N`,使用 npm dist-tag `beta` 发布,然后针对已发布的 `openclaw@YYYY.M.D-beta.N`
`openclaw@beta` 包运行发布后包验收。如果已推送或已发布的测试版需要修复,
切出下一个 `-beta.N`;不要删除或重写旧测试版。
10. 对于稳定版,仅在经过验证的测试版或发布候选版具备
所需验证证据后继续。稳定版 npm 发布会通过 `preflight_run_id` 复用成功的
预检工件;稳定版 macOS 发布就绪还需要 `main` 上的打包 `.zip`、`.dmg`、`.dSYM.zip` 和已更新的
`appcast.xml`
11. 发布后,运行 npm 发布后验证器;在需要发布后渠道证明时,运行可选的独立
已发布 npm Telegram E2E在需要时进行 dist-tag 提升;根据完整匹配的 `CHANGELOG.md` 章节生成 GitHub 发布/预发布说明;
并执行发布公告步骤。
## 发布预检
- 在发布预检前运行 `pnpm check:test-types`,确保测试 TypeScript 在更快的本地 `pnpm check` 门禁之外被覆盖
- 在发布预检前运行 `pnpm check:architecture`,确保更广泛的导入循环和架构边界检查在更快的本地门禁之外保持绿色
- 在 `pnpm release:check` 前运行 `pnpm build && pnpm ui:build`,确保预期`dist/*` 发布产物和 Control UI bundle 已存在,可用于 pack 验证步骤
- 在发布批准前运行手动 `Full Release Validation` 工作流,以便从一个入口点启动所有预发布测试盒。它接受分支、标签或完整提交 SHA派发手动 `CI`,并派发 `OpenClaw Release Checks`用于安装烟测、package acceptance、Docker 发布路径套件、live/E2E、OpenWebUI、QA Lab parity、Matrix 和 Telegram lane。只有在包已发布且也应运行发布后 Telegram E2E 时,才提供 `npm_telegram_package_spec`。当私有证据报告应证明验证匹配已发布的 npm 包、但不强制运行 Telegram E2E 时,提供 `evidence_package_spec`
- 在发布预检前运行 `pnpm check:test-types`,确保测试 TypeScript 在更快的本地 `pnpm check` 门禁之外被覆盖
- 在发布预检前运行 `pnpm check:architecture`,确保更广泛的导入循环和架构边界检查在更快的本地门禁之外也是绿色的
- 在 `pnpm release:check` 前运行 `pnpm build && pnpm ui:build`,确保打包验证步骤所需`dist/*` 发布产物和 Control UI bundle 已存在
- 在发布批准前运行手动 `Full Release Validation` workflow从一个入口点启动所有预发布测试盒。它接受分支、标签或完整 commit SHA分发手动 `CI`,并分发 `OpenClaw Release Checks`,用于安装 smoke、包验收、Docker 发布路径套件、live/E2E、OpenWebUI、QA Lab 对齐性、Matrix 和 Telegram 通道。仅在包已发布且发布后 Telegram E2E 也应运行时提供 `npm_telegram_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。
示例:`gh workflow run package-acceptance.yml --ref main -f workflow_ref=main -f source=npm -f package_spec=openclaw@beta -f suite_profile=product -f telegram_mode=mock-openai`
- 当你希望在发布工作继续进行的同时,为包候选版本获取旁路证明时,运行手动 `Package Acceptance` workflow。对 `openclaw@beta`、`openclaw@latest` 或精确发布版本使用 `source=npm`;使用 `source=ref` 受信任的 `package_ref` 分支/标签/SHA 与当前 `workflow_ref` harness 打包;对需 SHA-256 的 HTTPS tarball 使用 `source=url`;或对由另一个 GitHub Actions run 上传的 tarball 使用 `source=artifact`。该 workflow 将候选解析为 `package-under-test`,针对该 tarball 复用 Docker E2E 发布调度器,并且可以`telegram_mode=mock-openai``telegram_mode=live-frontier` 针对同一个 tarball 运行 Telegram QA。当选定的 Docker 通道包含 `published-upgrade-survivor` 时,包产物就是候选版本,而 `published_upgrade_survivor_baseline` 选择已发布基线。
示例:`gh workflow run package-acceptance.yml --ref main -f workflow_ref=main -f source=npm -f package_spec=openclaw@beta -f suite_profile=product -f published_upgrade_survivor_baseline=openclaw@2026.4.26 -f telegram_mode=mock-openai`
常用 profile
- `smoke`:安装/渠道/智能体、Gateway 网关网络和配置重载 lane
- `package`:不含 OpenWebUI 或 live ClawHub 的产物原生 package/update/plugin lane
- `product`package profile 加 MCP 渠道、cron/subagent 清理、OpenAI web 搜索和 OpenWebUI
- `smoke`:安装/渠道/智能体、Gateway 网关网络和配置重载通道
- `package`产物原生的包/更新/插件通道,含 OpenWebUI 或 live ClawHub
- `product`package profile 加 MCP 渠道、cron/subagent 清理、OpenAI web 搜索和 OpenWebUI
- `full`:带 OpenWebUI 的 Docker 发布路径分块
- `custom`:用于聚焦重跑的精确 `docker_lanes` 选择
- 当你只需要发布候选版本的完整常规 CI 覆盖时,直接运行手动 `CI` 工作流。手动 CI 派发会绕过 changed 作用域,并强制运行 Linux Node 分片、内置插件分片、渠道契约、Node 22 兼容性、`check`、`check-additional`、构建烟测、文档检查、Python Skills、Windows、macOS、Android 和 Control UI i18n lane
- 当你只需要发布候选版本的完整常规 CI 覆盖时,直接运行手动 `CI` workflow。手动 CI 分发会绕过变更范围限定,并强制运行 Linux Node 分片、内置插件分片、渠道契约、Node 22 兼容性、`check`、`check-additional`、构建 smoke、文档检查、Python Skills、Windows、macOS、Android 和 Control UI i18n 通道
示例:`gh workflow run ci.yml --ref release/YYYY.M.D`
- 验证发布遥测时运行 `pnpm qa:otel:smoke`。它通过本地 OTLP/HTTP receiver 演练 QA-lab并验证导出的 trace span 名称、有界属性以及内容/标识符脱敏,无需 Opik、Langfuse 或其他外部 collector。
- 每次打标签发布前运行 `pnpm release:check`
- 发布检查现在在单独的手动工作流中运行:
- 在验证发布 telemetry 时运行 `pnpm qa:otel:smoke`。它通过本地 OTLP/HTTP 接收器执行 QA-lab并验证导出的 trace span 名称、有界属性以及内容/标识符脱敏,无需 Opik、Langfuse 或其他外部 collector。
- 在每次带标签发布前运行 `pnpm release:check`
- 发布检查现在在单独的手动 workflow 中运行:
`OpenClaw Release Checks`
- `OpenClaw Release Checks` 还会在发布批准前运行 QA Lab mock parity 门禁,以及快速 live Matrix profile 和 Telegram QA lane。live lane 使用 `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 检查留在自己的 lane 中,避免拖慢或阻塞发布
- 带密钥的发布检查应通过 `Full Release Validation` 派发,或从 `main`/release 工作流 ref 派发,以便工作流逻辑和密钥保持受控
- `OpenClaw Release Checks` 接受分支、标签或完整提交 SHA只要解析后的提交可从 OpenClaw 分支或发布标签访问
- `OpenClaw NPM Release` 的仅验证预检也接受当前完整 40 字符工作流分支提交 SHA不要求已推送标签
- `OpenClaw Release Checks` 还会在发布批准前运行 QA Lab mock 对齐性门禁,以及快速 live Matrix profile 和 Telegram QA 通道。live 通道使用 `qa-live-shared` 环境Telegram 也使用 Convex CI 凭证租约。当你想并行获取完整 Matrix 传输、媒体和 E2EE inventory 时,使用 `matrix_profile=all``matrix_shards=true` 运行手动 `QA-Lab - All Lanes` workflow
- 跨操作系统安装和升级运行时验证是公开 `OpenClaw Release Checks``Full Release Validation` 的一部分,它们会直接调用可复用 workflow `.github/workflows/openclaw-cross-os-release-checks-reusable.yml`
- 这种拆分是有意的:让真实 npm 发布路径保持短、确定且聚焦产物,而较慢的 live 检查保留在自己的通道中,避免拖慢或阻塞发布
- 带 secret 的发布检查应通过 `Full Release Validation` 分发,或从 `main`/release workflow ref 分发,以便 workflow 逻辑和 secret 保持受控
- `OpenClaw Release Checks` 接受分支、标签或完整 commit SHA只要解析出的 commit 可从 OpenClaw 分支或发布标签访问
- `OpenClaw NPM Release` 仅验证预检也接受当前完整 40 字符 workflow 分支 commit SHA不要求已推送标签
- 该 SHA 路径仅用于验证,不能提升为真实发布
- 在 SHA 模式下,工作流只会为包元数据检查合成 `v<package.json version>`;真实发布仍需要真实发布标签
- 两个工作流都将真实发布和提升路径保留在 GitHub-hosted runner 上,而非变更性验证路径可以使用更大的 Blacksmith Linux runner
- 该工作流会使用 `OPENAI_API_KEY``ANTHROPIC_API_KEY` 工作流密钥运行 `OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_CACHE_TEST=1 pnpm test:live:cache`
- npm 发布预检不再等待单独的发布检查 lane
- 批准前运行 `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 版本),以在新的临时 prefix 中验证已发布 registry 安装路径
- beta 发布后运行 `OPENCLAW_NPM_TELEGRAM_PACKAGE_SPEC=openclaw@YYYY.M.D-beta.N OPENCLAW_NPM_TELEGRAM_CREDENTIAL_SOURCE=convex OPENCLAW_NPM_TELEGRAM_CREDENTIAL_ROLE=ci pnpm test:docker:npm-telegram-live`,使用共享租约 Telegram 凭证池,针对已发布 npm 包验证已安装包的新手引导、Telegram 设置和真实 Telegram E2E。本地维护者的一次性运行可以省略 Convex 变量,并直接传入三个 `OPENCLAW_QA_TELEGRAM_*` 环境凭证。
- 维护者可以通过手动 `NPM Telegram Beta E2E` 工作流从 GitHub Actions 运行相同的发布后检查。它有意仅支持手动运行,不会在每次合并时运行。
- 维护者发布自动化现在使用先预检、后提升
- 真实 npm 发布必须通过成功的 npm `preflight_run_id`
- 真实 npm 发布必须从与成功预检运行相同的 `main``release/YYYY.M.D` 分支派
- 在 SHA 模式下,workflow 只会为包元数据检查合成 `v<package.json version>`;真实发布仍需要真实发布标签
- 两个 workflow 都将真实发布和推广路径保留在 GitHub-hosted runner 上,而非变更性验证路径可以使用更大的 Blacksmith Linux runner
- 该 workflow 会使用 `OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_CACHE_TEST=1 pnpm test:live:cache`,并同时使用 `OPENAI_API_KEY``ANTHROPIC_API_KEY` workflow secret
- npm 发布预检不再等待单独的发布检查通道
- 批准前运行 `RELEASE_TAG=vYYYY.M.D node --import tsx scripts/openclaw-npm-release-check.ts`(或匹配的 beta/修正版标签)
- npm publish 后,运行 `node --import tsx scripts/openclaw-npm-postpublish-verify.ts YYYY.M.D`(或匹配的 beta/修正版版本),在全新的临时 prefix 中验证已发布 registry 安装路径
- beta publish 后,运行 `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 vars,并直接传入三个 `OPENCLAW_QA_TELEGRAM_*` 环境凭证。
- 维护者可以通过手动 `NPM Telegram Beta E2E` workflow 从 GitHub Actions 运行同一个发布后检查。它有意仅限手动运行,不会在每次合并时运行。
- 维护者发布自动化现在使用先预检再推广
- 真实 npm publish 必须通过成功的 npm `preflight_run_id`
- 真实 npm publish 必须从与成功预检 run 相同的 `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`,而公开 repo 保持仅 OIDC 发布
- 公开 `macOS Release` 仅用于验证;当标签只存在于 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` 的相同临时 prefix 升级路径,确保发布修正不会悄悄把较旧的全局安装留在基础 stable payload 上
- 除非 tarball 同时包含 `dist/control-ui/index.html` 和非空的 `dist/control-ui/assets/` payload否则 npm 发布预检会失败关闭,避免再次发布空的浏览器 dashboard
- 发布后验证还会检查已发布 registry 安装是否在根 `dist/*` 布局下包含非空的内置插件运行时依赖。缺失或包含空的内置插件依赖 payload 的发布会让 postpublish 验证器失败,且不能提升`latest`
- `pnpm test:install:smoke` 会对候选更新 tarball 强制执行 npm pack `unpackedSize` 预算,因此 installer e2e 会在发布路径前捕获意外的 pack 膨胀
- 如果发布工作触及 CI 规划、插件时序 manifest 或插件测试矩阵,请在批准前重新生成并审查 `.github/workflows/plugin-prerelease.yml`由 planner 拥有`plugin-prerelease-extension-shard` 矩阵输出,避免发布说明描述过时的 CI 布局
- stable macOS 发布就绪性还包括 updater surface
- GitHub release 最终必须包含打包`.zip`、`.dmg` 和 `.dSYM.zip`
- 发布后,`main` 上的 `appcast.xml` 必须指向新的 stable zip
- 打包后的 app 必须保留非 debug bundle id、非空 Sparkle feed URL以及不低于该发布版本规范 Sparkle build floor `CFBundleVersion`
- stable npm publish 可以通过 workflow input 显式目标为 `latest`
- 基于 token 的 npm dist-tag 变更现在位于 `openclaw/releases-private/.github/workflows/openclaw-npm-dist-tags.yml`,这是出于安全考虑,因为 `npm dist-tag add` 仍然需要 `NPM_TOKEN`,而公开仓库保持仅 OIDC publish
- 公开 `macOS Release` 仅用于验证;当标签只存在于 release 分支但 workflow 从 `main`发时,设置 `public_release_branch=release/YYYY.M.D`
- 真实私有 mac publish 必须通过成功的私有 mac `preflight_run_id``validate_run_id`
- 真实发布路径会推广准备好的产物,而不是再次重建它们
- 对于 `YYYY.M.D-N` 这样的 stable 修正发布,发布后 verifier 也会检查同一临时 prefix 从 `YYYY.M.D``YYYY.M.D-N` 的升级路径,确保发布修正不会静默地让较旧的全局安装停留在基础 stable payload 上
- npm 发布预检默认失败,除非 tarball 同时包含 `dist/control-ui/index.html` 和非空的 `dist/control-ui/assets/` payload这样我们就不会再次发布空的浏览器 dashboard
- 发布后验证还会检查已发布 registry 安装在根 `dist/*` 布局下包含非空的内置插件运行时依赖。若某个发布缺少内置插件依赖 payload或该 payload 为空,则 postpublish verifier 会失败,且无法推广`latest`
- `pnpm test:install:smoke` 会对候选更新 tarball 强制执行 npm pack `unpackedSize` 预算,因此 installer e2e 可以在发布 publish 路径前捕获意外的 pack 膨胀
- 如果发布工作触及 CI 规划、插件 timing manifest 或插件测试矩阵,请在批准前重新生成并审查由 planner 拥有的 `.github/workflows/plugin-prerelease.yml` 中的 `plugin-prerelease-extension-shard` 矩阵输出,确保发布说明不会描述过时的 CI 布局
- stable macOS 发布就绪性也包括 updater 表面
- GitHub release 最终必须包含打包`.zip`、`.dmg` 和 `.dSYM.zip`
- publish 后,`main` 上的 `appcast.xml` 必须指向新的 stable zip
- 打包后的应用必须保持非 debug bundle id、非空 Sparkle feed URL以及对该发布版本而言不低于规范 Sparkle build 下限`CFBundleVersion`
## 发布测试盒
`Full Release Validation` 是操作员从一个入口点启动所有预发布测试的方式。从受信任的 `main` 工作流 ref 运行它,并将发布分支、标签或完整提交 SHA 作为 `ref` 传入:
`Full Release Validation` 是操作员从一个入口点启动所有预发布测试的方式。从受信任的 `main` workflow ref 运行它,并将发布分支、标签或完整 commit SHA 作为 `ref` 传入:
```bash
gh workflow run full-release-validation.yml \
@ -152,18 +153,17 @@ gh workflow run full-release-validation.yml \
-f evidence_package_spec=openclaw@YYYY.M.D-beta.N
```
工作流会解析目标 ref使用 `target_ref=<release-ref>` 派发手动 `CI`,派发 `OpenClaw Release Checks`,并在设置 `npm_telegram_package_spec` 时可选派发独立的发布后 Telegram E2E。随后 `OpenClaw Release Checks` 会扇出安装烟测、跨操作系统发布检查、live/E2E Docker 发布路径覆盖、带 Telegram package QA 的 Package Acceptance、QA Lab parity、live Matrix 和 live Telegram。只有当 `Full Release Validation` 摘要显示 `normal_ci``release_checks` 成功,且任何可选 `npm_telegram` 子项成功或有意跳过时,完整运行才可接受。最终验证器摘要会为每个子运行包含最慢 job 表,因此发布经理无需下载日志即可查看当前关键路径。
请参阅 [完整发布验证](/zh-CN/reference/full-release-validation),了解完整阶段矩阵、精确工作流 job 名称、stable 与 full profile 差异、产物以及聚焦重跑句柄。
工作流会从运行 `Full Release Validation` 的受信任 ref 派发,通常为 `--ref main`,即使目标 `ref` 指向较旧的 release 分支或标签也是如此。不存在单独的 Full Release Validation workflow-ref 输入;通过选择工作流运行 ref 来选择受信任 harness。
workflow 会解析目标 ref使用 `target_ref=<release-ref>` 分发手动 `CI`,分发 `OpenClaw Release Checks`,并在设置了 `npm_telegram_package_spec` 时可选地分发独立的发布后 Telegram E2E。随后 `OpenClaw Release Checks` 会分发安装 smoke、跨操作系统发布检查、live/E2E Docker 发布路径覆盖、带 Telegram package QA 的 Package Acceptance、QA Lab 对齐性、live Matrix 和 live Telegram。只有当 `Full Release Validation` 摘要显示 `normal_ci``release_checks` 成功,且任何可选 `npm_telegram` 子项成功或有意跳过时,完整运行才可接受。最终 verifier 摘要会包含每个子 run 的最慢 job 表,因此发布经理无需下载日志就能看到当前关键路径。
参见 [完整发布验证](/zh-CN/reference/full-release-validation),了解完整阶段矩阵、精确 workflow job 名称、stable 与 full profile 差异、产物以及聚焦重跑句柄。
workflow 从运行 `Full Release Validation` 的受信任 ref 分发,通常是 `--ref main`,即使目标 `ref` 指向较旧的发布分支或标签。没有单独的 Full Release Validation workflow-ref input通过选择 workflow run ref 来选择受信任的 harness。
使用 `release_profile` 选择 live/provider 覆盖宽度
使用 `release_profile` 选择 live/provider 覆盖范围
- `minimum`:最快的发布关键 OpenAI/core live 和 Docker 路径
- `stable`minimum 加用于发布批准的 stable provider/backend 覆盖
- `full`stable 加广泛的 advisory provider/media 覆盖
- `stable`minimum 加用于发布批准的 stable provider/backend 覆盖
- `full`stable 加广泛的 advisory provider/media 覆盖
`OpenClaw Release Checks` 使用受信任的工作流 ref 将目标 ref 一次性解析为 `release-package-under-test`,并在发布路径 Docker 检查和 Package Acceptance 中复用该产物。这让所有面向包的测试盒使用相同字节,并避免重复构建包。
当 repo/org 变量已设置时,跨操作系统 OpenAI 安装烟测使用 `OPENCLAW_CROSS_OS_OPENAI_MODEL`,否则使用 `openai/gpt-5.4-mini`,因为该 lane 证明的是包安装、新手引导、Gateway 网关启动和一次 live 智能体回合,而不是 benchmark 最慢的默认模型。更广泛的 live provider 矩阵仍然是模型特定覆盖的位置。
`OpenClaw Release Checks` 使用受信任的工作流引用,将目标引用一次解析为 `release-package-under-test`,并在 release-path Docker 检查和 Package Acceptance 中复用该工件。这会让所有面向包的盒子使用相同字节,并避免重复构建包。跨 OS OpenAI 安装冒烟测试会在设置了仓库/组织变量时使用 `OPENCLAW_CROSS_OS_OPENAI_MODEL`,否则使用 `openai/gpt-5.4-mini`因为此通道验证的是包安装、新手引导、Gateway 网关启动和一次实时智能体轮次,而不是对最慢的默认模型做基准测试。更广泛的实时提供商矩阵仍然负责模型特定覆盖。
根据发布阶段使用这些变体:
@ -194,22 +194,22 @@ gh workflow run full-release-validation.yml \
-f npm_telegram_provider_mode=mock-openai
```
不要把完整总括流程作为聚焦修复后的第一次重跑。如果某个检查项失败,请使用失败的子 workflow、作业、Docker lane、包 profile、模型提供商或 QA lane 作为下一次证明。只有当修复改动了共享发布编排,或使先前的全检查项证据过期时,才再次运行完整总括流程。总括流程的最终验证器会重新检查已记录的子 workflow run ID因此在某个子 workflow 成功重跑后,只需重跑失败的 `Verify full validation` 父作业。
不要在一次聚焦修复后把完整总控作为首次重跑。如果一个盒子失败请使用失败的子工作流、作业、Docker 通道、包配置文件、模型提供商或 QA 通道作为下一次证明。只有当修复更改了共享发布编排,或让之前的全盒子证据过期时,才再次运行完整总控。总控的最终验证器会重新检查已记录的子工作流运行 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`,以及在提供独立包 Telegram lane 时的 `npm-telegram`
对于有界恢复,将 `rerun_group` 传给总控。`all` 是真正的候选发布运行,`ci` 只运行普通 CI 子项,`plugin-prerelease` 只运行仅发布的插件子项,`release-checks` 运行每个发布盒子,更窄的发布分组包括 `install-smoke`、`cross-os`、`live-e2e`、`package`、`qa`、`qa-parity`、`qa-live`,以及在提供独立包 Telegram 通道时的 `npm-telegram`
### Vitest
Vitest 检查项是手动 `CI` 子 workflow。手动 CI 会有意绕过变更范围,并强制对发布候选运行普通测试图Linux Node 分片、内置插件分片、渠道契约、Node 22 兼容性、`check`、`check-additional`、构建 smoke、文档检查、Python Skills、Windows、macOS、Android 和 Control UI i18n。
Vitest 盒子是手动 `CI` 子工作流。手动 CI 会有意绕过变更范围限定,并强制对候选发布运行普通测试图Linux Node 分片、内置插件分片、渠道契约、Node 22 兼容性、`check`、`check-additional`、构建冒烟、文档检查、Python Skills、Windows、macOS、Android 和 Control UI i18n。
用这个检查项回答“源代码树是否通过了完整普通测试套件?”它不等同于发布路径的产品验证。需要保留的证据:
用这个盒子回答“源代码树是否通过了完整的普通测试套件?”它不同于 release-path 产品验证。需要保留的证据:
- 显示已派发 `CI` 运行 URL 的 `Full Release Validation` 摘要
- 精确目标 SHA 上绿色通过的 `CI` 运行
- 调查回归时 CI 作业中失败或缓慢的分片名称
- 当某次运行需要性能分析时,保留 `.artifacts/vitest-shard-timings.json` 等 Vitest 计时 artifact
- `Full Release Validation` 摘要,显示已分派的 `CI` 运行 URL
- `CI`精确目标 SHA 上绿色
- 调查回归时来自 CI 作业的失败或慢速分片名称
- 运行需要性能分析时的 Vitest 计时工件,例如 `.artifacts/vitest-shard-timings.json`
仅当发布需要确定性的普通 CI而不需要 Docker、QA Lab、live、跨 OS 或包检查项时,才直接运行手动 CI
仅当发布需要确定性的普通 CI但不需要 Docker、QA Lab、实时、跨 OS 或包盒子时,才直接运行手动 CI
```bash
gh workflow run ci.yml --ref main -f target_ref=release/YYYY.M.D
@ -217,50 +217,50 @@ gh workflow run ci.yml --ref main -f target_ref=release/YYYY.M.D
### Docker
Docker 检查项通过 `openclaw-live-and-e2e-checks-reusable.yml` 存在于 `OpenClaw Release Checks` 中,并包含发布模式的 `install-smoke` workflow。它通过打包后的 Docker 环境验证发布候选,而不是只运行源代码级测试。
Docker 盒子位于 `OpenClaw Release Checks` 中,通过 `openclaw-live-and-e2e-checks-reusable.yml` 以及发布模式的 `install-smoke` 工作流提供。它通过打包后的 Docker 环境验证候选发布,而不只是源代码级测试。
发布 Docker 覆盖包括:
- 启用慢速 Bun 全局安装 smoke 的完整 install 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`、`bundled-channels-core`、`bundled-channels-update-a`、`bundled-channels-update-discord`、`bundled-channels-update-b` 和 `bundled-channels-contracts`
- 请求时,在 `plugins-runtime-services` 分块中覆盖 OpenWebUI
- 将内置渠道依赖 lane 拆分到 channel-smoke、update-target 和 setup/runtime contract 分块,而不是一个大型内置渠道作业
- 拆分内置插件安装/卸载 lane `bundled-plugin-install-uninstall-0``bundled-plugin-install-uninstall-23`
- 当发布检查包含 live 套件时,覆盖 live/E2E 提供商套件和 Docker live 模型
- 启用慢速 Bun 全局安装冒烟的完整安装冒烟
- 按目标 SHA 准备/复用根 Dockerfile 冒烟镜像,并将 QR、root/gateway 和 installer/Bun 冒烟作业作为独立 install-smoke 分片运行
- 仓库 E2E 通道
- release-path 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`、`bundled-channels-core`、`bundled-channels-update-a`、`bundled-channels-update-discord`、`bundled-channels-update-b` 和 `bundled-channels-contracts`
- 按请求在 `plugins-runtime-services` 分块内提供 OpenWebUI 覆盖
- 将内置渠道依赖通道拆分到 channel-smoke、update-target 和 setup/runtime contract 分块,而不是一个大型 bundled-channel 作业
- 拆分内置插件安装/卸载通道 `bundled-plugin-install-uninstall-0``bundled-plugin-install-uninstall-23`
- 当发布检查包含实时套件时,包含 live/E2E 提供商套件和 Docker 实时模型覆盖
重跑前先使用 Docker artifact。发布路径调度器会上传 `.artifacts/docker-tests/`,其中包含 lane 日志、`summary.json`、`failures.json`、阶段计时、调度器计划 JSON 和重跑命令。对于聚焦恢复,请在可复用 live/E2E workflow 上使用 `docker_lanes=<lane[,lane]>`,而不是重跑所有发布分块。生成的重跑命令会在可用时包含先前的 `package_artifact_run_id` 和已准备的 Docker 镜像输入,因此失败 lane 可以复用同一个 tarball 和 GHCR 镜像。
重跑前先使用 Docker 工件。release-path 调度器会上传 `.artifacts/docker-tests/`,其中包含通道日志、`summary.json`、`failures.json`、阶段计时、调度器计划 JSON 和重跑命令。对于聚焦恢复,在可复用 live/E2E 工作流上使用 `docker_lanes=<lane[,lane]>`,而不是重跑所有发布分块。生成的重跑命令会在可用时包含之前的 `package_artifact_run_id` 和已准备的 Docker 镜像输入,因此失败通道可以复用相同 tarball 和 GHCR 镜像。
### QA Lab
QA Lab 检查项也是 `OpenClaw Release Checks` 的一部分。它是智能体行为和渠道级发布门禁,独立于 Vitest 和 Docker 包机制。
QA Lab 盒子也是 `OpenClaw Release Checks` 的一部分。它是智能体行为和渠道级发布门禁,独立于 Vitest 和 Docker 包机制。
发布 QA Lab 覆盖包括:
- mock parity gate使用 agentic parity pack 将 OpenAI 候选 lane 与 Opus 4.6 baseline 进行比较
- 使用 `qa-live-shared` 环境的快速 live Matrix QA profile
- 使用 Convex CI 凭证租约的 live Telegram QA lane
- 当发布遥测需要明确本地证明时运行 `pnpm qa:otel:smoke`
- 使用智能体 parity 包对比 OpenAI 候选通道与 Opus 4.6 基线的 mock parity gate
- 使用 `qa-live-shared` 环境的快速实时 Matrix QA 配置文件
- 使用 Convex CI 凭证租约的实时 Telegram QA 通道
- 发布遥测需要显式本地证明时的 `pnpm qa:otel:smoke`
用这个检查项回答“发布在 QA 场景和 live 渠道流程中的行为是否正确?”批准发布时,请保留 parity、Matrix 和 Telegram lane 的 artifact URL。完整 Matrix 覆盖仍可作为手动分片 QA-Lab 运行使用,而不是默认的发布关键 lane
用这个盒子回答“发布在 QA 场景和实时渠道流程中是否行为正确?”批准发布时保留 parity、Matrix 和 Telegram 通道的工件 URL。完整 Matrix 覆盖仍可作为手动分片 QA-Lab 运行使用,而不是默认的发布关键通道
### 包
Package 检查项是可安装产品门禁。它由 `Package Acceptance` 和解析器 `scripts/resolve-openclaw-package-candidate.mjs` 支撑。解析器会将候选归一化为 Docker E2E 使用的 `package-under-test` tarball验证包清单记录包版本和 SHA-256并将 workflow harness ref 与包源 ref 分开。
包盒子是可安装产品门禁。它由 `Package Acceptance` 和解析器 `scripts/resolve-openclaw-package-candidate.mjs` 支撑。解析器会将候选项规范化为供 Docker E2E 使用的 `package-under-test` tarball验证包清单记录包版本和 SHA-256并将工作流 harness 引用与包源引用分开。
支持的候选来源:
- `source=npm``openclaw@beta`、`openclaw@latest` 或精确的 OpenClaw 发布版本
- `source=ref`:使用选定的 `workflow_ref` harness 打包受信任的 `package_ref` 分支、标签或完整提交 SHA
- `source=npm``openclaw@beta`、`openclaw@latest`或精确的 OpenClaw 发布版本
- `source=ref`:使用`workflow_ref` harness 打包受信任的 `package_ref` 分支、标签或完整提交 SHA
- `source=url`:下载 HTTPS `.tgz`,并要求提供 `package_sha256`
- `source=artifact`:复用另一个 GitHub Actions 运行上传的 `.tgz`
`OpenClaw Release Checks` 使用 `source=ref`、`package_ref=<release-ref>`、`suite_profile=custom`、`docker_lanes=bundled-channel-deps-compat plugins-offline` 和 `telegram_mode=mock-openai` 运行 Package Acceptance。发布路径 Docker 分块会覆盖重叠的安装、更新和插件更新 lanePackage Acceptance 会针对同一个已解析 tarball 保留 artifact 原生的内置渠道兼容性、离线插件 fixture 和 Telegram 包 QA。它是 GitHub 原生替代方案,用于替代过去大多数需要 Parallels 的包/更新覆盖。跨 OS 发布检查对于 OS 特定的新手引导、安装器和平台行为仍然重要,但包/更新产品验证应优先使用 Package Acceptance。
`OpenClaw Release Checks` 使用 `source=ref`、`package_ref=<release-ref>`、`suite_profile=custom`、`docker_lanes=bundled-channel-deps-compat plugins-offline` 和 `telegram_mode=mock-openai` 运行 Package Acceptance。release-path Docker 分块覆盖重叠的安装、更新和插件更新通道Package Acceptance 针对同一个已解析 tarball 保留工件原生的内置渠道兼容性、离线插件夹具和 Telegram 包 QA。它是 GitHub 原生替代方案,用来替代以前大多数需要 Parallels 的包/更新覆盖。跨 OS 发布检查对于 OS 特定的新手引导、安装器和平台行为仍然重要,但包/更新产品验证应优先使用 Package Acceptance。
旧版 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 夹具中缺少补丁文件、缺少持久化的 `update.channel`、旧版插件安装记录位置、缺少 marketplace 安装记录持久化,以及 `plugins update` 期间的配置元数据迁移。已发布的 `2026.4.26` 包可能会对已经发布的本地构建元数据戳文件发出警告。之后的包必须满足现代包契约;这些相同缺口会导致发布验证失败。
当发布问题涉及实际可安装包时,使用更广的 Package Acceptance profile
当发布问题涉及实际可安装包时,使用更广泛的 Package Acceptance 配置文件
```bash
gh workflow run package-acceptance.yml \
@ -268,61 +268,76 @@ gh workflow run package-acceptance.yml \
-f workflow_ref=main \
-f source=npm \
-f package_spec=openclaw@beta \
-f suite_profile=product
-f suite_profile=product \
-f published_upgrade_survivor_baseline=openclaw@2026.4.26
```
常见包 profile
常见包配置文件
- `smoke`:快速包安装/渠道/智能体、Gateway 网关网络和配置热重载 lane
- `package`无 live ClawHub 的安装/更新/插件包契约;这是 release-check 默认值
- `smoke`:快速包安装/渠道/智能体、Gateway 网关网络和配置重载通道
- `package`没有实时 ClawHub 的安装/更新/插件包契约;这是 release-check 默认值
- `product``package` 加上 MCP 渠道、cron/subagent 清理、OpenAI web 搜索和 OpenWebUI
- `full`:带 OpenWebUI 的 Docker 发布路径分块
- `full`:带 OpenWebUI 的 Docker release-path 分块
- `custom`:用于聚焦重跑的精确 `docker_lanes` 列表
对于包候选 Telegram 证明,在 Package Acceptance 上启用 `telegram_mode=mock-openai``telegram_mode=live-frontier`。该 workflow 会将已解析的 `package-under-test` tarball 传入 Telegram lane独立 Telegram workflow 仍接受已发布的 npm spec 用于发布后检查。
对于包候选 Telegram 证明,在 Package Acceptance 上启用 `telegram_mode=mock-openai``telegram_mode=live-frontier`。该工作流会将已解析的 `package-under-test` tarball 传入 Telegram 通道;独立 Telegram 工作流仍接受已发布的 npm 规格用于发布后检查。
## NPM workflow 输入
## NPM 工作流输入
`OpenClaw NPM Release` 接受这些由操作者控制的输入:
- `tag`:必需的发布标签,例如 `v2026.4.2`、`v2026.4.2-1` 或 `v2026.4.2-beta.1`;当 `preflight_only=true` 时,也可以是当前完整 40 字符 workflow 分支提交 SHA用于仅验证的 preflight
- `preflight_only``true` 表示验证/构建/打包,`false` 表示真实发布路径
- `preflight_run_id`:真实发布路径必需,以便 workflow 复用成功 preflight 运行中准备好的 tarball
- `npm_dist_tag`:发布路径的 npm 目标标签;默认`beta`
- `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 Checks` 接受这些由操作者控制的输入:
- `ref`:要验证的分支、标签或完整提交 SHA。带 secret 的检查要求解析出的提交可从 OpenClaw 分支或发布标签到达
- `ref`:要验证的分支、标签或完整提交 SHA。带密钥的检查要求解析后的提交可从 OpenClaw 分支或发布标签访问
规则:
- Stable 和 correction 标签可以发布到 `beta``latest`
- 稳定版和修正版标签可以发布到 `beta``latest`
- Beta 预发布标签只能发布到 `beta`
- 对于 `OpenClaw NPM Release`只有在 `preflight_only=true` 时才允许输入完整提交 SHA
- 对于 `OpenClaw NPM Release`仅当 `preflight_only=true`允许输入完整提交 SHA
- `OpenClaw Release Checks``Full Release Validation` 始终仅用于验证
- 真实发布路径必须使用 preflight 期间使用的同一个 `npm_dist_tag`workflow 会在发布继续之前验证该元数据
- 真实发布路径必须使用预检期间使用的同一个 `npm_dist_tag`;工作流会验证发布前的元数据仍然一致
## Stable npm 发布序列
## 稳定 npm 发布顺序
stable npm 发布时:
割稳定 npm 发布时:
1. 使用 `preflight_only=true` 运行 `OpenClaw NPM Release`
- 在标签存在之前,你可以使用当前完整 workflow 分支提交 SHA对 preflight workflow 进行仅验证的 dry run
2. 对普通 beta-first 流程选择 `npm_dist_tag=beta`,或者仅在你有意直接发布 stable 时选择 `latest`
3. 当你希望通过一个手动 workflow 获得普通 CI 加 live prompt cache、Docker、QA Lab、Matrix 和 Telegram 覆盖时,在发布分支、发布标签或完整提交 SHA 上运行 `Full Release Validation`
4. 如果你明确只需要确定性的普通测试图,请改为在发布 ref 上运行手动 `CI` workflow
1. 运行 `OpenClaw NPM Release` 并设置 `preflight_only=true`
- 在标签存在之前,你可以使用当前完整工作流分支的 commit
SHA对预检工作流进行仅验证的试运行
2. 为常规 beta 优先流程选择 `npm_dist_tag=beta`,只有在你明确想要直接发布稳定版时才选择 `latest`
3. 当你想通过一个手动工作流获得常规 CI以及实时提示缓存、Docker、QA Lab、
Matrix 和 Telegram 覆盖时,在发布分支、发布标签或完整
commit SHA 上运行 `Full Release Validation`
4. 如果你明确只需要确定性的常规测试图,请改为在发布 ref 上运行手动
`CI` 工作流
5. 保存成功的 `preflight_run_id`
6. 再次运行 `OpenClaw NPM Release`,并使用 `preflight_only=false`、相同的 `tag`、相同的 `npm_dist_tag` 和已保存的 `preflight_run_id`
7. 如果发布落在 `beta`,使用私有 `openclaw/releases-private/.github/workflows/openclaw-npm-dist-tags.yml` workflow 将该 stable 版本从 `beta` 提升到 `latest`
8. 如果发布有意直接发布到 `latest`,并且 `beta` 应立即跟随同一个 stable 构建,请使用同一个私有 workflow 将两个 dist-tag 都指向 stable 版本,或让它的定时自愈同步稍后移动 `beta`
6. 再次运行 `OpenClaw NPM Release`,并设置 `preflight_only=false`、相同的
`tag`、相同的 `npm_dist_tag`,以及保存的 `preflight_run_id`
7. 如果发布落在 `beta` 上,请使用私有的
`openclaw/releases-private/.github/workflows/openclaw-npm-dist-tags.yml`
工作流,将该稳定版本从 `beta` 提升到 `latest`
8. 如果发布有意直接发布到 `latest`,并且 `beta`
应立即跟随同一个稳定构建,请使用同一个私有
工作流让两个 dist-tag 都指向该稳定版本,或让它的定时
自修复同步稍后移动 `beta`
dist-tag 变更位于私有仓库中,这是出于安全考虑,因为它仍然需要 `NPM_TOKEN`,而公共仓库保持仅 OIDC 发布。
出于安全原因dist-tag 变更位于私有仓库中,因为它仍然
需要 `NPM_TOKEN`,而公共仓库保持仅 OIDC 发布。
这样可以让直接发布路径和 beta-first 提升路径都被记录在文档中,并且对操作者可见。
这会让直接发布路径和 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)
@ -338,6 +353,6 @@ dist-tag 变更位于私有仓库中,这是出于安全考虑,因为它仍
[`openclaw/maintainers/release/README.md`](https://github.com/openclaw/maintainers/blob/main/release/README.md)
中的私有发布文档作为实际运行手册。
## 相关内容
## 相关
- [发布渠道](/zh-CN/install/development-channels)

View File

@ -4,57 +4,57 @@ read_when:
summary: 如何在本地运行测试vitest以及何时使用强制/覆盖率模式
title: 测试
x-i18n:
generated_at: "2026-04-30T23:43:52Z"
generated_at: "2026-05-01T02:59:50Z"
model: gpt-5.5
provider: openai
source_hash: de18ac7d822055ee34885e5e897eff0fe7dde57c945a6b7f2c4bb2a29445c859
source_hash: 4d50f77fdb8dcf7153c59d1bd9f3d61d745ba17ea846eb0610d0f064ad0d1761
source_path: reference/test.md
workflow: 16
---
- 完整测试工具包(套件、真实环境测试、Docker[测试](/zh-CN/help/testing)
- 完整测试工具包(套件、实时、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所以该门禁衡量的是单元覆盖率套件加载的文件,而不是把每个拆分通道源文件都视为未覆盖。
- `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`:低成本的智能变更测试运行。它会从直接测试编辑、相邻的 `*.test.ts` 文件、显式源映射和本地导入图运行精确目标。宽泛/配置/package 变更会被跳过,除非它们映射到精确测试。
- `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`:显式的宽泛变更测试运行。当测试 harness、配置或 package 编辑应回退到 Vitest 更宽泛的变更测试行为时使用
- `pnpm test:changed`:低成本的智能变更测试运行。它会根据直接测试编辑、同级 `*.test.ts` 文件、显式源映射和本地导入图运行精确目标。宽泛的配置/包变更会被跳过,除非它们映射到精确测试。
- `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`:显式的宽泛变更测试运行。当测试 harness/配置/包编辑应回退到 Vitest 更宽泛的变更测试行为时使用。
- `pnpm changed:lanes`:显示相对于 `origin/main` 的 diff 触发的架构通道。
- `pnpm check:changed`:对相对于 `origin/main` 的 diff 运行智能变更检查门禁。它会为受影响的架构通道运行 typecheck、lint 和 guard 命令,但不会运行 Vitest 测试。使用 `pnpm test:changed` 或显式的 `pnpm test <target>` 提供测试证明。
- `pnpm test`:将显式文件/目录目标路由到有作用域的 Vitest 通道。无目标运行使用固定分片组,并展开为叶级配置以进行本地并行执行;插件组始终展开为按插件划分的分片配置,而不是一个巨大的根项目进程。
- 测试包装器运行结束时会输出简短的 `[test] passed|failed|skipped ... in ...` 摘要。Vitest 自己的耗时行保留为每个分片的详细信息
- `pnpm check:changed`对相对于 `origin/main` 的 diff 运行智能变更检查门禁。它会为受影响的架构通道运行类型检查、lint 和守护命令,但不会运行 Vitest 测试。使用 `pnpm test:changed` 或显式 `pnpm test <target>` 作为测试证明。
- `pnpm test`:将显式文件/目录目标路由到有作用域的 Vitest 通道。未指定目标的运行使用固定分片组,并展开为叶子配置以便本地并行执行;插件组始终展开为按插件划分的分片配置,而不是一个巨大的根项目进程。
- 测试包装器运行结束时会输出一条简短的 `[test] passed|failed|skipped ... in ...` 摘要。Vitest 自己的时长行仍保留为每个分片的详情
- 共享 OpenClaw 测试状态:当测试需要隔离的 `HOME`、`OPENCLAW_STATE_DIR`、`OPENCLAW_CONFIG_PATH`、配置 fixture、工作区、智能体目录或 auth-profile 存储时,在 Vitest 中使用 `src/test-utils/openclaw-test-state.ts`
- 进程 E2E 辅助工具:当 Vitest 进程级 E2E 测试需要在一处完成运行中的 Gateway 网关、CLI 环境、日志捕获和清理时,使用 `test/helpers/openclaw-test-instance.ts`
- Docker/Bash E2E 辅助工具source `scripts/lib/docker-e2e-image.sh` 的通道可以 `docker_e2e_test_state_shell_b64 <label> <scenario>` 传入容器,并用 `scripts/lib/openclaw-e2e-instance.sh` 解码;多 home 脚本可以传入 `docker_e2e_test_state_function_b64`,并在每个流程中调用 `openclaw_test_state_create <label> <scenario>`。更底层的调用方可以使用 `scripts/lib/openclaw-test-state.mjs shell --label <name> --scenario <name>` 生成容器内 shell 片段,或使用 `node scripts/lib/openclaw-test-state.mjs -- create --label <name> --scenario <name> --env-file <path> --json` 生成可 source 的宿主环境文件。`create` 前面的 `--`防止较新的 Node 运行时把 `--env-file` 当作 Node 标志处理。启动 Gateway 网关的 Docker/Bash 通道可以在容器内 source `scripts/lib/openclaw-e2e-instance.sh`,用于入口点解析、模拟 OpenAI 启动、Gateway 网关前台/后台启动、就绪探、状态环境导出、日志转储和进程清理。
- 完整、插件和 include-pattern 分片运行会更新 `.artifacts/vitest-shard-timings.json` 中的本地计时数据;之后的整配置运行会使用这些计时来平衡慢分片和快分片。Include-pattern CI 分片会把分片名称追加到计时键中,这样筛选后的分片计时仍然可见,而不会替换整配置计时数据。设置 `OPENCLAW_TEST_PROJECTS_TIMINGS=0` 可忽略本地计时产物
- 选定的 `plugin-sdk``commands` 测试文件现在会通过专用轻量通道路由,这些通道只保留 `test/setup.ts`,而运行时较重的用例仍留在现有通道上。
- 带有相邻测试的源文件会先映射到该相邻测试,然后再回退到更宽的目录 glob。`src/channels/plugins/contracts/test-helpers`、`src/plugin-sdk/test-helpers` 和 `src/plugins/contracts` 下的辅助工具编辑会使用本地导入图来运行导入它们的测试,而不是在依赖路径精确时宽泛运行每个分片。
- `auto-reply` 现在也拆分为三个专用配置(`core`、`top-level`、`reply`),这样 reply harness 不会压过更轻量的顶层 status/token/helper 测试。
- 基础 Vitest 配置现在默认使用 `pool: "threads"``isolate: false`,并在整个仓库配置中启用共享的非隔离 runner。
- 进程 E2E 辅助工具:当 Vitest 进程级 E2E 测试需要一个运行中的 Gateway 网关、CLI 环境、日志捕获和统一清理时,使用 `test/helpers/openclaw-test-instance.ts`
- Docker/Bash E2E 辅助工具source `scripts/lib/docker-e2e-image.sh` 的通道可以 `docker_e2e_test_state_shell_b64 <label> <scenario>` 传入容器,并用 `scripts/lib/openclaw-e2e-instance.sh` 解码;多 home 脚本可以传入 `docker_e2e_test_state_function_b64`,并在每个流程中调用 `openclaw_test_state_create <label> <scenario>`。更底层的调用方可以使用 `scripts/lib/openclaw-test-state.mjs shell --label <name> --scenario <name>` 生成容器内 shell 片段,或使用 `node scripts/lib/openclaw-test-state.mjs -- create --label <name> --scenario <name> --env-file <path> --json` 生成可 source 的宿主机环境文件。`create` 前面的 `--`防止较新的 Node 运行时把 `--env-file` 当作 Node 标志处理。启动 Gateway 网关的 Docker/Bash 通道可以在容器内 source `scripts/lib/openclaw-e2e-instance.sh`,用于入口点解析、模拟 OpenAI 启动、Gateway 网关前台/后台启动、就绪探、状态环境导出、日志转储和进程清理。
- 完整、插件和 include-pattern 分片运行会更新 `.artifacts/vitest-shard-timings.json` 中的本地计时数据;后续 whole-config 运行会使用这些计时来平衡慢分片和快分片。Include-pattern CI 分片会把分片名称追加到计时键中,这样可以在不替换 whole-config 计时数据的情况下保留过滤后的分片计时。设置 `OPENCLAW_TEST_PROJECTS_TIMINGS=0` 可忽略本地计时 artifact
- 选定的 `plugin-sdk``commands` 测试文件现在会路由到专用轻量通道,这些通道只保留 `test/setup.ts`,而运行时较重的用例仍留在现有通道上。
- 带同级测试的源文件会先映射到该同级测试,然后再回退到更宽的目录 glob。`src/channels/plugins/contracts/test-helpers`、`src/plugin-sdk/test-helpers` 和 `src/plugins/contracts` 下的辅助工具编辑会使用本地导入图来运行导入它们的测试,而不是在依赖路径精确时宽泛运行每个分片。
- `auto-reply` 现在也拆分为三个专用配置(`core`、`top-level`、`reply`),这样 reply harness 不会主导更轻量的顶层状态/token/辅助工具测试。
- 基础 Vitest 配置现在默认使用 `pool: "threads"``isolate: false`,并在仓库配置中启用共享的非隔离 runner。
- `pnpm test:channels` 运行 `vitest.channels.config.ts`
- `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-mode 路径与原生根项目运行进行基准测试
- `pnpm test:perf:changed:bench -- --worktree` 会在不先提交的情况下,对当前 worktree 变更集进行基准测试。
- `pnpm test:perf:imports`:启用 Vitest 导入时长 + 导入拆解报告,同时仍对显式文件/目录目标使用有作用域的通道路由。
- `pnpm test:perf:imports:changed`:相同的导入分析,但针对自 `origin/main` 以来变更的文件。
- `pnpm test:perf:changed:bench -- --ref <git-ref>` 会针对同一个已提交 git diff比基于路由的变更模式路径与原生根项目运行的基准表现
- `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 + heap 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`:在面向性能的变更后比较分组报告。
- `pnpm test:perf:groups --full-suite --allow-failures --output .artifacts/test-perf/baseline-before.json`:串行运行每个完整套件的 Vitest 叶子配置,并写入分组时长数据以及每个配置的 JSON/日志 artifact。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 网关端到端冒烟测试(多实例 WS/HTTP/node 配对)。默认使用 `threads` + `isolate: false`,并在 `vitest.e2e.config.ts` 中使用自适应 worker`OPENCLAW_E2E_WORKERS=<n>` 调整,并设置 `OPENCLAW_E2E_VERBOSE=1` 输出详细日志。
- `pnpm test:live`:运行提供商 live 测试minimax/zai。需要 API keys`LIVE=1`(或提供商特定的 `*_LIVE_TEST=1`)才能取消跳过。
- `pnpm test:docker:all`:构建共享 live-test 镜像,将 OpenClaw 一次打包为 npm tarball构建/复用一个裸 Node/Git runner 镜像以及一个把该 tarball 安装到 `/app` 的功能镜像,然后通过加权调度器 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行 Docker 冒烟通道。裸镜像(`OPENCLAW_DOCKER_E2E_BARE_IMAGE`)用于 installer/update/plugin-dependency 通道;这些通道挂载预构建 tarball而不是使用复制的仓库源。功能镜像`OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE`)用于普通内置应用功能通道。`scripts/package-openclaw-for-docker.mjs` 是唯一的本地/CI package packer并会在 Docker 使用前校验 tarball 和 `dist/postinstall-inventory.json`。Docker 通道定义位于 `scripts/lib/docker-e2e-scenarios.mjs`planner 逻辑位于 `scripts/lib/docker-e2e-plan.mjs``scripts/test-docker-all.mjs` 执行选定计划。`node scripts/test-docker-all.mjs --plan-json` 会为选定通道、镜像类型、package/live-image 需求、状态场景和凭证检查输出由调度器拥有的 CI 计划,而不构建或运行 Docker。`OPENCLAW_DOCKER_ALL_PARALLELISM=<n>` 控制进程槽位,默认值为 10`OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM=<n>` 控制提供商敏感的尾部池,默认值为 10。重型通道上限默认为 `OPENCLAW_DOCKER_ALL_LIVE_LIMIT=9`、`OPENCLAW_DOCKER_ALL_NPM_LIMIT=10` 和 `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7`;提供商上限默认通过 `OPENCLAW_DOCKER_ALL_LIVE_CLAUDE_LIMIT=4`、`OPENCLAW_DOCKER_ALL_LIVE_CODEX_LIMIT=4` 和 `OPENCLAW_DOCKER_ALL_LIVE_GEMINI_LIMIT=4` 为每个提供商设置一个重型通道。更大的宿主机可使用 `OPENCLAW_DOCKER_ALL_WEIGHT_LIMIT``OPENCLAW_DOCKER_ALL_DOCKER_LIMIT`。如果某个通道在低并行度宿主机上超过有效权重或资源上限,它仍可从空池启动,并会独自运行,直到释放容量。默认情况下通道启动会错开 2 秒,以避免本地 Docker daemon 出现创建风暴;可用 `OPENCLAW_DOCKER_ALL_START_STAGGER_MS=<ms>` 覆盖。runner 默认会预检 Docker、清理陈旧的 OpenClaw E2E 容器、每 30 秒输出活动通道状态、在兼容通道之间共享提供商 CLI 工具缓存、默认重试一次暂时性的 live-provider 失败(`OPENCLAW_DOCKER_ALL_LIVE_RETRIES=<n>`),并通道计时存储到 `.artifacts/docker-tests/lane-timings.json`,供后续运行按最长优先排序。使用 `OPENCLAW_DOCKER_ALL_DRY_RUN=1` 可打印通道清单而不运行 Docker使用 `OPENCLAW_DOCKER_ALL_STATUS_INTERVAL_MS=<ms>` 可调整状态输出,或使用 `OPENCLAW_DOCKER_ALL_TIMINGS=0` 禁用计时复用。使用 `OPENCLAW_DOCKER_ALL_LIVE_MODE=skip` 仅运行确定性/本地通道,或使用 `OPENCLAW_DOCKER_ALL_LIVE_MODE=only` 仅运行 live-provider 通道package 别名为 `pnpm test:docker:local:all``pnpm test:docker:live:all`。Live-only 模式会把 main 和 tail live 通道合并为一个最长优先池,这样提供商桶可以把 Claude、Codex 和 Gemini 工作打包在一起。除非设置了 `OPENCLAW_DOCKER_ALL_FAIL_FAST=0`runner 会在第一次失败后停止调度新的池化通道,并且每个通道都有 120 分钟的兜底超时,可用 `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS` 覆盖;选定的 live/tail 通道使用更严格的通道上限。CLI 后端 Docker 设置命令有自己的超时,通过 `OPENCLAW_LIVE_CLI_BACKEND_SETUP_TIMEOUT_SECONDS` 置(默认 180。每通道日志、`summary.json`、`failures.json` 和阶段计时会写入 `.artifacts/docker-tests/<run-id>/` 下;使用 `pnpm test:docker:timings <summary.json>` 查慢通道,使用 `pnpm test:docker:rerun <run-id|summary.json|failures.json>` 打印低成本的定向重跑命令。
- `pnpm test:docker:browser-cdp-snapshot`:构建一个基于 Chromium 的 source E2E 容器,启动原始 CDP 加隔离的 Gateway 网关,运行 `browser doctor --deep`,并验证 CDP role 快照包含链接 URL、光标提升的可点击项、iframe refs 和 frame 元数据。
- CLI 后端 live Docker 探针可以作为聚焦通道运行,例如 `pnpm test:docker:live-cli-backend:codex`、`pnpm test:docker:live-cli-backend:codex:resume` 或 `pnpm test:docker:live-cli-backend:codex:mcp`。Claude 和 Gemini 有匹配`:resume``:mcp` 别名。
- `pnpm test:docker:openwebui`:启动 Docker 化的 OpenClaw + Open WebUI通过 Open WebUI 登录,检查 `/api/models`,然后通过 `/api/chat/completions` 运行一次真实的代理聊天。需要可用的 live 模型 key例如 `~/.profile` 中的 OpenAI,会拉取外部 Open WebUI 镜像,且不期望像普通 unit/e2e 套件一样具备 CI 稳定性。
- `pnpm test:docker:mcp-channels`:启动一个已种子的 Gateway 网关容器和第二个客户端容器,后者会启动 `openclaw mcp serve`,然后通过真实 stdio bridge 验证路由后的对话发现、transcript 读取、附件元数据、live 事件队列行为、出站发送路由,以及 Claude 风格的渠道 + permission 通知。Claude 通知断言会直接读取原始 stdio MCP 帧,因此该冒烟测试反映的是 bridge 实际发出的内容。
- `pnpm test:docker:upgrade-survivor`:将打包好的 OpenClaw tar 包安装到脏的旧用户夹具上,运行包更新以及不需要实时提供商或渠道密钥的非交互式 Doctor然后启动回环 Gateway 网关,并检查智能体、渠道配置、插件允许列表、工作区/会话文件、过期的插件 runtime-deps 状态、启动和 RPC Status 是否保留下来
- `pnpm test:docker:published-upgrade-survivor`:默认`openclaw@latest` 安装到脏的旧用户夹具上,将该已发布安装更新为打包好的 OpenClaw tar 包,然后运行相同的 Doctor、Gateway 网关启动和 RPC 保留断言。可使`OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPEC` 覆盖基线。
- `pnpm test:e2e`:运行 Gateway 网关端到端冒烟测试(多实例 WS/HTTP/node 配对)。默认使用 `threads` + `isolate: false`,并在 `vitest.e2e.config.ts` 中使用自适应 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 镜像,将 OpenClaw 打包一次为 npm tarball构建/复用一个裸 Node/Git runner 镜像以及一个把该 tarball 安装到 `/app` 的功能镜像,然后通过加权调度器 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行 Docker 冒烟通道。裸镜像(`OPENCLAW_DOCKER_E2E_BARE_IMAGE`)用于安装器/更新/插件依赖通道;这些通道挂载预构建 tarball而不是使用复制的仓库源代码。功能镜像(`OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE`)用于常规构建应用功能通道。`scripts/package-openclaw-for-docker.mjs` 是唯一的本地/CI 包打包器,会在 Docker 使用前验证 tarball 和 `dist/postinstall-inventory.json`。Docker 通道定义位于 `scripts/lib/docker-e2e-scenarios.mjs`规划器逻辑位于 `scripts/lib/docker-e2e-plan.mjs``scripts/test-docker-all.mjs` 执行选定计划。`node scripts/test-docker-all.mjs --plan-json` 会输出由调度器拥有的 CI 计划,用于选定通道、镜像种类、包/live-image 需求、状态场景和凭证检查,而不会构建或运行 Docker。`OPENCLAW_DOCKER_ALL_PARALLELISM=<n>` 控制进程槽位,默认值为 10`OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM=<n>` 控制提供商敏感的尾部池,默认值为 10。重型通道上限默认`OPENCLAW_DOCKER_ALL_LIVE_LIMIT=9`、`OPENCLAW_DOCKER_ALL_NPM_LIMIT=10` 和 `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7`;提供商上限默认通过 `OPENCLAW_DOCKER_ALL_LIVE_CLAUDE_LIMIT=4`、`OPENCLAW_DOCKER_ALL_LIVE_CODEX_LIMIT=4` 和 `OPENCLAW_DOCKER_ALL_LIVE_GEMINI_LIMIT=4` 设置为每个提供商一个重型通道。更大的主机可使用 `OPENCLAW_DOCKER_ALL_WEIGHT_LIMIT``OPENCLAW_DOCKER_ALL_DOCKER_LIMIT`。如果某个通道在低并行度主机上超过有效权重或资源上限,它仍可以从空池启动,并会独占运行直到释放容量。通道启动默认错开 2 秒,以避免本地 Docker daemon 出现 create 风暴;可用 `OPENCLAW_DOCKER_ALL_START_STAGGER_MS=<ms>` 覆盖。runner 默认会预检 Docker、清理陈旧的 OpenClaw E2E 容器、每 30 秒输出活动通道状态、在兼容通道之间共享提供商 CLI 工具缓存、默认重试一次瞬时 live-provider 失败(`OPENCLAW_DOCKER_ALL_LIVE_RETRIES=<n>`),并通道计时存储到 `.artifacts/docker-tests/lane-timings.json`,供后续运行按最长优先排序。使用 `OPENCLAW_DOCKER_ALL_DRY_RUN=1` 可打印通道 manifest 而不运行 Docker使用 `OPENCLAW_DOCKER_ALL_STATUS_INTERVAL_MS=<ms>` 可调整状态输出,或使用 `OPENCLAW_DOCKER_ALL_TIMINGS=0` 禁用计时复用。使用 `OPENCLAW_DOCKER_ALL_LIVE_MODE=skip` 只运行确定性/本地通道,或使用 `OPENCLAW_DOCKER_ALL_LIVE_MODE=only` 只运行 live-provider 通道;包别名为 `pnpm test:docker:local:all``pnpm test:docker:live:all`。Live-only 模式会把主 live 通道和尾部 live 通道合并到一个按最长优先的池中,让提供商桶可以把 Claude、Codex 和 Gemini 工作打包在一起。runner 会在第一次失败后停止调度新的池化通道,除非设置了 `OPENCLAW_DOCKER_ALL_FAIL_FAST=0`;每个通道都有 120 分钟的后备超时,可通过 `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS` 覆盖;选定的 live/tail 通道使用更严格的通道上限。CLI 后端 Docker 设置命令有自己的超时,通过 `OPENCLAW_LIVE_CLI_BACKEND_SETUP_TIMEOUT_SECONDS` 置(默认 180。每通道日志、`summary.json`、`failures.json` 和阶段计时会写入 `.artifacts/docker-tests/<run-id>/` 下;使用 `pnpm test:docker:timings <summary.json>`慢通道,使用 `pnpm test:docker:rerun <run-id|summary.json|failures.json>` 打印低成本的定向重跑命令。
- `pnpm test:docker:browser-cdp-snapshot`:构建基于 Chromium 的源码 E2E 容器,启动原始 CDP 加隔离 Gateway 网关,运行 `browser doctor --deep`,并验证 CDP 角色快照包含链接 URL、光标提升的可点击项、iframe ref 和 frame 元数据。
- CLI 后端 live Docker 探针可以作为聚焦通道运行,例如 `pnpm test:docker:live-cli-backend:codex`、`pnpm test:docker:live-cli-backend:codex:resume` 或 `pnpm test:docker:live-cli-backend:codex:mcp`。Claude 和 Gemini 有对应`:resume``:mcp` 别名。
- `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`然后验证路由式会话发现、转录读取、附件元数据、live 事件队列行为、出站发送路由,以及通过真实 stdio bridge 发送的 Claude 风格渠道 + 权限通知。Claude 通知断言会直接读取原始 stdio MCP frame因此该冒烟测试反映 bridge 实际发出的内容。
- `pnpm test:docker:upgrade-survivor`:将打包的 OpenClaw tar 包安装到脏的旧用户 fixture 上,在没有实时提供商或渠道密钥的情况下运行软件包更新和非交互式 Doctor然后启动 local loopback Gateway 网关,并检查智能体、渠道配置、插件 allowlist、工作区/会话文件、过期的插件 runtime-deps 状态、启动和 RPC Status 是否保留。
- `pnpm test:docker:published-upgrade-survivor`:默认安装 `openclaw@latest`,在没有实时提供商或渠道密钥的情况下植入真实的现有用户文件,使用内置的 `openclaw config set` 命令配方配置该基线,将该已发布安装更新为打包的 OpenClaw tar 包,运行非交互式 Doctor写入 `.artifacts/upgrade-survivor/summary.json`,然后启动 local loopback Gateway 网关,并检查已配置的 intent、工作区/会话文件、过期的插件配置/runtime-deps 状态、启动和 RPC Status 是否保留或干净修复。可`OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPEC` 覆盖基线Package Acceptance 将同一值公开为 `published_upgrade_survivor_baseline`
## 本地 PR 门禁
对于本地 PR 落地/门禁检查,运行:
对于本地 PR 合并/门禁检查,运行:
- `pnpm check:changed`
- `pnpm check`
@ -63,7 +63,7 @@ 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`
@ -76,12 +76,12 @@ x-i18n:
- `source ~/.profile && pnpm tsx scripts/bench-model.ts --runs 10`
- 可选环境变量:`MINIMAX_API_KEY`、`MINIMAX_BASE_URL`、`MINIMAX_MODEL`、`ANTHROPIC_API_KEY`
- 默认提示词:“回复一个单词ok。不要标点或额外文本。”
- 默认提示词“回复一个单词ok。不要标点或额外文本。”
上次运行2025-12-3120 次运行):
- minimax 中位数 1279 ms最小 1114最大 2431
- opus 中位数 2454 ms最小 1224最大 3170
- minimax 中位数 1279ms最小 1114最大 2431
- opus 中位数 2454ms最小 1224最大 3170
## CLI 启动基准测试
@ -111,41 +111,41 @@ x-i18n:
- `real``health`、`status`、`status --json`、`sessions`、`sessions --json`、`tasks --json`、`tasks list --json`、`tasks audit --json`、`agents list --json`、`gateway status`、`gateway status --json`、`gateway health --json`、`config get gateway.port`
- `all`:两个预设
输出包 `sampleCount`、平均值、p50、p95、最小/最大值、退出码/信号分布,以及每条命令的最大 RSS 摘要。可选的 `--cpu-prof-dir` / `--heap-prof-dir` 会为每次运行写入 V8 配置文件,使计时和配置文件捕获使用同一套测试框架
输出包含每条命令的 `sampleCount`、平均值、p50、p95、最小/最大值、退出码/信号分布,以及最大 RSS 摘要。可选的 `--cpu-prof-dir` / `--heap-prof-dir` 会为每次运行写入 V8 profile使计时和 profile 采集使用同一套 harness
已保存输出约定:
- `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`
- `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`
已签入夹具
已签入的 fixture
- `test/fixtures/cli-startup-bench.json`
- 使用 `pnpm test:startup:bench:update` 刷新
- 使用 `pnpm test:startup:bench:check` 将当前结果与夹具比较
- 使用 `pnpm test:startup:bench:check` 将当前结果与 fixture 比较
## 新手引导 E2EDocker
Docker 是可选的;仅容器化新手引导烟雾测试需要它。
Docker 是可选的;仅容器化新手引导 smoke 测试需要它。
在干净 Linux 容器中的完整冷启动流程:
在干净的 Linux 容器中运行完整冷启动流程:
```bash
scripts/e2e/onboard-docker.sh
```
脚本通过伪 tty 驱动交互式向导,验证配置/工作区/会话文件,然后启动 Gateway 网关并运行 `openclaw health`
脚本通过伪 tty 驱动交互式向导,验证配置/工作区/会话文件,然后启动 Gateway 网关并运行 `openclaw health`
## QR 导入烟雾测试Docker
## QR 导入 smokeDocker
确保维护的 QR 运行时辅助工具可在支持的 Docker Node 运行时下加载(默认 Node 24兼容 Node 22
确保维护中的 QR 运行时 helper 可以在受支持的 Docker Node 运行时下加载Node 24 默认Node 22 兼容
```bash
pnpm test:docker:qr
```
## 相关
## 相关内容
- [测试](/zh-CN/help/testing)
- [实时测试](/zh-CN/help/testing-live)