openclaw-cn npm 发布完整指南:从本地打包、手动发布到 GitHub Actions 自动发版
openclaw-cn npm 发布完整指南:从本地打包、手动发布到 GitHub Actions 自动发版
本文是 openclaw-cn(OpenClaw 中文社区版)发布到 npm 的端到端实操指南,覆盖账号与 Access Token 准备、GitHub Actions Secret 配置、本地 pnpm pack 预检、手动 pnpm publish、基于版本 tag 的自动化发布流程,以及发布后的验证、撤销与版本管理策略。读完本文,你将掌握一套可复现的 npm 发版流程,并能对照仓库中的 .github/workflows/npm-publish.yml 与 package.json 理解每个环节的底层实现。
发布物是什么:openclaw-cn 的 npm 包形态
在动手发布前,先了解这个包"长什么样"。openclaw-cn 是发布到 npm registry 的 CLI 包,用户通过一条命令即可全局安装:
npm install -g openclaw-cn@latest
安装后可直接运行 openclaw-cn(旧版别名 clawdbot-cn 依然可用),详见 README.md 的快速开始部分。包的组成由根目录 package.json 控制,几个关键字段决定了发布行为:
bin字段(package.json):同时注册clawdbot-cn、openclaw、openclaw-cn三个命令,全部指向dist/entry.js,保证历史兼容。files白名单(package.json):显式声明发布内容,包括dist/**全部构建产物、docs/**、skills/**、CHANGELOG.md、README.md、LICENSE、git-hooks/**、patches/**以及各extensions/*的源码与清单文件,同时排除extensions/feishu/**。exports与main(package.json):入口为dist/index.js,并暴露./plugin-sdk子路径供插件导入。engines(package.json):要求node >= 22.12.0,这是安装端的最低运行门槛。packageManager(package.json):锁定pnpm@10.23.0,发布流水线与本地构建均使用 pnpm。prepack钩子(package.json):执行pnpm build && pnpm ui:build,确保任何pack/publish前产物已是最新构建。
另外 .gitignore 中默认排除 dist 目录,但通过 !dist/control-ui/ 例外保留了 Web 控制台产物(见 .gitignore),这是为了让控制台 UI 也能随 npm 包分发。
前置准备:npm 账号、Access Token 与 GitHub Secrets
正式发布前需要完成三项准备,它们分别对应"身份认证"、"仓库侧密钥存储"和"CI 读取密钥"三个环节。
1. 注册 npm 账号
如果还没有 npm 账号,前往 npm 官网的注册页面完成注册。账号必须能通过邮箱验证,因为发布包与后续生成 token 都依赖有效账号。
2. 创建 npm Access Token(推荐 Automation 类型)
登录 npm 官网后,点击右上角头像进入 Access Tokens 页面,选择 Generate New Token,在 token 类型中选择 Automation。Automation 类型 token 专为 CI/CD 场景设计,权限仅覆盖包的读取与发布,不包含账号资料读写等敏感权限,比经典(Classic)token 更适合放入 GitHub Secrets。生成后复制 token,其格式类似 npm_xxxxxxxxxxxxxx。
从源码视角看,这个 token 最终会注入发布命令的环境变量:工作流中通过
env.NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}传递给pnpm publish(见 .github/workflows/npm-publish.yml),pnpm/npm 会将其识别为 npm registry 的认证凭据。
3. 配置 GitHub Secrets
进入你的 GitHub 仓库页面,依次打开 Settings → Secrets and variables → Actions,点击 New repository secret:
- Name:
NPM_TOKEN - Value:粘贴上一步复制的 npm token
保存后,仓库的 GitHub Actions 工作流即可通过 secrets.NPM_TOKEN 读取该值。注意 GitHub 不会显示已保存的 secret 内容,如需轮换只能新建覆盖。
本地测试发布:先打包,不发布
在正式触网发布前,强烈建议在本地完整走一遍"构建 + 打包 + 安装验证",这能提前暴露构建失败、产物缺失等问题。原文档给出的流程如下:
# 构建项目(TypeScript 编译 + UI 资源)
pnpm build
pnpm ui:build
# 打包(只生成 tarball,不上传 registry)
pnpm pack
pnpm build实际执行的是tsc -p tsconfig.json,随后依次调用scripts/canvas-a2ui-copy.ts、scripts/copy-hook-metadata.ts和scripts/write-build-info.ts(见 package.json)。其中write-build-info.ts会把package.json的version、当前 git commit 和构建时间写入dist/build-info.json,让每个包都能追溯对应源码版本。pnpm ui:build通过 scripts/ui.js 进入ui/目录执行 Vite 构建,产物落入dist/control-ui/(这正是.gitignore里单独放行该目录的原因)。pnpm pack触发prepack钩子再次构建,然后生成openclaw-cn-<版本号>.tgz,例如:
npm install -g ./openclaw-cn-2026.1.25.tgz
用全局安装的方式测试 tarball,可以模拟用户侧的安装体验,验证 openclaw-cn 命令能否正常拉起。若安装后执行命令报缺依赖,多半是依赖声明问题——仓库曾在 0.1.9 中修复过全局安装时 strip-ansi 幽灵依赖导致 ERR_MODULE_NOT_FOUND 的案例(见 CHANGELOG.md),这正是"本地先装一次"能捕获的问题类型。
用 release-check 做发布前体检
仓库还提供了专门的发布体检脚本 scripts/release-check.ts,建议在打包前执行:
pnpm release:check
它会做两件事:
- npm pack 内容校验:以
--dry-run --ignore-scripts方式模拟打包,断言dist/discord/send.js、dist/hooks/gmail.js、dist/whatsapp/normalize.js等关键产物必须存在,同时禁止任何dist/Clawdbot.app/前缀的 macOS 打包残留进入 npm 包。 - 插件版本对齐校验:遍历
extensions/*目录,要求每个插件的package.jsonversion 与根包一致,否则报错并提示先运行pnpm plugins:sync。
手动发布到 npm:一条龙直发
如果不希望依赖 CI,也可以直接在本地完成发布。原文档给出的手动流程是:
# 1. 登录 npm(首次执行,后续会记住凭据)
npm login
# 2. 构建项目
pnpm build
pnpm ui:build
# 3. 发布(公开无 scope 包)
pnpm publish --access public
补充几个实操要点:
npm login会要求输入用户名、密码和一次性验证码(若开启 2FA),建议在干净终端执行;登录状态保存在本机~/.npmrc,CI 环境不需要此步骤。pnpm publish --access public中的--access public对无 scope 的包(如openclaw-cn)其实不是必须的,但对@scope/命名空间下的包则是硬性要求;保留该参数可保证在任何命名下都以公开包发布。- 发布同样会触发
prepack钩子自动构建,所以即使漏了前两步构建,publish也会尝试补齐,但显式先构建能更快定位问题。 - 发布前请确认本地
node版本满足engines要求(≥ 22.12.0),避免构建产物与运行环境不一致。
通过 GitHub Actions 自动发布:打 tag 即发版
手动发布适合零星发版,但更稳妥的做法是把发布交给 CI。仓库已经内置了完整的自动发布工作流 .github/workflows/npm-publish.yml,整个流程由"打 tag"这一个动作触发。
工作流内部做了什么
该工作流在 push 事件中监听 v* 开头的 tag(.github/workflows/npm-publish.yml),即任何 v<版本号> 的 tag 推送都会触发发布。其执行步骤可以拆解为:
- Checkout:
actions/checkout@v4拉取代码,fetch-depth: 0确保拿到完整历史(供后续 commit 信息写入)。 - Setup pnpm:
pnpm/action-setup@v4固定 pnpm 版本为10.23.0,与packageManager字段一致。 - Setup Node.js:
actions/setup-node@v4安装 Node 22,并设置registry-url指向 npm 官方源、启用 pnpm 缓存。 - 安装依赖:
pnpm install --frozen-lockfile——严格按pnpm-lock.yaml安装,保证 CI 与本地依赖一致,杜绝"本地能过 CI 挂"。 - 构建:依次执行
pnpm build和pnpm ui:build。 - 判定 npm dist-tag:核心逻辑(.github/workflows/npm-publish.yml)根据 git tag 是否包含
-test、-beta、-alpha后缀,把发布通道映射为test、beta、alpha,否则走默认的latest:
GIT_TAG=${GITHUB_REF#refs/tags/v}
if [[ "$GIT_TAG" == *"-test"* ]]; then
echo "tag=test"
elif [[ "$GIT_TAG" == *"-beta"* ]]; then
echo "tag=beta"
elif [[ "$GIT_TAG" == *"-alpha"* ]]; then
echo "tag=alpha"
else
echo "tag=latest"
fi
- 发布:执行
pnpm publish --access public --no-git-checks --provenance --tag <tag>(.github/workflows/npm-publish.yml),并通过NODE_AUTH_TOKEN注入NPM_TOKEN。
其中两个参数值得理解:
--no-git-checks:跳过 npm 对"工作区是否干净、当前分支是否有 tag"的默认检查,因为 CI 在 tag 推送后 checkout 的是 tag 指向的提交,本地 git 状态与 tag 不完全同步属正常现象。--provenance:开启 npm 供应链溯源签名,配合工作流顶部的permissions: id-token: write(.github/workflows/npm-publish.yml),发布产物会携带由 npm registry 生成的 provenance 证明,提升包的可信度。
实际操作步骤
- 更新版本号(可选):编辑 package.json 的
version字段。例如从2026.1.25改为2026.1.26。若本次发布涉及extensions/*插件版本对齐,可先执行pnpm plugins:sync,该脚本会把所有插件版本同步到根包版本并为缺失的插件 CHANGELOG 补条目(见 scripts/sync-plugin-versions.ts)。 - 提交更改:
git add package.json
git commit -m "chore: bump version to 2026.1.26"
git push
- 创建并推送 tag(版本号前加
v):
git tag v2026.1.26
git push origin v2026.1.26
- 等待自动发布:GitHub Actions 检测到
v2026.1.26后自动构建并发布。若 tag 带-beta/-alpha/-test后缀,则包会发布到对应预发布通道而非latest,方便先小范围验证。
查看发布状态
在仓库页面进入 Actions tab,找到 Publish to npm workflow(与 .github/workflows/npm-publish.yml 的 name: Publish to npm 对应),即可看到每次 tag 推送触发的运行记录。点击运行可查看每个 step 的实时日志;若发布失败,重点排查 Publish to npm step 的错误输出——常见的失败原因见下文"常见问题"。
验证发布:确认包真的可用
发布成功后,务必从"消费者"视角验证:
# 查看包信息(名称、版本、描述、bin 等)
npm view openclaw-cn
# 全局安装
npm install -g openclaw-cn
# 验证版本号
openclaw-cn --version
两点补充:
- 如果发布到了
beta/alpha通道,验证时需显式指定标签,例如npm install -g openclaw-cn@beta,否则默认拉取latest。 - 全局安装会触发包的
postinstall脚本(scripts/postinstall.js),它负责三件事:为dist/entry.js添加可执行权限、通过setup-git-hooks配置 git 钩子、检测是否同时装了上游openclaw包并给出中文警告(提示openclaw命令可能指向最后安装的版本,建议改用openclaw-cn命令)。安装日志中出现这些输出属于正常现象。
版本管理建议:从日期版本到语义化版本
原文档指出,项目当前使用日期版本(如 2026.1.25),但建议逐步向语义化版本(SemVer)演进:
- 主要版本(Major):破坏性更新,对应
2026.1.x → 2026.2.x这类跨代变化。 - 次要版本(Minor):新功能且向后兼容,例如
2026.1.25 → 2026.1.26。 - 补丁版本(Patch):Bug 修复,可考虑
2026.1.25.1这样的四级补丁号。
结合仓库现状有两个需要说明的细节:
- 版本号与 openclawVersion 分离:根包的 npm
version目前是0.2.0(见 package.json),而openclawVersion字段为2026.3.24(package.json)。后者用于与上游 OpenClaw 的日期版本对齐,是第三方插件做版本兼容性检查的依据——0.1.9中曾因插件要求主机版本>=2026.3.22而 npm 版本是0.x导致检查失败,最终通过新增该字段解决(见 CHANGELOG.md)。因此改版本号时,这两个字段可能都需要同步更新。 - tag 命名与 dist-tag 联动:自动发布工作流以 tag 字符串推断发布通道,若走
latest通道,tag 必须是纯粹的v<版本号>;若带-beta、-alpha、-test后缀则进入对应预发布通道。版本规划时应让 tag 命名与期望的 npm dist-tag 保持一致。
常见问题与排查
1. 发布失败:包名已存在
openclaw-cn 必须在你名下可用。若该名称已被其他账号占用,npm 会拒绝发布。此时需要更换包名并同步更新 package.json 的 name、bin 以及文档中的安装命令。
2. 权限错误
- 确认 GitHub Secrets 中的
NPM_TOKEN值正确且未被轮换。 - 确认该 token 归属的 npm 账号对该包拥有
publish权限(若包已被组织管理,还需是组织的 member 或 owner)。 - 若本地手动发布报权限错,先执行
npm whoami确认当前登录账号。
3. 构建失败
先在本地完整执行 pnpm build && pnpm ui:build。若 CI 失败而本地通过,优先检查是否因 --frozen-lockfile 导致依赖锁定不一致;此时应重新生成 pnpm-lock.yaml 后提交。另外构建依赖原生模块(如 sharp、node-pty、Baileys),.npmrc 中已通过 allow-build-scripts 显式放行其构建脚本,不要随意删除该配置。
4. 安装时 SSH 报错(Permission denied)
这是 @whiskeysockets/baileys 传递依赖 libsignal-node 从 GitHub 拉取原生模块时的常见问题,报错形如:
Permission denied (publickey)
fatal: Could not read from remote repository
仓库已做多层防护:.npmrc 设置 git-protocol=https 并调大 fetch-timeout/fetch-retry-*;postinstall 自动写入 git URL 重定向 https://github.com/.insteadOf ssh://git@github.com/;Dockerfile 在容器内做全局配置;另有 scripts/setup-npm-git-config.sh 可手动执行。完整机制见 docs/npm-ssh-config.md。若仍报错,可手动执行:
git config url."https://github.com/".insteadOf ssh://git@github.com/
git config url."https://".insteadOf git://
然后删除 node_modules 与 pnpm-lock.yaml 重装。
5. 如何撤销发布
npm 允许在发布后 72 小时内撤销:
npm unpublish openclaw-cn@2026.1.25
⚠️ 注意:撤销后的版本号不能再次使用。因此误发布时优先考虑"撤销后升新版本号再发",而不是试图复用旧号。若超过 72 小时,只能联系 npm 支持处理,或直接发布一个新的修正版本(Deprecate 也是一种轻量方案,可将旧版本标记为废弃而保留可安装性)。
发布检查清单
每次发布前逐项确认,缺一不可:
- [ ] 代码已测试通过(
pnpm test) - [ ] 本地 lint 通过(
pnpm lint) - [ ]
version已更新(含openclawVersion如需要) - [ ]
pnpm plugins:sync已同步插件版本(如需) - [ ] CHANGELOG.md 已更新
- [ ]
NPM_TOKEN已在 GitHub Secrets 中配置 - [ ] 本地
pnpm build && pnpm ui:build构建成功 - [ ]
pnpm release:check通过(npm pack 内容与插件版本体检) - [ ]
pnpm pack后本地全局安装验证可运行 - [ ] README 文档内容与当前版本一致
走完这条链路——本地预检、手动/自动发布、tag 驱动的 dist-tag 分流、发布后验证——即可稳定、可追溯地维护 openclaw-cn 的 npm 分发,为所有通过 npm install -g openclaw-cn 安装的用户持续交付新版本。