🪜【CI/CD】如何发布 Java 包到 Maven 中央仓库
前言
最近参与一些开源项目,涉及到发版相关的问题,没有看到详细又不过时的教程,于是自己调研摸索,总结出了这篇文章。
本文主要参考官方文档进行编写,演示仓库位于 https://github.com/seriouszyx/maven-release-example。
准备工作
Coordinates
Maven 用 groupid 来标识项目空间,用域名逆序的方式命名。下面是两种命名的例子,如果有自己的域名,直接使用就可以;如果没有,可以使用 github 等代码托管服务的域名。
- www.seriouszyx.com -> com.seriouszyx
- github.com/seriouszyx -> io.github.seriouszyx
下面是支持个人 groupid 的代码托管服务,假设使用 io.github.myusername
,需要创建一个名为 OSSRH-TICKETNUMBER 的公开仓库进行验证(验证成功后可删除)。如果使用自己的域名,也需要添加 TXT 解析,稍后会提到。
服务 | groupid | 相关文档 |
---|---|---|
GitHub | io.github.myusername | https://pages.github.com/ |
GitLab | io.gitlab.myusername | https://about.gitlab.com/stages-devops-lifecycle/pages/ |
Gitee | io.gitee.myusername | https://gitee.com/help/articles/4136 |
Bitbucket | io.bitbucket.myusername | https://support.atlassian.com/bitbucket-cloud/docs/publishing-a-website-on-bitbucket-cloud/ |
SourceForge | io.sourceforge.myusername | https://sourceforge.net/p/forge/documentation/Project%20Web%20Services/ |
artifactId 用来标识项目本身,如果项目命名很长,可以使用“-”来进行分隔。
GPG
将组件发布到 Maven 中央仓库需要使用 PGP 进行签名,GnuPG (又称 GPG) 都是 OpenPGP 的实现,需要先创建你自己的键值对,再上传到服务器以供验证。
从 https//www.gnupg.org/download/ 下载安装,使用 --version
标志检查。
$ gpg --version
gpg (GnuPG) 2.2.28
libgcrypt 1.8.8
Copyright (C) 2021 g10 Code GmbH
License GNU GPL-3.0-or-later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Home: C:/Users/Yixiang Zhao/AppData/Roaming/gnupg
Supported algorithms:
Pubkey: RSA, ELG, DSA, ECDH, ECDSA, EDDSA
Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
CAMELLIA128, CAMELLIA192, CAMELLIA256
Hash: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed, ZIP, ZLIB, BZIP2
安装成功后产生键值对,过程中需要填写姓名、邮箱和密码,密钥有效期为 2 年,到时候需要使用密码延长有效期,可以看到我的公钥 id 是 444D548E4E29746B4E2C89FC89985FBD3651A87B
。
$ gpg --gen-key
gpg (GnuPG) 2.2.28; Copyright (C) 2021 g10 Code GmbH
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Note: Use "gpg --full-generate-key" for a full featured key generation dialog.
GnuPG needs to construct a user ID to identify your key.
Real name: Yixiang Zhao
Email address: seriouszyx@gmail.com
You selected this USER-ID:
"Yixiang Zhao <seriouszyx@gmail.com>"
Change (N)ame, (E)mail, or (O)kay/(Q)uit? O
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
gpg: key 89985FBD3651A87B marked as ultimately trusted
gpg: directory 'C:/Users/Yixiang Zhao/AppData/Roaming/gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as 'C:/Users/Yixiang Zhao/AppData/Roaming/gnupg/openpgp-revocs.d\444D548E4E29746B4E2C89FC89985FBD3651A87B.rev'
public and secret key created and signed.
pub rsa3072 2021-10-14 [SC] [expires: 2023-10-14]
444D548E4E29746B4E2C89FC89985FBD3651A87B
uid Yixiang Zhao <seriouszyx@gmail.com>
sub rsa3072 2021-10-14 [E] [expires: 2023-10-14]
后续步骤需要通过你的公钥来进行验证,所以把它上传到服务器中,注意 --send-keys
后面是你自己的公钥。
$ gpg --keyserver keyserver.ubuntu.com --send-keys 444D548E4E29746B4E2C89FC89985FBD3651A87B
gpg: sending key 89985FBD3651A87B to hkp://keyserver.ubuntu.com
等大概十几分钟,验证公钥是否发布成功。
$ gpg --keyserver keyserver.ubuntu.com --recv-keys 444D548E4E29746B4E2C89FC89985FBD3651A87B
gpg: key 89985FBD3651A87B: "Yixiang Zhao <seriouszyx@gmail.com>" not changed
gpg: Total number processed: 1
gpg: unchanged: 1
在 Sonatype 创建 Issue
开发者要想将组件发布至 Maven 中央仓库,需要借助于 Sonatype 的开源软件存储库托管(Open Source Software Repository Hosting, OSSRH)服务。Sonatype 使用 JIRA 来管理请求,所以需要先注册账号。
注册好之后,就可以创建一个新的 Issue(文档中又称 Project ticket),可以参考我创建的测试 Issue OSSRH-74121。
这时需要进行人工审核,将分配的编号 OSSRH-74121
添加到域名的 TXT 解析,或者在 GitHub 等托管服务中创建一个名为 OSSRH-74121
的公开库。我等了大概一两个小时,就通过了审核,Status 变成了 RESOLVED
。
配置发布信息
本文使用 Maven 为例发布自己的 Java 包,如果使用 Gradle、Ant 等工具,可以参照官方文档。
分发管理和认证
在 pom.xml
中添加以下配置,使得可以使用 Nexus Staging Maven plugin 插件向 OSSRH Nexus Repository Manager 发布。
<distributionManagement>
<snapshotRepository>
<id>ossrh</id>
<url>https://s01.oss.sonatype.org/content/repositories/snapshots</url>
</snapshotRepository>
<repository>
<id>ossrh</id>
<url>https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/</url>
</repository>
</distributionManagement>
<build>
<plugins>
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6.8</version>
<extensions>true</extensions>
<configuration>
<serverId>ossrh</serverId>
<nexusUrl>https://s01.oss.sonatype.org/</nexusUrl>
<autoReleaseAfterClose>true</autoReleaseAfterClose>
</configuration>
</plugin>
...
</plugins>
</build>
下面是发布所需的 JIRA 账户信息,写入到 Maven 的 setting.xml
文件中(通常位于 ~/.m2
)。
<settings>
<servers>
<server>
<id>ossrh</id>
<username>your-jira-id</username>
<password>your-jira-pwd</password>
</server>
</servers>
</settings>
注意这里的 id 和 snapshotRepository
/repository
中的 id,以及 plugin
中的 id 都是相同的,都为 ossrh。
Javadoc 和源代码
为了生成 Javadoc 和源 jar 文件,需要在 pom.xml
中添加以下配置。
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
GPG 签名组件
Maven GPG 插件使用以下配置为组件进行签名。
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
并在 setting.xml
中配置 gpg 的运行文件和密码。
<settings>
<profiles>
<profile>
<id>ossrh</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<gpg.executable>D:/Work/GnuPG/bin/gpg.exe</gpg.executable>
<gpg.passphrase>the_pass_phrase</gpg.passphrase>
</properties>
</profile>
</profiles>
</settings>
如果想要发布正式版本,还需要在 pom.xml
中配置项目名、描述、开发者等信息。
<name>maven-release-example</name>
<description>Example project to deploy maven projects.</description>
<url>https://github.com/seriouszyx/maven-release-example</url>
<licenses>
<license>
<name>MIT</name>
<url>https://opensource.org/licenses/MIT</url>
</license>
</licenses>
<developers>
<developer>
<name>Yixiang Zhao</name>
<email>seriouszyx@gmail.com</email>
<organization>seriouszyx</organization>
<organizationUrl>https://seriouszyx.com/</organizationUrl>
</developer>
</developers>
<scm>
<connection>scm:git:https://github.com/seriouszyx/maven-release-example.git</connection>
<developerConnection>scm:git:https://github.com/seriouszyx/maven-release-example.git</developerConnection>
<url>https://github.com/seriouszyx/maven-release-example</url>
</scm>
发布
更改 pom.xml
中的版本号为 1.0.0
, 在项目根目录运行 mvn clean deploy
即可发布,发布成功后组件会存储到一个临时存储库中,只对团队成员开放,可以在 https://s01.oss.sonatype.org/ 访问,点击右上角登录 JIRA 的账号,搜索刚发布的组件,即可查询到相关信息。
因为之前在 maven 插件 nexus-staging-maven-plugin 中的 autoReleaseAfterClose
属性设置为 true 了,所以自动上传到 staging repository ,并且自动执行了 close->release->drop 三步曲,等待两小时后就可以在 https://search.maven.org 查到了。
在新建工程的 pom.xml
种添加依赖,即可使用 jar 包中的方法。
<dependency>
<groupId>com.seriouszyx</groupId>
<artifactId>maven-release-example</artifactId>
<version>1.0.0</version>
</dependency>
- 版权声明:本文采用知识共享 3.0 许可证 (保持署名-自由转载-非商用-非衍生)
- 发表于 2021-10-16