发布jar包到Maven中央仓库
发布到第三方仓库
Maven 中央仓库并不支持直接上传 jar 包,因此需要将 jar 包发布到一些指定的第三方 Maven 仓库, 比如:Sonatype OSSRH 仓库,然后该仓库再将 jar 包同步到 Maven ,本文详细记录整个发布、同步过程。
注册一个 Sonatype 用户
进入地址:https://issues.sonatype.org/secure/Signup!default.jspa
注册 Sonatype 用户,Sonatype 通过 JIRA(JIRA 是 Atlassian 公司出品的项目与事务跟踪工具)
来管理 OSSRH 仓库。
创建一个发布构件的 issue
提交「构件发布申请」的第一步是在 JIRA Dashborad 上创建一个 issue。如下所示,点击Create
按钮:
会弹出一个对话框让你填写 issue 的详细信息,这里最重要的就是 Group Id,一般会带上域名, 千万别弄错了,这关系到以后发布其它的构件。我们这里是com.vesoft。
Sonatype 有域名验证,验证方式:
- 往你的 DNS 中添加 JIRA 编号记录重定向到你的 Github 主页
- 如果你没有域名,可参考这个链接:http://central.sonatype.org/pages/choosing-your-coordinates.html 的方法进行操作
- 选择一个带有项目托管信息的 GroupId,例如 io.github.facebook 或 com.github.facebook
-
另外一种推荐的方式是使用免费的 free managed security reporting service
- 将 https://hackerone.com/central-security-project/reports/new 作为你项目的安全信息保障 url,剩下的事情 Sonatype 工作人员会自行搞定。
等待 issue 审核通过
审核因为时差原因需要一定时间,审核通过后会收到邮件通知,同时在对应 issue 下会看到 Sonatype 工作人员的回复,一般是添加一个 comment,内容大致如下:
Configuration has been prepared, now you can: Deploy snapshot artifacts into
repository https://oss.sonatype.org/content/repositories/snapshots
Deploy release
artifacts into the staging repository https://oss.sonatype.org/service/local/staging/deploy/maven2
Promote staged artifacts into repository 'Releases' Download snapshot and release
artifacts from group https://oss.sonatype.org/content/groups/public
Download snapshot, release and staged artifacts from staging group
https://oss.sonatype.org/content/groups/staging
please comment on this ticket
when you promoted your first release, thanks
使用 GPG 生成密钥对
生成密钥对
gpg --gen-key
会让选择加密方式,默认选择: RSA and RSA (default)
,需输入用户名和邮箱,和 Passphase——相当于密钥库密码。
查看公钥
gpg --list-keys xxx/.gnupg/pubring.gpg --------------------------------- pub 2048R/xxxx 2019-12-02 uid $YOUR_UID <$YOUR_EMAIL> sub 2048R/**** 2019-12-02
这里的公钥 ID 是 xxxx,马上就会用到了。
将公钥上传到 PGP 密钥服务器
gpg --keyserver hkp://keys.gnupg.net:11371 --send-keys xxxx
查看公钥是否上传成功
> gpg --keyserver hkp://keys.gnupg.net:11371 --recv-keys xxxx gpg: 下载密钥‘xxxx’,从 hkp 服务器 keys.gnupg.net gpg: 密钥 xxxx:“$YOUR_UID <$YOUR_EMAIL>”未改变 gpg: 合计被处理的数量:1 gpg: 未改变:1
注意:
- 根据实际填写此处的公钥 ID
-
很多网上教程给的是
http://pool.sks-keyservers.net
,个人感觉http://pool.sks-keyservers.net
这个 keyserver 不好用,上传了 key,经常会验证失败, 也获取失败,maven 支持两个key servers:http://keys.gnupg.net:11371
和http://pool.sks-keyservers.net:11371
- 此处采用 hkp 协议而不是 http 协议很
- 多教程没有给端口,经试验,需加上端口号
本地的私钥用来对上传的构件进行数字签名,而下载该构件的用户可通过上传的公钥来验证签名 --需验证这个构件是否由本人上传的,因为存在构件被篡改的可能。
修改Maven配置文件
修改 Maven 配置文件主要是需要修改setting.xml
和项目的pom.xml
文件
配置 Maven 的 setting.xml
修改~/.m2/setting.xml
文件
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd"> <servers> <!-- ... --> <server> <id>snapshots</id> <username>$USER_NAME</username> <password>$YOUR_PASSWORD</password> </server> <server> <id>release</id> <username>$USER_NAME</username> <password>$YOUR_PASSWORD</password> </server> </servers> </settings>
替换USER_NAME
,YOUR_PASSWORD
为Sonatype
上面注册的用户名和密码,
这里的 ID 会在 pom.xml 里面使用到。
配置 Maven 的 pom.xml
<project> ... <!-- More Project Information --> <name>nebula-java</name> <description>Nebula Java Client</description> <url>https://github.com/vesoft-inc/nebula-java</url> <scm> <connection>scm:git:https://github.com/vesoft-inc/nebula</connection> <url>https://github.com/vesoft-inc/nebula</url> <developerConnection>scm:git:https://github.com/vesoft-inc/nebula</developerConnection> </scm> <licenses> <license> <name>Apache License, Version 2.0</name> <url>https://www.apache.org/licenses/LICENSE-2.0.txt</url> <distribution>repo</distribution> <comments>license</comments> </license> </licenses> ... <profiles> <profile> <id>release</id> <build> <plugins> <!-- Source --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <executions> <execution> <id>attach-sources</id> <goals> <goal>jar</goal> </goals> </execution> </executions> </plugin> <!-- Javadoc --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-javadoc-plugin</artifactId> <version>3.1.1</version> <configuration> <excludePackageNames>com.facebook.thrift:com.facebook.thrift.*</excludePackageNames> </configuration> <executions> <execution> <id>attach-javadocs</id> <phase>package</phase> <goals> <goal>jar</goal> </goals> <configuration> <doclint>none</doclint> </configuration> </execution> </executions> </plugin> <!-- GPG --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-gpg-plugin</artifactId> <version>1.6</version> <executions> <execution> <phase>verify</phase> <goals> <goal>sign</goal> </goals> </execution> </executions> </plugin> </plugins> </build> <distributionManagement> <repository> <id>release</id> <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url> </repository> <snapshotRepository> <id>snapshots</id> <url>https://oss.sonatype.org/content/repositories/snapshots/</url> </snapshotRepository> </distributionManagement> </profile> </profiles> ... </project>
pom.xml
中必须包括:name
、 description
、url
、licenses
、developers
、
cm
等基本信息 (血泪史之踩过的坑)发布 maven 除了 jar 必须还有文档包和源码包。
因此 pom 需添加maven-javadoc-plugin
和maven-source-plugin
。 参考示例:
com-vesoft-client |-- pom.xml |-- src\ `-- target `-- attach-source-javadoc-1.0-SNAPSHOT.jar `-- attach-source-javadoc-1.0-SNAPSHOT-javadoc.jar `-- attach-source-javadoc-1.0-SNAPSHOT-sources.jar
发布构建需要秘钥加密,因此 pom 需添加maven-gpg-plugin
(血泪史之踩过的坑)
多模块项目配置
nebula-java 是多模块项目
<modules> <module>client</module> <module>examples</module> </modules>
为了上传 Client,需要上传parent
的pom.xml
,否则 Client 会找不到依赖
(血泪史之踩过的坑),但我们又不希望上传examples
模块,所以要在examples
的maven-deploy-plugin
中声明skip
跳过布署。
故做了如下改动:
项目信息 name 、 description 、 url 、 licenses 、 developers 、 scm 等信息和
maven-gpg-plugin
放在 parent 的pom.xml
文件中:
<project> ... <name>nebula-java</name> <description>Nebula Java Client</description> <url>https://github.com/vesoft-inc/nebula-java</url> <scm> <connection>scm:git:https://github.com/vesoft-inc/nebula</connection> <url>https://github.com/vesoft-inc/nebula</url> <developerConnection>scm:git:https://github.com/vesoft-inc/nebula</developerConnection> </scm> <licenses> <license> <name>Apache License, Version 2.0</name> <url>https://www.apache.org/licenses/LICENSE-2.0.txt</url> <distribution>repo</distribution> <comments>license</comments> </license> </licenses> <developers> <developer> <id>$ID</id> <name>$NAME</name> <email>$EMAIL</email> <organization>vesoft</organization> <roles> <role>architect</role> <role>developer</role> </roles> </developer> </developers> <distributionManagement> <repository> <id>release</id> <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url> </repository> <snapshotRepository> <id>snapshots</id> <url>https://oss.sonatype.org/content/repositories/snapshots/</url> </snapshotRepository> </distributionManagement> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-gpg-plugin</artifactId> <version>1.6</version> <executions> <execution> <phase>verify</phase> <goals> <goal>sign</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
在 Java Client 的pom.xml
中添加maven-javadoc-plugin
、maven-source-plugin
和
maven-deploy-plugin
:
<plugins> ...... <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <executions> <execution> <id>attach-sources</id> <goals> <goal>jar</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-javadoc-plugin</artifactId> <version>3.1.1</version> <configuration> <excludePackageNames>com.facebook.thrift:com.facebook.thrift.*</excludePackageNames> </configuration> <executions> <execution> <id>attach-javadocs</id> <phase>package</phase> <goals> <goal>jar</goal> </goals> <configuration> <doclint>none</doclint> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-deploy-plugin</artifactId> <executions> <execution> <id>default-deploy</id> <phase>deploy</phase> </execution> </executions> </plugin> </plugins>
在 example 模块的pom.xml
中声明skip deploy
:
<plugins> ...... <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-deploy-plugin</artifactId> <configuration> <skip>true</skip> </configuration> </plugin> </plugins>
Q: 为什么 maven-gpg-plugin 放在 parent 的 pom.xm l中,而 maven-javadoc-plugin,maven-source-plugin 插件放在 Client 的 pom.xml 中
A: 因为上传的所有构件都需要加密,包括 parent 的 pom.xml,因此放在 parent 中; 而只有 Client 需要上传 javadoc,source,因此 maven-javadoc-plugin,maven-source-plugin 插件放在 Client 中。