发布管理
添加于:v11.13.0
pnpm 可以自行对工作区进行版本管理与发布,无需单独的发布工具。该工作流分为两部分:
- As you work,
pnpm changerecords change intents: small markdown files in.changeset/saying which packages a change affects, how each should be bumped, and a summary that becomes the changelog entry. 这些会随变更一起提交。 - 在发布时,直接运行
pnpm version -r会消耗待处理的意图:它会提升整个工作区的版本、向依赖方传播、写入变更日志,并在一个纳入提交的账本中记录它消耗了哪些内容。
意图文件使用 changesets 格式,因此已有的 .changeset/ 目录仍可继续使用。如果你更愿意继续使用 Changesets CLI,请参见在 pnpm 中使用 Changesets。
记录一项变更#
pnpm change
它会提示你输入受影响的包、它们的提升类型以及摘要,然后写入类似 .changeset/calm-cats-resolve.md 的文件:
---
"@example/core": minor
---
Added a `--watch` flag to the build command.
要查看待处理的意图会产生什么结果:
pnpm change status
发布#
pnpm version -r
这会应用发布计划:被某个意图点名的每个包都会被提升,通过 workspace: 范围依赖它的每个包同样会被提升。先用 --dry-run 预览,再用 --filter 缩小范围。
Because a recursive run can bump many packages to different versions, no git commit or tag is created, because there is no single version to tag. 请自行提交结果,然后使用 pnpm publish -r 发布。
首次发布#
自 v11.16.0 起,包的首次发布会原样发布其清单中写明的版本,而不再在该版本基础上提升。 pnpm version -r 与 pnpm change status 会从注册源查询每次发布的当前版本;当该版本尚未发布时,包会以该版本首次登场,而其待处理的变更意图仅从下一次发布开始生效。因此,一个新添加、初始版本为 1100.0.0 且带有 minor 意图的包会发布为 1100.0.0,而不会直接跳到 1100.1.0。
Private packages ("private": true) are never published, so they skip this registry check: their pending change intents are always applied on top of the version in their manifest.
配置#
发布行为通过 pnpm-workspace.yaml 中的 versioning 键进行配置:
versioning:
fixed:
- ['@example/cli', '@example/napi']
ignore:
- '@example/internal'
maxBump: minor
lanes:
'@example/cli': alpha
changelog:
storage: repository
每个键都在版本管理设置中说明。
当两个工作区项目发布相同名称时,可以用带 ./ 前缀的工作区相对目录来引用某个项目,而不是用它的名称(例如 "./packages/cli")。这在意图文件中,以及 versioning.lanes、versioning.fixed 和 versioning.ignore 中都适用。
固定组#
Packages listed together in versioning.fixed always release at one shared version: the highest current version in the group, bumped by the largest bump any member needs. 固定组必须在通道之间一起迁移,并且必须完全位于某个 epic 之内或完全在其之外。
通道#
通道是一条并行的发布轨道。当某个包处于某条通道上时,它会从与发布主通道上所有内容稳定版本相同的运行中,发布 X.Y.Z-<lane>.N 形式的预发布版本。这使得重写或某一个主版本线可以在公开环境中逐步成熟,而工作区的其余部分继续发布。
pnpm lane alpha --filter @example/cli # 切换到 alpha 通道
pnpm lane main --filter @example/cli # 回归稳定通道
pnpm lane # 显示成员
关于预发布版本如何计算,请参见 pnpm lane。
剧集#
An epic ties a group of member packages to a lead package, constraining every member's major version to a band derived from the lead's major: while the lead is on major M, members live in M*100 to M*100+99.
versioning:
epics:
- lead: '@example/app'
packages:
- './packages/**'
- '!./packages/private-*'
With the lead on 11.x, members occupy majors 1100 to 1199. Members move independently inside the band: patch, minor, and even a major intent that stays in-band. 会让成员越过区间上限的提升会被拒绝,直至主导包推进自身主版本。当发布计划把主导包带到新的稳定主版本时,所有成员都会在同一计划中重新落到区间下限。
成员资格通过 pnpm 的包选择器匹配:名称通配符、带 ./ 前缀的目录通配符,以及带 ! 前缀的否定项。选择器按顺序求值,由最后一个匹配项决定,因此后续的包含项可以重新纳入先前被否定项排除的包。主导包永远不会成为自身区间的成员。
Checking committed versions#
pnpm change check validates the versions already committed in the workspace against the versioning.epics bands and the versioning.fixed groups, without reading any change intent. Run it in CI, next to the lint and test steps, so a version that drifted out of its band is caught on the pull request that introduced it rather than at release time.
变更日志#
默认情况下(versioning.changelog.storage: registry),不会提交 CHANGELOG.md。每次发布的章节会在发布时组装,并叠加在上一个已发布版本的变更日志之上打包进已发布的 tarball。已消耗的变更意图只有在注册源确认该版本已连同其章节发布之后,才会被后续的 pnpm version -r 回收。
改为设置 versioning.changelog.storage: repository,即可在每个包中保留已提交的 CHANGELOG.md 文件。
Private packages are never published, so no tarball could carry their changelog. Their releases always use repository storage, whatever is configured: the section is prepended to the package's committed CHANGELOG.md, and the release counts as consumed without a registry confirmation. An intent file that also names other projects is still deleted only once all of them have released.
账本#
pnpm version -r 会把每个已消耗的意图记录在 .changeset/ledger.yaml 中,这是一个纳入提交、仅追加的文件:
"@example/core@1.3.0":
dir: packages/core
intents:
- calm-cats-resolve
消耗情况按项目跟踪:只有当一个意图所涉及的所有项目都已发布后,该意图文件才会被删除。 This is what makes cherry-picks and merge-backs between release branches safe. A release branch that has already consumed an intent will not consume it again when the commit is merged forward, and a package on a lane can half-consume an intent whose prose still has a stable release to compose.