故障排查
本指南聚焦于实践中最常见、最值得优先排查的失败模式:配置加载、版本管理、registry 认证、Git 状态和 CI 行为。
先从最安全的诊断命令开始
Section titled “先从最安全的诊断命令开始”在重试失败的发布之前,先运行这些命令:
pubm changesets status --verbosepubm changesets version --dry-runpubm --dry-runpubm --mode ci --phase prepare这些命令合起来可以回答:
pubm认为应该发布哪个版本- 哪些包会受到影响
- changelog 文本是否正常
- 凭据和 registry 检查是否已经就绪
发布被 Git 状态阻塞
Section titled “发布被 Git 状态阻塞”症状:
- release stops before publish
- errors mention a dirty working tree
- errors mention the wrong branch
需要检查:
- commit or stash local changes
- confirm you are on the expected branch
- 如果这是有意的例外,判断是否可以接受
--any-branch
除非你真的想降低发布安全性,否则不要把绕过类 flags 变成标准工作流的一部分。
version 命令提示找不到 changeset
Section titled “version 命令提示找不到 changeset”Symptoms:
pubm changesets versionprintsNo changesets found.
需要检查:
- confirm files exist in
.pubm/changesets/ - make sure you are in the repository root
- 如果你是从
.changeset/迁移过来,请运行pubm changesets migrate
bump 了错误的包
Section titled “bump 了错误的包”症状:
- packages you did not expect appear in
changesets status - fixed or linked packages move together unexpectedly
需要检查:
- run
pubm changesets status --verbose - inspect
fixedandlinkedgroups inpubm.config.* - verify whether the repository is using
independentorfixedversioning
如果 workspace 结构很复杂,建议改用显式的 packages 配置,而不要只依赖自动发现。
配置文件加载失败
Section titled “配置文件加载失败”症状:
- startup fails before the release pipeline begins
- errors mention config imports or bundling
需要检查:
- ensure the config file is one of the supported names
- import
defineConfigfrom@pubm/core - remove heavy runtime work from the top level of the config module
- verify optional dependencies are installed where needed
好的配置文件应该主要是声明式的。如果它开始像应用代码,把辅助逻辑拆到更小的模块里,并保持求值过程可预测。
npm publish 因认证或权限错误失败
Section titled “npm publish 因认证或权限错误失败”症状:
- 401 or 403 responses
- messages about OTP, 2FA, or publish permission
需要检查:
- verify
NODE_AUTH_TOKEN - confirm the token has publish access to the package
- prefer automation-compatible tokens in CI
- confirm the package access level matches registry expectations
如果仓库发布的是带 scope 的公开包,也要确认它在 npm 上确实应该是 public。
jsr publish 失败
Section titled “jsr publish 失败”症状:
- jsr target fails while npm succeeds
需要检查:
- verify
JSR_TOKEN - run
pubm --mode ci --phase prepare - confirm the package metadata is valid for jsr
由于 pubm 会发布到多个 target,应先修复失败的 registry,而不是盲目重试,以免造成部分发布的混乱。
crates.io publish 失败
Section titled “crates.io publish 失败”症状:
- Rust package publish fails
- one crate succeeds but another blocks later in the sequence
需要检查:
- verify
CARGO_REGISTRY_TOKEN - confirm crate dependency ordering and versions are valid
- inspect package-specific
registriesoverride inpubm.config.*(or check manifest files if using inference)
在需要考虑顺序时,Rust 发布会按顺序执行。这是正常现象,通常也说明 pubm 正在保护依赖正确性。
pubm 内部的 build 或 test 步骤失败
Section titled “pubm 内部的 build 或 test 步骤失败”症状:
- release stops during test or build
- error message suggests rerunning the underlying script
应该怎么做:
- rerun the script directly
- fix the underlying build or test failure
- retry
pubm
Examples:
pnpm run testpnpm run build如果你的脚本名称不同,请让它们与配置或 CLI flags 对齐:
pubm --test-script test:ci --build-script build:releasecontents 发布不工作
Section titled “contents 发布不工作”症状:
- publish command cannot find expected files
- release works from root but fails from
dist/
需要检查:
- confirm
contentspoints to the final publish directory - ensure the build step creates that directory before publish starts
- verify the target directory contains the manifest files expected by the selected registry (
package.jsonfor npm,jsr.jsonordeno.json/deno.jsoncfor jsr,Cargo.tomlfor crates)
contents 会改变运行时流程的工作目录。应把它视为发布根目录,而不只是输出目录。
CI 与本地运行行为不同
Section titled “CI 与本地运行行为不同”症状:
- local publish succeeds
- CI publish fails or hangs
原因:
- CI disables prompts
- tokens must come from environment variables or prior secret sync
- shallow checkouts often break tag-aware flows
需要检查:
- run
pubm --mode ci --phase preparelocally - use full Git history in CI
- confirm every required token is present in the job environment
GitHub Release 问题
Section titled “GitHub Release 问题”症状:
- release creation fails
- release metadata looks incomplete
需要检查:
- confirm repository remote metadata is valid
- ensure Git tags exist and are pushed
- distinguish between normal publish flow and
--mode ci --phase publish
pubm 会通过 API 创建 GitHub Release。在本地模式下如果没有 GITHUB_TOKEN,你可以输入 token、在浏览器中打开草稿,或者跳过。--mode ci --phase publish 会作为流程的一部分通过 API 创建 GitHub Release。
已发生 rollback,仓库状态看起来很混乱
Section titled “已发生 rollback,仓库状态看起来很混乱”症状:
- publish failed mid-run
- tags or commits were created and then removed
应该怎么做:
- inspect current tags with
git tag - inspect working tree status with
git status - rerun only after you understand which step failed first
关键是诊断最初原因,而不是只看随后出现的 rollback 消息。
回滚 unpublish 后版本号被永久占用
Section titled “回滚 unpublish 后版本号被永久占用”症状:
- publish 失败,rollback 运行,并从 npm unpublish 了某个包,或从 crates.io yank 了某个版本
- 用相同版本重新 publish 时失败,提示版本号已被占用
发生了什么:
npm unpublish 会删除包的 tarball,但版本号会被永久保留,无法被重用。crates.io 的 cargo yank 同样会将该版本标记为不可用。
应该怎么做:
- 升级到新版本(例如用
1.2.4代替1.2.3)并重新发布 - 在 CI 中,默认会跳过 unpublish 以避免消耗版本号。使用
--dangerously-allow-unpublish或在 config 中设置rollback.dangerouslyAllowUnpublish: true来启用它
何时提交 issue
Section titled “何时提交 issue”当你能用以下内容复现问题时,再提交 issue:
- the exact command
- relevant config
- target registries
- expected behavior
- actual behavior and error output
高质量 bug 报告对以下情况尤其有价值:
- 混合 JS 和 Rust 的仓库
- 由 plugin 提供的 registries
- config loader 的边缘情况
- 部分失败后的 rollback 行为
有用的恢复流程
Section titled “有用的恢复流程”如果发布失败,而你希望保守地恢复:
git statusgit tag --sort=-creatordate | headpubm changesets status --verbosepubm changesets version --dry-runpubm --dry-runpubm --mode ci --phase prepare只有在 dry-run 和 CI preparation 的输出重新变得合理之后,才重跑真正的发布。