- 系统会多次要求您输入一次性密码（OTP），即您使用的双因素认证应用生成的验证码。根据待发布软件包的数量，您可能需要输入多个OTTP，因为这些代码往往在所有软件包发布前就会失效。
- 若发布流程意外中断（可能因超时或输错OTP导致），可通过执行 [`npx lerna publish from-package`](https://lerna.js.org/docs/features/version-and-publish#from-package) 命令恢复操作。

6. 最后，当 npm 软件包发布完成后，请将 Lerna 生成的提交记录（"发布"和更新日志更新）遴选合并到 Gutenberg 的 `trunk` 分支。

## 开发版发布

如[同步 Gutenberg 插件](#synchronizing-the-gutenberg-plugin)章节所述，软件包每两周会从 `wp/latest` 分支发布一次。此外，开发者可随时通过开发版来测试 `trunk` 分支即将推出的变更。我们利用[软件包分发标签](https://docs.npmjs.com/cli/v7/commands/npm-dist-tag)功能，使得根据 npm 指南使用未来版本代码成为可能：

> 默认情况下，npm 使用 `latest` 标签标识软件包当前版本，执行 `npm install <pkg>`（不附带任何 `@<version>` 或 `@<tag>` 限定符）时会安装 `latest` 标签对应的版本。通常项目仅将 `latest` 标签用于稳定版本，其他标签则用于预发布版等不稳定版本。

在本项目中，我们使用 `next` 分发标签标识开发版代码。开发者如需安装该版本的软件包，需输入：

```bash
npm install @wordpress/components@next
```

若要启动 npm 软件包开发版的发布流程，请前往 Gutenberg 的 GitHub 仓库的 Actions 标签页，找到["发布 npm 软件包"操作](https://github.com/WordPress/gutenberg/actions/workflows/publish-npm-packages.yml)。注意标有“此工作流由 `workflow_dispatch` 事件触发”的蓝色横幅，展开其右侧的“运行工作流”下拉菜单。

![npm 发布工作流运行下拉菜单](https://developer.wordpress.org/files/2023/07/image-4.png)

如需将开发版软件包发布至 npm，请从“发布类型”下拉菜单选择 `development`，并保持“WordPress 主版本号”输入框为空。最后点击绿色“运行工作流”按钮。这将触发 npm 发布任务，该任务需要经过 Gutenberg 核心团队成员的批准。请找到当前发布任务对应的["发布 npm 软件包"操作](https://github.com/WordPress/gutenberg/actions/workflows/publish-npm-packages.yml)，并完成[审批流程](https://docs.github.com/en/actions/how-tos/managing-workflow-runs-and-deployments/managing-deployments/reviewing-deployments#approving-or-rejecting-a-job)。

幕后流程中，发布操作完全通过 `./bin/plugin/cli.js npm-next` 命令实现自动化。该命令会确保 `wp/next` 分支与为 Gutenberg 插件创建的最新发布分支（`release/X.Y`）保持同步。为避免软件包版本冲突，我们始终会加入最新提交的 SHA 值，例如：`@wordpress/block-editor@5.2.10-next.645224df70.0`。

[插件代码库]: https://plugins.trac.wordpress.org/browser/gutenberg/
[软件包发布流程]: https://github.com/WordPress/gutenberg/blob/HEAD/packages/README.md#releasing-packages

# 发布到 NPM 的软件包与 WordPress 核心更新

Gutenberg 代码库遵循 [WordPress SVN 代码库](https://make.wordpress.org/core/handbook/about/release-cycle/)的分支策略，适用于每个主要的 WordPress 版本发布。除此之外，它还包含另外两个特殊的控制 npm 发布流程的分支：

-   `wp/latest` 分支包含与通过 `latest` 分发标签发布到 npm 的相同版本的软件包。此分支的目标是与最新的 Gutenberg 插件版本保持同步，唯一的例外是计划外的 [Bugfix 发布](#独立错误修复软件包发布)。
-   `wp/next` 分支包含与通过 `next` 分发标签发布到 npm 的相同版本的软件包。它始终与 `trunk` 分支保持同步。项目应仅将这些软件包用于开发或测试目的。
-   针对特定 WordPress 主要版本（包括其后续的次要版本更新）的 Gutenberg 分支 `wp/X.Y`（例如 `wp/6.2`）会在计划包含在下一个主要 WordPress 版本中的最后一次发布后不久，基于当前的 Gutenberg 插件发布分支 `release/X.Y`（例如 `release/15.1`）创建。

发布类型及其时间表：

-   [同步 Gutenberg 插件](#同步-gutenberg-插件)（`latest` 分发标签）—— 基于新创建的 `release/X.Y`（例如 `release/12.8`）分支，每两周自动发布一次，该分支包含 Gutenberg 插件的 RC1 版本。
-   [WordPress 发布](#wordpress-发布)（`wp-X.Y` 分发标签，例如 `wp-6.2`）—— 根据需求从 `wp/X.Y`（例如 `wp/6.2`）分支触发发布。一旦达到 WordPress 主要发布周期中的某个时间点（在 Beta 1 之前不久），我们仅从 Gutenberg 代码库中挑选提交到 WordPress 核心，此时我们使用 `wp/X.Y` 分支（从 `release/X.Y` 分支创建，例如 `release/15.1`）通过 `wp-X.Y` 分发标签进行 npm 发布。也可以使用旧分支将错误或安全修复反向移植到相应旧版本的 WordPress 核心。
-   [开发版本发布](#开发版本发布)（`next` 分发标签）—— 也可以在需要测试即将到来的更改时随时执行开发版本发布。

还可以选择随时执行[独立错误修复软件包发布](#独立错误修复软件包发布)。这应仅用于在常规周期之外必须发布到 _npm_ 的关键错误修复或安全发布。

## 同步 Gutenberg 插件

对于每个 Gutenberg 插件发布，我们还会将更新后的 WordPress 软件包版本发布到 npm。这是通过处理 Gutenberg 插件发布的[发布工具](https://github.com/WordPress/gutenberg/blob/trunk/.github/workflows/build-plugin-zip.yml)自动完成的。成功的 RC1 发布会触发 npm 发布任务，这需要由 Gutenberg 核心团队成员批准。找到新版本的 ["构建 Gutenberg 插件 Zip" 工作流](https://github.com/WordPress/gutenberg/actions/workflows/build-plugin-zip.yml)，并[批准](https://docs.github.com/en/actions/how-tos/managing-workflow-runs-and-deployments/managing-deployments/reviewing-deployments#approving-or-rejecting-a-job)它。

我们特意在 Gutenberg RC1 发布时，使用 Gutenberg 发布分支 `release/X.Y`（例如 `release/12.7`）的内容更新 Gutenberg 代码库中的 `wp/latest` 分支。这样做是为了确保 `wp/latest` 分支尽可能接近最新版本的 Gutenberg 插件。同时，这实际上也消除了在将提交反向移植到 `trunk` 时，因发布过程中应用到 `package.json` 和 `CHANGELOG.md` 文件的更新而产生冲突的可能性。过去，当我们在常规 Gutenberg 发布一周后进行 npm 发布时，在这方面遇到了许多问题。在将新的软件包版本发布到 npm 时，我们至少选择 `minor` 版本升级，以便为未来的错误修复或安全发布留出空间。

在幕后，所有步骤都通过 `./bin/plugin/cli.js npm-latest` 命令自动完成。作为记录，手动过程将非常接近以下步骤：

1.  确保 WordPress `trunk` 分支对增强功能开放。
2.  使用 `git fetch` 获取最后发布的 Gutenberg 发布分支。
3.  检出 `wp/latest` 分支。
4.  从当前分支中删除所有文件：`git rm -r .`。
5.  从发布分支检出所有文件：`git checkout release/x.x -- .`。
6.  使用 `git commit -m "Merge changes published in the Gutenberg plugin vX.X release"` 将所有更改提交到 `wp/latest` 分支，并推送到代码库。
7.  使用计算出的新发布版本更新软件包的 `CHANGELOG.md` 文件，并提交到 `wp/latest` 分支。假设软件包版本使用 `major.minor.patch` 格式编写，请确保至少应用 `minor` 版本升级。例如，如果要发布的软件包的 CHANGELOG 指示下一个未发布版本是 `5.6.1`，则在 `minor` 版本的情况下选择 `5.7.0` 作为版本。这一点很重要，因为如果需要为次要的 WordPress 发布进行错误修复，应保留补丁版本号（见下文）。
8.  通过控制台登录 npm：`npm login`。请注意，您应启用双因素认证（2FA）。
9.  从 `wp/latest` 分支，使用 `npm ci` 安装 npm 依赖项。
10. 运行脚本 `npx lerna publish --no-private`。
    -   当被要求选择每个软件包的版本号时，请选择更新的 CHANGELOG 文件中的值。
    -   您将被多次要求输入一次性密码（OTP）。这是您使用的 2FA 验证器应用程序中的代码。根据要发布的软件包数量，您可能需要输入多次 OTP，因为它们往往在所有软件包发布之前就过期了。
    -   如果发布过程未完成（可能是因为超时或输入了错误的 OTP），您可以通过 [`npx lerna publish from-package`](https://lerna.js.org/docs/features/version-and-publish#from-package) 恢复它。
11. 最后，既然 npm 软件包已发布，将 lerna 创建的提交（"Publish" 和 CHANGELOG 更新）挑选到 Gutenberg 的 `trunk` 分支中。

## WordPress 版本发布

当需要将错误修复或安全补丁移植到 WordPress 核心时，需遵循以下工作流程。适用场景包括：

-   在 WordPress 发布周期的 `beta` 和 `RC` 阶段，当发布分支 `wp/X.Y`（例如 `wp/5.7`）已存在时。
-   针对 WordPress 小版本和安全版本发布（例如 `5.1.1`）。

1.  检出对应的 WordPress 主版本分支（若小版本为 `5.2.1`，则检出 `wp/5.2`）。
2.  基于该分支创建功能分支，并将所需错误修复的合并提交拣选到该分支。可使用 [`npm run other:cherry-pick`](/docs/contributors/code/auto-cherry-picking.md) 脚本自动完成拣选操作。
3.  基于此分支创建拉取请求，目标分支选择前述 WordPress 主版本分支。
4.  点击 "Rebase and Merge" 按钮合并拉取请求以保留提交历史。

此时 `wp/X.Y` 分支已准备就绪可发布 npm 软件包。请前往 Gutenberg 的 GitHub 仓库 Actions 标签页，找到 ["发布 npm 软件包" 操作](https://github.com/WordPress/gutenberg/actions/workflows/publish-npm-packages.yml)。注意蓝色横幅提示 "此工作流程具有 `workflow_dispatch` 事件触发器"，展开右侧的 "Run workflow" 下拉菜单。

![npm 发布工作流运行下拉菜单](https://developer.wordpress.org/files/2023/07/image-2.png)

要为 WordPress 主版本发布 npm 软件包，请选择 `trunk` 作为运行工作流的分支（这意味着运行工作流所用的脚本来自 trunk 分支，但软件包本身将通过下文选择正确的"发布类型"后从发布分支发布），然后在"发布类型"下拉菜单中选择 `wp`，并在"WordPress 主版本"输入框中填入 `X.Y`（例如 `5.2`）。最后点击绿色 "Run workflow" 按钮。这将触发 npm 发布任务，需经 Gutenberg 核心团队成员批准。请找到本次发布的 ["发布 npm 软件包" 操作](https://github.com/WordPress/gutenberg/actions/workflows/publish-npm-packages.yml)，并完成[审批流程](https://docs.github.com/en/actions/how-tos/managing-workflow-runs-and-deployments/managing-deployments/reviewing-deployments#approving-or-rejecting-a-job)。

备案记录：手动操作流程如下：

1.  检出之前使用的 WordPress 分支（例如 `wp/5.2`）。
2.  执行 `git pull`。
3.  运行 `npx lerna publish patch --no-private --dist-tag wp-5.2` 命令（详见[软件包发布流程]），但在选择各软件包版本号时（假设版本号格式为 `主版本.次版本.修订号`），请确保仅提升 `修订号`。例如，若该 WordPress 分支最后发布的软件包版本为 `5.6.0`，则选择 `5.6.1` 作为新版本。

**注意：** 对于 WordPress `5.0` 和 `5.1` 版本，曾采用不同的发布流程。这意味着针对这两个版本选择 npm 软件包版本时，可能无法使用下一个 `修订号` 版本（因其可能已被占用）。此时应使用"元数据"修饰符。例如，若该 WordPress 分支最后发布的软件包版本为 `5.6.1`，则选择 `5.6.1+patch.1` 作为版本号。

3.  （可选）更新已发布软件包的 `CHANGELOG.md` 文件，添加新发布版本信息，并提交至对应分支（例如 `wp/5.2`）。
4.  将 CHANGELOG 更新提交（如有）拣选至 Gutenberg 的 `trunk` 分支。

至此 npm 软件包应已准备就绪，可以创建补丁并提交至对应的 WordPress SVN 分支。

## 独立错误修复包发布

当软件包需要在常规发布周期外向 _npm_ 发布错误修复或安全更新时，需遵循以下工作流程。

注意：`trunk` 和 `wp/latest` 分支均为受限分支，仅 Gutenberg 核心团队具有 _推送_ 权限。

识别需要从代码库 `trunk` 分支移植到 `wp/latest` 分支的拉取请求对应的提交哈希值。

接下来需要准备 `wp/latest` 分支以发布软件包至 _npm_。

打开终端并执行以下步骤：

1.  `git checkout trunk`
2.  `git pull`
3.  `git checkout wp/latest`
4.  `git pull`

在移植提交前，请检查 `wp/latest` 分支是否存在待发布的软件包：

1.  `git checkout wp/latest`
2.  `npx lerna updated`

现在将提交从 `trunk` 分支 _拣选_ 到 `wp/latest` 分支，若提交为拉取请求的合并提交，请使用 `-m 1 commithash`：

1.  `git cherry-pick -m 1 cb150a2`
2.  `git push`

在等待 GitHub Actions 构建 [通过 `wp/latest` 分支检查](https://github.com/WordPress/gutenberg/actions?query=branch%3Awp%2Ftrunk) 期间，识别并开始更新 `CHANGELOG.md` 文件：

1.  `git checkout wp/latest`
2.  `npx lerna updated`
    示例：
    ```shell
    npx lerna updated
    @wordpress/e2e-tests
    @wordpress/jest-preset-default
    @wordpress/scripts
    lerna success found 3 packages ready to publish
    ```

检查当前 `CHANGELOG.md` 文件中列出的版本，浏览软件包提交历史（例如 [@wordpress/scripts](https://github.com/WordPress/gutenberg/commits/HEAD/packages/scripts)），注意查找 _"chore(release): publish"_ 和 _"Update changelogs"_ 提交以确定最近的版本更新，然后查看自最近发布以来的提交记录，有助于了解自上次发布以来的变更内容。

注意：您可能会发现某些软件包的当前版本不是最新的，如遇此情况，建议更新先前发布的版本。

此时 `wp/latest` 分支已准备就绪可发布 npm 软件包。请前往 Gutenberg 的 GitHub 仓库 Actions 标签页，找到 ["发布 npm 软件包" 操作](https://github.com/WordPress/gutenberg/actions/workflows/publish-npm-packages.yml)。注意蓝色横幅提示 "此工作流程具有 `workflow_dispatch` 事件触发器"，展开右侧的 "Run workflow" 下拉菜单。

![npm 发布工作流运行下拉菜单](https://developer.wordpress.org/files/2023/07/image-6.png)

要发布包含错误修复的 npm 软件包，请在"发布类型"下拉菜单中选择 `bugfix`，并保持"WordPress 主版本"输入框为空。最后点击绿色 "Run workflow" 按钮。这将触发 npm 发布任务，需经 Gutenberg 核心团队成员批准。请找到本次发布的 ["发布 npm 软件包" 操作](https://github.com/WordPress/gutenberg/actions/workflows/publish-npm-packages.yml)，并完成[审批流程](https://docs.github.com/en/actions/how-tos/managing-workflow-runs-and-deployments/managing-deployments/reviewing-deployments#approving-or-rejecting-a-job)。

在后台，后续流程由 `./bin/plugin/cli.js npm-bugfix` 命令自动完成。备案记录：手动操作流程与以下步骤高度相似：

1.  检出 `wp/latest` 分支。
2.  使用计算得出的新发布版本更新各软件包的 `CHANGELOG.md` 文件，并提交至 `wp/latest` 分支。
3.  通过控制台登录 npm：`npm login`。注意应启用双因素认证。
4.  在 `wp/latest` 分支上，运行 `npm ci` 安装 npm 依赖项。
5.  运行脚本 `npx lerna publish --no-private`。
    -   当提示选择各软件包版本号时，请选择已更新的 CHANGELOG 文件中的对应值。