跳转至主要内容
版本: 5.0

发布手册

1. 引言

1.1 Apache 发布文档

参考以下链接以了解 ASF 发布流程:

1.2 PGP 签名

遵循 Apache 发布指南对发布版本进行签名,用户也可以通过此来确定下载的版本是否被篡改。

为版本签名创建一个 pgp 密钥,使用 \<your Apache ID>@apache.org 作为密钥的 USER-ID

更多详情,请参考 Apache 发布签名文档使用 OpenPGP 进行加密

生成密钥的简要流程:

  • 使用 gpg --gen-key 生成一个新的 gpg 密钥,将密钥长度设置为 4096 并设置为永不过期
  • 使用 gpg --keyserver keys.openpgp.org --send-key <your key id> 将密钥上传到公钥服务器
  • 使用 gpg --armor --export <your key id> >> gpgapachekey.txt 将公钥导出为文本文件
  • 获取其他贡献者的密钥以进行签名(可选)
  • 将生成的密钥添加到 KEYS 文件(由发布经理上传到 svn 仓库)
提示

设置默认公钥。如果您有多个公钥,请修改 ~/.gnupg/gpg.conf

参考示例:

[root@localhost ~]# gpg --gen-key
gpg (GnuPG) 2.0.22; Copyright (C) 2013 Free Software Foundation, Inc.
...
# secret key generation directory
gpg: directory `/root/.gnupg' created
gpg: new configuration file `/root/.gnupg/gpg.conf' created
gpg: WARNING: options in `/root/.gnupg/gpg.conf' are not yet active during this run
gpg: keyring `/root/.gnupg/secring.gpg' created
gpg: keyring `/root/.gnupg/pubring.gpg' created
Please select what kind of key you want:
(1) RSA and RSA (default)
(2) DSA and Elgamal
(3) DSA (sign only)
(4) RSA (sign only)
Your selection?
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 4096
Requested keysize is 4096 bits
Please specify how long the key should be valid.
0 = key does not expire
<n> = key expires in n days
<n>w = key expires in n weeks
<n>m = key expires in n months
<n>y = key expires in n years
Key is valid for? (0)
Key does not expire at all
Is this correct? (y/N) y

GnuPG needs to construct a user ID to identify your key.
# set USER-ID
Real name: rocketmq
Email address: rocketmq@apache.org
Comment: rocketmq
You selected this USER-ID:
"rocketmq (rocketmq) <rocketmq@apache.org>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
You need a Passphrase to protect your secret key.

...
gpg: /root/.gnupg/trustdb.gpg: trustdb created
gpg: key 7DE280AF marked as ultimately trusted
public and secret key created and signed.

gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u
pub 4096R/7DE280AF 2022-07-05
Key fingerprint = 421D C10E 9CC3 D261 9F89 C777 86BB 17AA 7DE2 80AF
uid rocketmq (rocketmq) <rocketmq@apache.org>
sub 4096R/65B9828A 2022-07-05

生成的公钥和私钥地址:

gpg: keyring `/root/.gnupg/secring.gpg' created
gpg: keyring `/root/.gnupg/pubring.gpg' created

将生成的公钥和私钥转换为 ASCII 格式:

gpg --armor --output /root/gpgtest/public-key.txt --export 7DE280AF
gpg --armor --output /root/gpgtest/private-key.txt --export-secret-keys 7DE280AF

查看密钥列表:

[root@localhost ~]# gpg --list-keys
/root/.gnupg/pubring.gpg
------------------------
pub 4096R/7DE280AF 2022-07-05
uid rocketmq (rocketmq) <rocketmq@apache.org>
sub 4096R/65B9828A 2022-07-05

将公钥上传到公钥服务器

[root@localhost gpgtest]# gpg --keyserver keys.openpgp.org --send-key 7DE280AF
gpg: sending key 7DE280AF to hkp server keys.openpgp.org

1.3 POM 设置

配置 POM 文件以将版本部署到 ASF Nexus 仓库。

① 添加 Apache POM 继承默认设置

<parent>
<groupId>org.apache</groupId>
<artifactId>apache</artifactId>
<version>XX</version>
</parent>

② 在 Maven 配置文件 settings.xml 中添加密钥信息。

<settings>
<profiles>
<profile>
<id>signed_release</id>
<properties>
<mavenExecutorId>forked-path</mavenExecutorId>
<gpg.keyname>yourKeyName</gpg.keyname>
<deploy.url>https://dist.apache.org/repos/dist/dev/rocketmq/</deploy.url>
</properties>
</profile>
</profiles>
<servers>
<!-- To publish a snapshot of some part of Maven -->
<server>
<id>apache.snapshots.https</id>
<username>yourApacheID</username>
<!-- Use the password encryption by maven -->
<password>yourApachePassword</password>
</server>
<!-- To stage a release of some part of Maven -->
<server>
<id>apache.releases.https</id>
<username>yourApacheID</username>
<password>yourApachePassword</password>
</server>
<server>
<id>gpg.passphrase</id>
<passphrase>yourKeyPassword</passphrase>
</server>
</servers>
</settings>
提示

建议使用 Maven 的密码加密功能 来加密 gpg.passphrase

③ 构建制品并签名

mvn clean install -Papache-release

1.4 处理问题

解决与此发布版本相关的 JIRA 问题和 GitHub Issue。

检查 MQVersion 是否与发布版本一致。

1.5 发布说明

通过 RocketMQ JIRA 生成发布说明,并推送到 rocketmq-site,在版本投票邮件中添加链接。

2. 构建源码发布版本

使用 Maven Release 插件 将制品发布到 ASF Nexus 暂存仓库,在版本验证和版本投票后,将其复制到 Apache SVN 版本仓库。

2.1 检查 RocketMQ 版本

确认 MQVersion 版本,如果格式不匹配 release-4.5.0 或不一致,请将其修改为正确格式,并推送到 develop 分支。

public static final int CURRENT_VERSION = Version.V4_5_0.ordinal();

2.2 在 ASF Nexus 仓库中进行暂存

  1. 切换到 develop 分支,确认与此版本相关的所有 GitHub PR 已合并。

① 配置 pom.xml 文件

<scm>
<url>git@github.com:apache/rocketmq.git</url>
<connection>scm:git:git@github.com:apache/rocketmq.git</connection>
<developerConnection>scm:git:git@github.com:apache/rocketmq.git</developerConnection>
<tag>rocketmq-all-x.x.x</tag>
</scm>

② Maven Release 插件

mvn release:clean
mvn release:prepare
mvn release:perform

遵循此流程将生成的制品放入暂存仓库:

  1. mvn clean release:clean:清除失败的构建和丢弃的版本。
  2. mvn release:prepare -Psigned_release -Darguments="-DskipTests":根据 SCM 属性更新 tag。
  3. mvn -Psigned_release release:perform -Darguments="-DskipTests":将生成的制品暂存到 Nexus 仓库。可以添加 -DdryRun=true 参数进行试运行。

完成上述流程后,可以在本地分支的 target 目录或 Nexus 暂存仓库 中找到预发布版本的制品。

提示

如果仅发布源码版本,请保留源码和相关 jar 文件,并使用 Nexus GUI 中的 delete 选项删除其他制品。

2.3 RC 版本文件

  • 在预发布版本投票通过之前,它将暂存在 /dev/rocketmq 并存储在 x.x.x-rcx/ 目录中。需要以下文件:

    rocketmq-all-x1.x2.x3-bin-release.zip

    rocketmq-all-x1.x2.x3-bin-release.zip.asc

    rocketmq-all-x1.x2.x3-bin-release.zip.sha512

    rocketmq-all-x1.x2.x3-source-release.zip

    rocketmq-all-x1.x2.x3-source-release.zip.asc

    rocketmq-all-x1.x2.x3-source-release.zip.sha512

使用 gpg 命令生成签名和验证文件:

  • 生成 asc 文件

    gpg --clearsign rocketmq-all-x1.x2.x3-bin-release.zip
    gpg --clearsign rocketmq-all-x1.x2.x3-source-release.zip
  • 生成 sha512 文件

    gpg --print-md SHA512 rocketmq-all-x1.x2.x3-bin-release.zip > rocketmq-all-x1.x2.x3-bin-release.zip.sha512
    gpg --print-md SHA512 rocketmq-all-x1.x2.x3-source-release.zip > rocketmq-all-x1.x2.x3-source-release.zip.sha512
提示

源码和二进制版本应以 rocketmq-all 开头,以便于 RocketMQ Docker 构建

2.4 回滚和重试

如果暂存过程中出现问题,请按照以下流程回滚:

  • 删除在 2.2 步骤中创建的 tag

    • 列出所有 tag 并找到最近创建的一个

      git tag -ln
    • 从本地仓库删除 tag

      git tag -d rocketmq-all-x1.x2.x3
    • 将更新推送到 GitHub

      git push origin :refs/tags/rocketmq-all-x1.x2.x3
  • 删除 2.2 步骤中开发分支的提交记录

    • 列出 git 日志

      git log
    • 找到最近的提交记录并按如下方式标记:

      des1[maven-release-plugin]prepare release rocketmq-all-4.9.2]

      des2[maven-release-plugin]prepare for next development iteration]

    • 删除提交

      git reset --hard commit-id
      git push origin HEAD --force
  • 删除 Nexus 中要回滚的版本

  • 回滚到 2.1 步骤并重做

3. 构建二进制发布版本

二进制和源码版本都是从同一个代码分支构建的,但您应该注意操作系统版本。

一些依赖项,如 netty tc-native,对操作系统敏感。

  • 确保签出了预发布版本分支
  • 确保所有单元测试通过 mvn clean install
  • 确保所有集成测试通过 mvn clean install -Pit-test

构建成功后,还需要生成 .asc 和 .sha512 文件,并在验证和投票后,最终将其复制到 svn 仓库。

4. 版本验证

4.1 二进制发布版本验证清单

  • 检查构建依赖项的操作系统,netty-tcnative 对操作系统敏感
  • 确保许可证是 Apache V2
  • 如果引入了第三方依赖项,请更新 NOTICE 文件
  • 解压压缩文件以检查版本是否正确
  • 验证 ASC 签名、SHA512 摘要
  • 运行 Quick-Start 以启动 nameserver 和 broker
  • 运行 clusterList 命令以检查版本是否正确
  • 确保没有 nohup.out 文件

4.2 源码发布版本验证清单

  • 确保许可证是 Apache V2
  • 如果引入了第三方依赖项,请更新 NOTICE 文件
  • 解压压缩文件以检查版本是否正确
  • 验证 ASC 签名、SHA512 摘要
  • 编译源码并运行 Quick-Start 以启动 nameserver 和 broker
  • 运行 clusterList 命令以检查版本是否正确

4.3 验证工具

按照以下步骤验证 GPG 签名和 SHA512 摘要。

  1. 下载发布包、.asc 文件和 .sha512 文件。

  2. 在 Unix 系统上,运行以下命令:

    for file in `find . -type f -iname '*.asc'`
    do
    gpg --verify ${file}
    done

    gpg --verify rocketmq-all-%version-number%-source-release.zip.asc rocketmq-all-%version-number%-bin-release.zip

    如果您看到 Good signature,则签名正确。

    gpg: Good signature from ... gpg: Signature made ...
  3. 根据 SHA512 验证版本的一致性。

    gpg --print-md SHA512 rocketmq-all-%version-number%-source-release.zip 
    gpg --print-md SHA512 rocketmq-all-%version-number%-bin-release.zip

5. 关闭暂存仓库

  1. 预发布版本完成清单验证后,关闭 Nexus 暂存仓库并准备版本投票。
  2. 在 Nexus 上选择 orgapacherocketmq-XXX 待发布版本,点击 Close 图标以关闭暂存仓库。
  3. 关闭前,Nexus 将执行一系列签名验证和文本检查。
  4. 如果验证成功,Nexus 将关闭仓库并提供暂存仓库 URL,即投票邮件中标记为 "The staging repo" 的地址。
  5. 如果验证失败,修复问题、回滚并重新执行发布流程。
  6. 如果上述工作全部完成,使用 SVN 将其复制到 /dev/rocketmq Apache 远程仓库。

6. 版本投票

RocketMQ 社区通过 dev@rocketmq.apache.org 邮件列表进行版本投票。

参考 投票流程 以了解 Apache 的投票流程。

6.1 社区投票

邮件列表:dev 列表

邮件主题:[VOTE]: Release Apache RocketMQ \<release-version> RC\<RC Number>

你好,RocketMQ 社区:

这是关于 Apache RocketMQ \<release version>的发布投票。

${RocketMQ 简介及本次发布特性。}

制品地址:

https://dist.apache.org/repos/dist/dev/rocketmq/${release version}

暂存仓库地址:

https://repository.apache.org/content/repositories/orgapacherocketmq-XXX/

版本 Git Tag:

\<GitHub 仓库中该 Tag 的链接>

版本 Tag 哈希值:

\<该 Tag 的哈希值>

发布说明:

\<插入 RocketMQ 发布说明链接>

制品已使用以下 Key 签名:\<签名密钥 ID>,可在 keys 文件中找到

https://dist.apache.org/repos/dist/dev/rocketmq/KEYS

投票将至少持续 72 小时,直到获得必要数量的投票。

请按以下标准投票:

[ ]+1 同意

[ ]+0 无意见

[ ]-1 不同意(需说明理由)

谢谢,

Apache RocketMQ 团队

提示

版本 Tag 哈希值:可以使用提交 ID (commit id)。

6.2 结果公告

72 小时后,如果有至少 3 票赞成且无反对票,请发送以下邮件宣布版本发布。

邮件主题:[RESULT][VOTE]: Release Apache RocketMQ \<release-version> RC\<RC Number>

你好,RocketMQ 社区:

Apache RocketMQ <release version> 的投票现已结束,投票已通过,结果为:[number]个绑定赞成票 (+1),[number]非绑定赞成票 (+1),无 0 或 -1 票。

绑定赞成票:

用户名 (Apache ID)

用户名 (Apache ID)

用户名 (Apache ID)

....

非绑定赞成票:

用户名 (Apache ID)

....

发布内容即将发布。

谢谢,

Apache RocketMQ 团队

如果投票未通过,请修复问题、回滚、增加 RC 编号、重启发布流程,并重新发起版本投票流程。

更新邮件主题:[RESTART][VOTE][#]: Release Apache RocketMQ \<release-version> RC\<RC Number>

7. 发布版本

Apache RocketMQ PMC 投票通过后,将版本发布到 Maven Nexus 仓库和 Apache 版本仓库。

  1. 发布到 Nexus 仓库,在暂存区选择 orgapacherocketmq-XXX 并点击 Release 图标进行发布。
  2. 发布到 Apache 版本仓库,使用 SVN 将版本复制到 /release/rocketmq
  3. Apache RocketMQdevelop 分支合并到 master 分支。
  4. 将发布说明添加到 Releases · apache/rocketmq
  5. 创建一个新分支,命名为 release-x.x.x
  6. 更新 apache/rocketmq-site 官网首页

8. 版本公告

邮件列表:announce@apache.org, users@rocketmq.apache.org,

private@rocketmq.apache.org, dev@rocketmq.apache.org

邮件主题: [ANNOUNCE] Release Apache RocketMQ \<release-version>

大家好,

Apache RocketMQ 团队很高兴地宣布 Apache RocketMQ \<release version 的发布。>.

${RocketMQ 简介及本次发布特性。}

关于 Apache RocketMQ 的更多详细信息,请访问:

https://rocketmq.apache.org/

发布制品可以在此处下载:

https://dist.apache.org/repos/dist/release/rocketmq/${release-version}

发布说明可以在此处找到:

\<插入 RocketMQ 发布说明链接>

谢谢,

Apache RocketMQ 团队