跳至主要内容
版本: 5.0

发布手册

1. 简介

1.1 Apache 发布文档

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

1.2 PGP 签名

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

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

有关更多详细信息,请参考 Apache Releases Signing 文档Cryptography with OpenPGP

生成密钥的简要流程:

  • 使用 gpg --gen-key 生成新的 gpg 密钥,将密钥长度设置为 4096 且设置为永不过期
  • 使用 gpg --keyserver keys.openpgp.org --send-key <您的密钥 ID> 将密钥上传到公钥服务器
  • 使用 gpg --armor --export <您的密钥 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: [email protected]
Comment: rocketmq
You selected this USER-ID:
"rocketmq (rocketmq) <[email protected]>"

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) <[email protected]>
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) <[email protected]>
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 问题。

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

1.5 发布说明

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

2. 构建源代码发布

使用 Maven Release 插件 版本发布插件将 Artifact 发布到 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>[email protected]:apache/rocketmq.git</url>
<connection>scm:git:[email protected]:apache/rocketmq.git</connection>
<developerConnection>scm:git:[email protected]:apache/rocketmq.git</developerConnection>
<tag>rocketmq-all-x.x.x</tag>
</scm>

② maven release 插件

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

按照此流程将生成的 Artifact 放置到暂存存储库中:

  1. mvn clean release:clean:清除失败的构建和已丢弃的版本。
  2. mvn release:prepare -Psigned_release -Darguments="-DskipTests":根据 SCM 属性更新标签。
  3. mvn -Psigned_release release:perform -Darguments="-DskipTests":将生成的工件暂存到 Nexus 存储库。您可以添加 -DdryRun=true 参数以执行干运行。

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

提示

要仅发布源代码版本,请仅保留源代码和相关的 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 中创建的标签

    • 列出所有标签并找到最近创建的标签

      git tag -ln
    • 从本地存储库中删除标签

      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,该 URL 在选举邮件中标记为“The staging repo”。
  5. 如果验证失败,请修复问题、回滚并重新执行发布流程。
  6. 如果所有上述工作都已完成,请使用 SVN 将其复制到 /dev/rocketmq Apache 远程存储库。

6. 版本选举

RocketMQ 社区通过 **[email protected]** 邮件列表进行版本选举。

请参考 投票流程 了解 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 版本}

暂存库

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

发布的 Git 标签

\<GitHub 仓库标签的链接>

发布标签的哈希值

\<发布标签的哈希值>

发布说明

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

工件已使用密钥:\<签名密钥的 ID>签名,可以在密钥文件中找到

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

投票将至少开放 72 小时,或直到达到必要的投票数。

请根据情况投票

[ ]+1 赞成

[ ]+0 无意见

[ ]-1 反对,并说明原因

谢谢,

Apache RocketMQ 团队

提示

发布标签的哈希值:您可以使用提交 ID。

6.2 结果公布

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

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

您好,RocketMQ 社区:

Apache RocketMQ <release version> 投票现已结束,并以[数量]绑定 +1 票,[数量]非绑定 +1 票,以及 0 或 -1 票通过。

绑定投票 +1 票

用户名(Apache ID)

用户名(Apache ID)

用户名(Apache ID)

....

非绑定投票 +1 票

用户名(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. 版本公告

邮件列表:[email protected], [email protected],

[email protected], [email protected]

邮件主题: [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 团队