配置
pubm 有意保持 CLI-first,但真实项目很快就会超出只靠 flags 配置的范围。pubm.config.* 用来保存仓库级的发布目标、包布局、插件和与 changeset 相关的版本规则。
运行 pubm init 可以通过交互方式生成此配置文件。只有当你的选择与下方所示默认值不同时,向导才会创建配置文件。
支持的配置文件
Section titled “支持的配置文件”pubm 支持这些文件名:
pubm.config.tspubm.config.mtspubm.config.ctspubm.config.jspubm.config.mjspubm.config.cjs
TypeScript 配置文件可直接使用。loader 会在执行前先打包该文件,因此不需要单独的运行时转译步骤。
配置层解析出的默认值如下:
export default defineConfig({ versioning: "independent", branch: "main", changelog: true, changelogFormat: "default", commit: false, access: "public", fixed: [], linked: [], updateInternalDependencies: "patch", ignore: [], tag: "latest", contents: ".", saveToken: true, releaseDraft: true, releaseNotes: true, rollback: { strategy: "individual", dangerouslyAllowUnpublish: false, }, packages: [{ path: "." }], validate: { cleanInstall: true, entryPoints: true, extraneousFiles: true, }, snapshotTemplate: "{tag}-{timestamp}", locale: "en",});registry 是如何推断的
Section titled “registry 是如何推断的”pubm 会检查每个 package 目录中的 manifest 文件,并将它们映射到对应的 registry:
| Manifest | 推断出的 registry |
|---|---|
package.json | npm |
jsr.json | jsr |
deno.json / deno.jsonc | jsr |
Cargo.toml | crates |
npm 还适用两条额外规则:
package.json中的publishConfig.registry会把npm替换成自定义 URL- 当没有
publishConfig时,.npmrc中的 registry 会替换npm
versioning
Section titled “versioning”- 类型:
"independent" | "fixed" - 默认值:
"independent"
控制多包仓库中的版本分配方式。
branch
Section titled “branch”- 类型:
string - 默认值:
"main"
受保护的发布运行中,HEAD 必须匹配的分支。
packages
Section titled “packages”- 类型:
PackageConfig[] - 默认值:
[{ path: "." }]
显式声明可发布的包。除非在单个包上覆盖,否则 registry 会从 manifest 文件中推断。
plugins
Section titled “plugins”- 类型:
PubmPlugin[] - 默认值:
[]
注册插件,这些插件可以添加 hooks、commands、registries 或 ecosystems。
- 类型:
string[][] - 默认值:
[]
必须始终使用相同版本的包分组。
linked
Section titled “linked”- 类型:
string[][] - 默认值:
[]
应该共享最高 bump 类型的包分组。
ignore
Section titled “ignore”- 类型:
string[] - 默认值:
[]
从 workspace 发现中排除的包名或路径。
- 类型:
string - 默认值:
"latest"
发布运行使用的默认 dist-tag。
contents
Section titled “contents”- 类型:
string - 默认值:
"."
在运行发布流程之前切换到的目录。
saveToken
Section titled “saveToken”- 类型:
boolean - 默认值:
true
是否将受支持 registry 的 token 保存起来,供本地机器后续复用。
releaseDraft
Section titled “releaseDraft”- 类型:
boolean - 默认值:
true
发布流程是否应该创建 GitHub Release。禁用后会完全跳过 release 步骤。
excludeRelease
Section titled “excludeRelease”- 类型:
string[] - 默认值:
[]
用于指定包的 glob 模式,这些包会被版本化和发布,但会被排除在 git tag 创建和 GitHub Release 草稿之外。仅在 versioning 为 "independent" 时生效。
适用于内部构建产物,例如平台特定的二进制文件,它们需要发布到注册表,但不应以独立 release 的形式出现。
export default defineConfig({ versioning: "independent", excludeRelease: ["packages/cli/platforms/*"], packages: [ { path: "packages/core" }, { path: "packages/cli" }, { path: "packages/cli/platforms/*" }, ],});validate
Section titled “validate”- 类型:
ValidateConfig
这些字段属于公开 schema,但目前还不是所有 publish 路径上的活动开关。应把它们视为带类型的配置面,而不是保证在运行时生效的切换项。
snapshotTemplate
Section titled “snapshotTemplate”- 类型:
string - 默认值:
"{tag}-{timestamp}"
当 pubm --snapshot 生成临时版本字符串时使用的模板。
可用的模板变量:
{base}:来自 manifest 的当前包版本{tag}:snapshot tag,默认是snapshot{timestamp}:格式为YYYYMMDDTHHmmss的 UTC 时间戳{commit}:当前 git commit SHA
在使用 fixed 版本策略的 monorepo 项目中,模板以第一个包的版本作为 {base} 应用一次。使用 independent 版本策略时,每个包使用各自的 {base} 生成快照版本。
createPr
Section titled “createPr”- 类型:
boolean - 默认值:
false
为版本升级提交创建 pull request,而不是直接推送到基础分支。启用后,pubm 会创建 pubm/version-packages-* 分支并推送,然后开启一个 PR。PR 合并后,现有的发布工作流会正常触发。
当直接推送到受保护的分支失败时,pubm 会自动回退到 PR 模式。
locale
Section titled “locale”- 类型:
"en" | "ko" | "zh-cn" | "fr" | "de" | "es" - 默认值:
"en"
CLI 输出语言。也可通过 --locale flag 或 PUBM_LOCALE 环境变量设置。解析顺序:--locale flag → PUBM_LOCALE 环境变量 → config → 系统语言 → "en"。
rollback
Section titled “rollback”控制发布失败时的回滚行为。
| 键 | 类型 | 默认值 | 描述 |
|---|---|---|---|
strategy | "individual" | "all" | "individual" | 回滚粒度。取代已废弃的顶层字段 rollbackStrategy。 |
dangerouslyAllowUnpublish | boolean | false | 允许在非 TTY(CI)环境中的回滚期间对 registry 执行 unpublish/yank。即使 unpublish 后,npm 也会永久保留该版本号,无法被重用。 |
export default defineConfig({ rollback: { strategy: "individual", dangerouslyAllowUnpublish: true, // 在 CI 中启用 },});已废弃的顶层字段 rollbackStrategy 仍然有效,并映射到 rollback.strategy。如果同时设置了两者,rollback.strategy 优先生效。
配置和 CLI flags 如何交互
Section titled “配置和 CLI flags 如何交互”当前的运行时行为是:
- config 提供
packages和plugins的仓库默认值 - 与版本规划相关的 config,例如
versioning、fixed和linked,会被 changeset 流程使用 - CLI flags 仍然控制每次运行的发布行为
- registry 会从 manifest 推断;
packages[].registries可以覆盖该推断
如果要针对某个 registry 做一次性发布:
pubm --registry npm --tag beta对于 workspace 或混合语言仓库,请显式声明 package。registry 会从每个 package 的 manifest 文件中推断:
import { defineConfig } from "@pubm/core";
export default defineConfig({ versioning: "independent", packages: [ { path: "packages/core", }, { path: "packages/cli", registries: ["npm"], }, { path: "crates/pubm-rs", }, ],});在以下情况下建议使用显式 package 条目:
- 你只想让
pubm发布发现到的 workspace 包中的一部分 - JavaScript 和 Rust 包共存于同一个仓库
- 你需要覆盖推断出的 registry,或者添加私有 registry
PackageConfig
Section titled “PackageConfig”package 级条目长这样:
interface PackageConfig { path: string; registries?: Array<"npm" | "jsr" | "crates" | PrivateRegistryConfig>; ecosystem?: "js" | "rust"; buildCommand?: string; testCommand?: string;}
interface PrivateRegistryConfig { url: string; token: { envVar: string };}只有在推断不够用,或者你需要在内建 registry 之外再加私有 registry 时,才使用 registries:
packages: [ { path: "packages/a", registries: [ "npm", { url: "https://npm.internal.com", token: { envVar: "INTERNAL_NPM_TOKEN" } }, ], },];每个包都有自己的版本和 tag。
export default defineConfig({ versioning: "independent",});所有受影响的包共享一个版本。
export default defineConfig({ versioning: "fixed",});fixed 和 linked 分组
Section titled “fixed 和 linked 分组”你可以让大多数包保持独立,同时强制选定的包一起移动:
export default defineConfig({ versioning: "independent", fixed: [["@acme/core", "@acme/react"]], linked: [["@acme/cli", "@acme/config"]],});fixed:分组内所有包最终会使用完全相同的版本linked:最高的 bump 类型会在整个分组中传播
Snapshot 设置
Section titled “Snapshot 设置”Snapshot 适合预览发布和按分支验证。
export default defineConfig({ snapshotTemplate: "{tag}-{timestamp}",});示例输出:
0.4.1-snapshot-20260312T102233
通过 plugins 数组添加插件:
import { defineConfig } from "@pubm/core";import { externalVersionSync } from "@pubm/plugin-external-version-sync";
export default defineConfig({ plugins: [ externalVersionSync({ targets: [ { file: "README.md", pattern: /pubm@([\\w.-]+)/, }, ], }), ],});阅读 Plugins API Reference 了解 hooks 顺序、命令注册和自定义 registry 支持。
如果包里有 package.json 和 jsr.json(或 deno.json / deno.jsonc),registry 会自动推断。不需要配置文件,pubm.config.ts 是可选的。只有在你需要覆盖默认值时才创建它,例如自定义 branch、plugins、release assets 等。
App monorepo
Section titled “App monorepo”只有 package.json 的包会被解析为 npm。除非你想覆盖,否则不需要显式 registries。
import { defineConfig } from "@pubm/core";
export default defineConfig({ versioning: "fixed", packages: [ { path: "packages/web" }, { path: "packages/server" }, ],});混合 JS + Rust workspace
Section titled “混合 JS + Rust workspace”import { defineConfig } from "@pubm/core";
export default defineConfig({ versioning: "independent", packages: [ { path: "packages/sdk" }, { path: "crates/sdk-core" }, ],});Release 资产
Section titled “Release 资产”releaseAssets 用来声明每个 GitHub Release 要附带的二进制构件。大多数情况下,一个简单的 glob 字符串就足够了:
import { defineConfig } from "@pubm/core";
export default defineConfig({ releaseAssets: [ "platforms/*/bin/mytool", ],});compress
Section titled “compress”- 类型:
"tar.gz" | "zip" | "tar.xz" | "tar.zst" | false | Record<string, CompressFormat> - 默认值:按 OS 自动检测(windows →
zip,其他 →tar.gz)
全局默认压缩格式。可以在 releaseAssets 内的 group 或 file 级别覆盖。
export default defineConfig({ // Windows 使用 zip,其他平台使用 tar.gz compress: { windows: "zip" },
releaseAssets: [ "platforms/*/bin/mytool", ],});releaseAssets
Section titled “releaseAssets”- 类型:
(string | ReleaseAssetGroupConfig)[] - 默认值:
undefined(不附加任何资产)
每一项要么是 glob 字符串,要么是带显式控制的对象:
releaseAssets: [ // 字符串:glob,全自动 "platforms/*/bin/mytool",
// 对象:按 group 显式配置 { packagePath: "packages/cli", // monorepo:把资产关联到这个 package 的 Release files: [ "platforms/*/bin/mytool", { path: "dist/*.dmg", compress: false, name: "MyTool-{version}-{os}" }, ], compress: "tar.gz", // group 默认值 name: "{name}-{platform}", // group 名称模板 },]阅读 Release Assets 了解完整的 compress cascade 规则、name 模板变量和使用场景示例。
pubm changesets version 可以从两个来源解析版本 bump:.pubm/changesets/ 中的 changeset 文件和 conventional commit 消息。你可以控制哪些来源处于活跃状态,以及提交类型如何映射到 bump 级别。
versionSources
Section titled “versionSources”- 类型:
"all" | "changesets" | "commits" - 默认值:
"all"
控制 pubm changesets version 在计算版本 bump 时读取哪些来源。
| 值 | 行为 |
|---|---|
"all" | 对有 changeset 的包使用 changeset。对没有待处理 changeset 的包回退到 conventional commits。 |
"changesets" | 只读取 .pubm/changesets/ 文件。Conventional commits 被忽略。 |
"commits" | 只读取 conventional commit 消息。Changeset 文件被忽略。 |
conventionalCommits
Section titled “conventionalCommits”配置提交类型前缀如何映射到 semver bump 级别。仅在 versionSources 为 "all" 或 "commits" 时生效。
export default defineConfig({ versionSources: "all", conventionalCommits: { types: { // 添加默认被忽略的类型 refactor: "patch", docs: "patch", }, },});默认映射为:
| 提交类型 | Bump |
|---|---|
feat | minor |
fix | patch |
perf | patch |
footer 中包含 BREAKING CHANGE 或使用 ! 后缀(如 feat!:)的提交,无论类型映射如何,始终产生 major bump。
未在映射中列出的提交类型(如 chore、docs、test、ci、style、refactor)在 bump 计算中会被忽略。你可以在 types 对象中覆盖任何类型——例如,refactor: "patch" 会将 refactor 提交视为 patch bump。
- 如果你需要 package 分组或混合 registry,请阅读 Monorepo 指南。
- 如果配置中注册了自定义插件,请阅读 Plugins API Reference。
- 如果你想把二进制和 archive 附加到 GitHub Releases,请阅读 Release Assets 指南。
- 阅读 Changesets 指南了解更多关于 conventional commit 降级回退行为的内容。