参考以下链接,了解 ASF 版本发布流程:
遵循 Apache 版本发布指南,对发布版本签名,用户也可据此判断下载的版本是否被篡改。
创建 pgp
密钥用于版本签名,使用 <your Apache ID>@apache.org 作为密钥 USER-ID
详情可参考 Apache Releases Signing documentation,Cryptography with OpenPGP
生成密钥的简要流程:
gpg --gen-key
生成一个新的 gpg
密钥, 设置密钥长度为 4096 并设置永不过期gpg --keyserver keys.openpgp.org --send-key <your key id>
上传密钥到公钥服务器gpg --armor --export <your key id> >> gpgapachekey.txt
导出公钥到文本文件Tips: 需要设置默认公钥, 若有多个公钥,请修改 ~/.gnupg/gpg.conf
参考示例:
[root@localhost ~]# gpg --gen-key gpg (GnuPG) 2.0.22; Copyright (C) 2013 Free Software Foundation, Inc. ... # 密钥生成目录 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. # 设置 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
配置 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>
Tips: 推荐使用 Maven's password encryption capabilities 加密 gpg.passphrase
③ 构建 Artifacts 并签名
mvn clean install -Papache-release
解决与该发布版本相关的 JIRA issues 和 GitHub issues
检查 MQVsersion 是否与发布版本一致。
通过 RocketMQ JIRA 生成 Release Notes,推送到 rocketmq-site, 并添加链接至版本选举邮件。
使用 Maven Release plugin 版本发布插件,发布 Artifact 至 ASF Nexus 暂存库,完成版本验证和版本投票后,拷贝至 Apache SVN 版本库。
确认 MQVersion 版本,若与 release-4.5.0
形式不符或版本不一致,修改至正确并推送到 develop
分支。
public static final int CURRENT_VERSION = Version.V4_5_0.ordinal();
切换至 develop
分支,确认与该版本相关的 GitHub PRs 均已合并。
① 配置 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 plugin
mvn release:clean mvn release:prepare mvn release:perform
执行以下流程将生成的 Artifacts 放入暂存库:
mvn clean release:clean
:清除构建失败及丢弃的版本mvn release:prepare -Psigned_release -Darguments="-DskipTests"
:根据 SCM
属性更新 tagmvn -Psigned_release release:perform -Darguments="-DskipTests"
:将生成 artifacts 暂存到 Nexus repo。可添加 -DdryRun=true
参数执行预演执行完上述流程可在 Nexus staging repo 或本地分支的 target
目录下找到预发布版本的 Artifacts
Tips: 只发布源码版本,仅需要保留源码和相关 jar 文件,Nexus GUI 中右键 delete
其余 artifact
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
Tips: 源码版本和二进制版本应以 rocketmq-all
开头,以便使用 Docker 构建 RocketMQ Docker Build
若执行 staging 过程出现问题,按照如下流程进行回滚:
删除在 2.2 步骤中创建的 tag
git tag -ln
git tag -d rocketmq-all-x1.x2.x3
git push origin :refs/tags/rocketmq-all-x1.x2.x3
删除 2.2 步骤中开发分支的提交记录
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 重做
二进制版本和源码版本使用相同的代码分支构建,需要注意操作系统版本。
有些依赖,比如 netty tc-native
对操作系统敏感。
mvn clean install
mvn clean install -Pit-test
成功构建后,同样需要生成 .asc 文件和 .sha512 文件,完成验证和投票后,最终并拷贝到 svn 仓库。
按照下面的流程验证 GPG 签名、SHA512 摘要
.asc
文件,.sha512
文件for file in `find . -type f -iname '*.asc'` do gpg --verify ${file} done
or
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 ...
gpg --print-md SHA512 rocketmq-all-%version-number%-source-release.zip gpg --print-md SHA512 rocketmq-all-%version-number%-bin-release.zip
预发布版本完成清单验证后, 关闭 Nexus 暂存库,准备进行版本选举。
选择 Nexus 上的 orgapacherocketmq-XXX
待发布版本,点击 Close
图标,关闭暂存库。
关闭之前,Nexus 会进行一些系列的签名验证和文本校验。
校验通过, Nexus 会关闭仓库并提供暂存库URL,在选举邮件中标注为:The staging repo
若校验失败,修复 issues 回滚并重新执行版本发布流程。
若以上工作均已完备,使用 SVN 拷贝至 /dev/rocketmq Apache 远程仓库。
RocketMQ 社区通过 dev@rocketmq.apache.org 邮件列表进行版本选举。
参考 voting process,了解Apache 投票流程。
邮件列表:dev list
邮件主题:[VOTE]: Release Apache RocketMQ <release-version> RC<RC Number>
Hello RocketMQ Community,
This is the vote for <release version> of Apache RocketMQ.
${A brief introduction to RocketMQ and the features of this release.}
The artifacts:
https://dist.apache.org/repos/dist/dev/rocketmq/${release version}
The staging repo:
https://repository.apache.org/content/repositories/orgapacherocketmq-XXX/
Git tag for the release:
<link to the tag of GitHub repo>
Hash for the release tag:
<Hash value of the release tag>
Release Notes:
<insert link to the rocketmq release notes>
The artifacts have been signed with Key : <ID of signing key>, which can be found in the keys file:
https://dist.apache.org/repos/dist/dev/rocketmq/KEYS
The vote will be open for at least 72 hours or until necessary number of votes are reached.
Please vote accordingly:
[ ] +1 approve
[ ] +0 no opinion
[ ] -1 disapprove with the reason
Thanks,
The Apache RocketMQ Team
Tips: Hash for the release tag: 可使用 commit id
72 小时后,若至少有 3 票通过而没有反对票,则发送如下邮件庆祝版本发布
邮件主题:[RESULT][VOTE]: Release Apache RocketMQ <release-version> RC<RC Number>
Hello RocketMQ Community,
The Apache RocketMQ
<release version>
vote is now closed and has passed with [number] binding +1s, [number] non-binding +1s and no 0 or -1:Binding votes +1s:
User Name (Apache ID)
User Name (Apache ID)
User Name (Apache ID)
....
Non-binding votes +1s:
User Name (Apache ID)
....
The release will be published soon.
Thanks,
The Apache RocketMQ Team
若投票未通过, 修复 issues, 回滚, 增加 RC 的编号,重新启动版本发布流程,重新发起版本投票流程
更新邮件主题:[RESTART][VOTE][#]: Release Apache RocketMQ <release-version> RC<RC Number>
Apache RocketMQ PPMC 投票通过后, 发布版本到 Maven Nexus 仓库和 Apache 版本仓库
Release
图标发布develop
分支至 master
分支release-x.x.x
邮件列表:announce@apache.org, users@rocketmq.apache.org,
private@rocketmq.apache.org, dev@rocketmq.apache.org
邮件主题: [ANNOUNCE] Release Apache RocketMQ <release-version>
Hi all,
The Apache RocketMQ team would like to announce the release of Apache RocketMQ <release version>.
${A brief introduction to RocketMQ and the features of this release.}
More details regarding Apache RocketMQ can be found at:
The release artifacts can be downloaded here:
https://dist.apache.org/repos/dist/release/rocketmq/${release-version}
The release notes can be found here:
<insert link to the rocketmq release notes>
Thanks,
The Apache RocketMQ Team