发包到Maven Central Repository流程分享
OrdinaryRoad
上海
1
26
313
0
当我们使用构建工具构建项目时,引入依赖是很方便的。当我们想让他人使用自己的项目时,可以通过共享源码、打二进制包等方式。本文介绍了将JAVA项目发布到Maven中心仓库的流程,所用项目构建工具为Maven。
友情提示:此篇文章大约需要阅读 31分50秒
### 1. 环境准备
#### 1.1 申请权限
##### 1.1.1 注册账号
[Sign up for Jira - Sonatype JIRA](https://issues.sonatype.org/secure/Signup!default.jspa)
##### 1.1.2 新建问题(jira)
[创建问题](https://issues.sonatype.org/secure/CreateIssue!default.jspa)
- 问题类型:![New Project](https://issues.sonatype.org/secure/viewavatar?size=xsmall&avatarId=14241&avatarType=issuetype "New Project - Add a new project to the repository") New Project
- 概要:随便填
- Group Id:项目pom文件中的group id
- 官方帮助文档:[Choosing your Coordinates - The Central Repository Documentation (sonatype.org)](https://central.sonatype.org/publish/requirements/coordinates/)
- 如果使用自己的域名,例如 `ordinaryroad.tech`,则可以填 `tech.ordinaryroad`,新建成功后需要[添加一条内容为该问题的jira号的TXT解析记录](https://central.sonatype.org/faq/how-to-set-txt-record/)例如 `OSSRH-XXXXXXX`,用于证明域名的所有权
- 通过后可以发布子域名的包,例如项目group id为 `tech.ordinaryroad.bilibili.live`,就不需要再次提交申请了
- Project URL:项目网站地址
- 例如[https://github.com/1962247851/ordinaryroad-bilibili-live](https://github.com/1962247851/ordinaryroad-bilibili-live)
- SCM url:源码版本控制地址
- 例如[https://github.com/1962247851/ordinaryroad-bilibili-live.git](https://github.com/1962247851/ordinaryroad-bilibili-live.git)
其余默认即可
##### 1.1.3 新建成功后等待结果即可
注意时区差异,我晚上申请的,10来分钟就通过了
拒绝后会留言告诉你问题,往下翻可以看到活动日志,不需要重新创建jira,改正后重新开启jira即可
#### 1.2 安装配置gpg
签名工具,确保文件未被篡改
参考:[Working with PGP Signatures - The Central Repository Documentation (sonatype.org)](https://central.sonatype.org/publish/requirements/gpg/)
##### 1.2.1 安装
下载地址:[GnuPG - Download](https://gnupg.org/download/index.html#sec-1-2)
mac可以使用homebrew安装 `brew install gnupg`
安装后使用 `gpg --version`验证
```bash
$ gpg --version
gpg (GnuPG) 2.4.1
libgcrypt 1.10.2
Copyright (C) 2023 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: /home/mylocaluser/.gnupg
支持的算法:
公钥: RSA, ELG, DSA, ECDH, ECDSA, EDDSA
密文: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
CAMELLIA128, CAMELLIA192, CAMELLIA256
散列: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
压缩: 不压缩, ZIP, ZLIB, BZIP2
```
##### 1.2.2 生成密钥对
```bash
$ gpg --gen-key
gpg (GnuPG) 2.2.19; Copyright (C) 2019 Free Software Foundation, Inc.
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: Central Repo Test
Email address: central@example.com
You selected this USER-ID:
"Central Repo Test <central@example.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 8190C4130ABA0F98 marked as ultimately trusted
gpg: revocation certificate stored as
'/home/mylocaluser/.gnupg/openpgp-revocs.d/CA925CD6C9E8D064FF05B4728190C4130ABA0F98.rev'
public and secret key created and signed.
pub rsa3072 2021-06-23 [SC] [expires: 2023-06-23]
CA925CD6C9E8D064FF05B4728190C4130ABA0F98
uid Central Repo Test <central@example.com>
sub rsa3072 2021-06-23 [E] [expires: 2023-06-23]
```
##### 1.2.3 查看密钥对
`CA925CD6C9E8D064FF05B4728190C4130ABA0F98`为keyid
```bash
$ gpg --list-keys
/home/mylocaluser/.gnupg/pubring.kbx
---------------------------------
pub rsa3072 2021-06-23 [SC] [expires: 2023-06-23]
CA925CD6C9E8D064FF05B4728190C4130ABA0F98
uid [ultimate] Central Repo Test <central@example.com>
sub rsa3072 2021-06-23 [E] [expires: 2023-06-23]
```
> 如果有多个密钥对,则需要使用短keyid(十六进制格式的keyid)例如 `0x3ABDEC12`,配置在项目的 `maven-gpg-plugin`插件里,用于指定所用密钥
```bash
$ gpg --list-signatures --keyid-format 0xshort
/home/mylocaluser/.gnupg/pubring.kbx
---------------------------------
pub rsa3072/0x3ABDEC12 2021-01-27 [SC] [expires: 2023-01-27]
74524542545300A398653AB5242798823ABDEC12
uid [ultimate] Other Name <otheremail@example.com>
sig 3 0x3ABDEC12 2021-01-27 Other Name <alarconj@gmail.com>
sub rsa3072 2021-01-27 [E] [expires: 2023-01-27]
sig 0x3ABDEC12 2021-01-27 Julian Alarcon <alarconj@gmail.com>
pub rsa3072/0x0ABA0F98 2021-06-23 [SC] [expires: 2022-03-21]
CA925CD6C9E8D064FF05B4728190C4130ABA0F98
uid [ultimate] Central Repo Test <central@example.com>
sig 3 0x0ABA0F98 2021-06-24 Central Repo Test <central@example.com>
sub rsa3072/0x7C17C93B 2021-06-23 [E] [expires: 2023-06-23]
sig 0x0ABA0F98 2021-06-23 Central Repo Test <central@example.com>
```
##### 1.2.4 分发公钥
分发到公共服务器,使得他人能够验证文件的完整性,`CA925CD6C9E8D064FF05B4728190C4130ABA0F98`为keyid
```bash
gpg --keyserver keyserver.ubuntu.com --send-keys CA925CD6C9E8D064FF05B4728190C4130ABA0F98
```
> 可以发布到多个服务器
```bash
gpg --keyserver keys.openpgp.org --send-keys CA925CD6C9E8D064FF05B4728190C4130ABA0F98
gpg --keyserver pgp.mit.edu --send-keys CA925CD6C9E8D064FF05B4728190C4130ABA0F98
```
### 2. 更新配置
#### 2.1 更新Maven配置 `settings.xml`
##### 2.1.1 添加ossrh的server
```xml
<settings>
<servers>
...
<!-- https://central.sonatype.org/publish/publish-maven/ -->
<!-- ossrh -->
<server>
<id>ossrh</id>
<username>${jira用户名}</username>
<password>${jira密码}</password>
</server>
...
</servers>
</settings>
```
##### 2.1.2 添加profile
```xml
<settings>
...
<!-- ossrh-start -->
<!-- https://central.sonatype.org/publish/publish-maven/#gpg-signed-components -->
<profile>
<id>ossrh</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<!-- 根据安装情况设置:gpg2/gpg -->
<gpg.executable>gpg</gpg.executable>
<gpg.passphrase>${生成密钥时填的密码}</gpg.passphrase>
<maven-source-plugin.version>3.2.1</maven-source-plugin.version>
<maven-javadoc-plugin.version>3.5.0</maven-javadoc-plugin.version>
<maven-gpg-plugin.version>3.1.0</maven-gpg-plugin.version>
<nexus-staging-maven-plugin.version>1.6.13</nexus-staging-maven-plugin.version>
<gpg.keyname>${短keyid}</gpg.keyname>
</properties>
</profile>
<!-- 禁用注释检查 -->
<profile>
<id>disable-javadoc-doclint</id>
<activation>
<jdk>[1.8,)</jdk>
</activation>
<properties>
<javadoc.opts>-Xdoclint:none</javadoc.opts>
</properties>
</profile>
<!-- 自动发包 -->
<profile>
<id>ossrh-release-auto</id>
<properties>
<auto-release-after-close>true</auto-release-after-close>
</properties>
</profile>
<profile>
<id>ossrh-release-manually</id>
<properties>
<auto-release-after-close>false</auto-release-after-close>
</properties>
</profile>
<!-- ossrh-end -->
</profiles>
...
</settings>
```
#### 2.2 更新项目配置 `pom.xml`
##### 2.2.1 添加meta配置
```xml
<project>
...
<name>ordinaryroad-bilibili-live</name>
<description>使用Netty来连接B站直播间的弹幕信息流Websocket接口</description>
<url>https://github.com/1962247851/ordinaryroad-bilibili-live</url>
<licenses>
<license>
<name>The MIT License</name>
<url>https://opensource.org/license/mit/</url>
<distribution>repo</distribution>
</license>
</licenses>
<scm>
<url>https://github.com/1962247851/ordinaryroad-bilibili-live</url>
<connection>scm:git:https://github.com/1962247851/ordinaryroad-bilibili-live.git</connection>
<developerConnection>scm:git:https://github.com/1962247851/ordinaryroad-bilibili-live</developerConnection>
</scm>
<developers>
<developer>
<name>OrdinaryRoad</name>
<email>or-mjz@qq.com</email>
<url>https://github.com/1962247851</url>
<timezone>UTC+08:00</timezone>
</developer>
</developers>
...
</project>
```
##### 2.2.2 添加插件配置
```xml
<project>
<build>
<plugins>
...
<!-- 发包相关插件-start -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>${maven-source-plugin.version}</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>${maven-javadoc-plugin.version}</version>
<configuration>
<encoding>UTF-8</encoding>
<charset>UTF-8</charset>
<docencoding>UTF-8</docencoding>
</configuration>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<additionalJOption>${javadoc.opts}</additionalJOption>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>${maven-gpg-plugin.version}</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
<configuration>
<keyname>${gpg.keyname}</keyname>
<passphraseServerId>${gpg.keyname}</passphraseServerId>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>${nexus-staging-maven-plugin.version}</version>
<extensions>true</extensions>
<configuration>
<serverId>ossrh</serverId>
<nexusUrl>https://s01.oss.sonatype.org/</nexusUrl>
<autoReleaseAfterClose>${auto-release-after-close}</autoReleaseAfterClose>
</configuration>
</plugin>
<!-- 发包相关插件-end -->
</plugins>
</build>
</project>
```
### 3. 发包
- `mvn deploy`发包前最好先 `mvn clean`一次,或者用 `mvn clean deploy`
- 可以用注册的jira账户登录[Nexus Repository Manager (sonatype.org)](https://s01.oss.sonatype.org/#welcome),来[管理暂存的包](https://s01.oss.sonatype.org/#stagingRepositories),或[搜索发布的包](https://s01.oss.sonatype.org/#nexus-search;quick~),如果deploy后自动发布,release成功后会自动drop掉暂存的包
- 更多发包插件 `nexus-staging-maven-plugin`的配置介绍[Configuring Your Project for Deployment (sonatype.com)](https://help.sonatype.com/repomanager2/staging-releases/configuring-your-project-for-deployment#ConfiguringYourProjectforDeployment-DeploymentwiththeNexusStagingMavenPlugin)
#### 3.1 deploy时自动发布
ide中找到Maven的Profiles选项,选中 `ossrh-release-auto`,相当于 `mvn xxx -P ossrh-release-auto`
![Pastedimage20230520101428.png](https://api.ordinaryroad.tech/upms/file/download/ordinaryroad-blog/2023-05-20/e8967e45e5dc43c98024fc43250553ec.png)
效果与将 `nexus-staging-maven-plugin`的 `autoReleaseAfterClose`设置为 `true`一样
```xml
...
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>${nexus-staging-maven-plugin.version}</version>
<extensions>true</extensions>
<configuration>
<serverId>ossrh</serverId>
<nexusUrl>https://s01.oss.sonatype.org/</nexusUrl>
<autoReleaseAfterClose>true</autoReleaseAfterClose>
</configuration>
</plugin>
...
```
在控制台或者ide执行 `mvn clean deploy`后等待即可,发布成功后jira问题中会添加一条评论
```bash
mvn clean deploy
```
#### 3.2 deploy后手动发布
![Pastedimage20230520101634.png](https://api.ordinaryroad.tech/upms/file/download/ordinaryroad-blog/2023-05-20/cedd6bb135ac46048656f2b0329431d5.png)
相当于将 `nexus-staging-maven-plugin`的 `autoReleaseAfterClose`设置为 `false`
```xml
...
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>${nexus-staging-maven-plugin.version}</version>
<extensions>true</extensions>
<configuration>
<serverId>ossrh</serverId>
<nexusUrl>https://s01.oss.sonatype.org/</nexusUrl>
<autoReleaseAfterClose>false</autoReleaseAfterClose>
</configuration>
</plugin>
...
```
成功后只是暂存了,需要手动选择发布还是取消发布
- 控制台方式
> 确定发布
```bash
mvn nexus-staging:release
```
> 取消发布
```bash
mvn nexus-staging:drop
```
- 网页方式
登录[Nexus Repository Manager (sonatype.org)](https://s01.oss.sonatype.org/#welcome),选择相应的Repository进行release或者drop操作即可
### 4. 其他项目引用
刚发布[Maven Central - Search (sonatype.com)](https://central.sonatype.com/search)可能还搜不出来,可以先在这里面搜索使用
![Pastedimage20230520104707.png](https://api.ordinaryroad.tech/upms/file/download/ordinaryroad-blog/2023-05-20/0bd1d1dba0434ce1b10bbb1e3d5b9d5c.png)
#### 4.1 引入快照SNAPSHOT
```xml
<repositories>
<repository>
<id>ossrh-SNAPSHOT</id>
<url>https://s01.oss.sonatype.org/content/repositories/snapshots/</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
```
### 相关链接
1. [Sign up for Jira - Sonatype JIRA](https://issues.sonatype.org/secure/Signup!default.jspa)
2. [GnuPG - Download](https://gnupg.org/download/index.html#sec-1-2)
3. [Working with PGP Signatures - The Central Repository Documentation (sonatype.org)](https://central.sonatype.org/publish/requirements/gpg/)
4. [Configuring Your Project for Deployment (sonatype.com)](https://help.sonatype.com/repomanager2/staging-releases/configuring-your-project-for-deployment#ConfiguringYourProjectforDeployment-DeploymentwiththeNexusStagingMavenPlugin)
5. [Nexus Repository Manager (sonatype.org)](https://s01.oss.sonatype.org/#welcome)
6. [Maven Central - Search (sonatype.com)](https://central.sonatype.com/search)
---
### 2024年发包流程更新
> https://central.sonatype.org/publish/publish-portal-maven/
0. 迁移账号,添加并验证namespace
1. 更新账号凭证
![image.png](https://api.ordinaryroad.tech/upms/file/download/ordinaryroad-blog/2024-10-06/7e56dda3a7b84b5d8adc19831119db36.png)
2. 更新发包插件
```xml
<build>
<plugins>
<plugin>
<groupId>org.sonatype.central</groupId>
<artifactId>central-publishing-maven-plugin</artifactId>
<version>0.6.0</version>
<extensions>true</extensions>
<configuration>
<publishingServerId>central</publishingServerId>
<autoPublish>true</autoPublish>
</configuration>
</plugin>
<plugins>
</build>
```
3. `mvn clean deploy`
![image.png](https://api.ordinaryroad.tech/upms/file/download/ordinaryroad-blog/2024-10-06/b988c74546884bd5801a7c38c1fc704f.png)
本文作者:OrdinaryRoad
本文链接: 版权声明:本文为OrdinaryRoad博客博主 OrdinaryRoad 的原创文章,遵循
CC BY-SA 4.0
许可协议,转载请附上本文链接及本声明。
1
评论
已自动恢复阅读位置、日/夜间模式参数