发布到中央仓库

注册Sonatype 用户

注册地址:

https://issues.sonatype.org/secure/Signup!default.jspa

切记要记住用户名密码,后面都要用到。

  1. email:aoxiaojian@gmail.com
  2. Fullname: Sky Ao
  3. Username: skyao
  4. password: $$$$$$$$$

创建Issue

为了发布我们的构件,需要以提交issue的方式创建ticket,地址为:

https://issues.sonatype.org/secure/CreateIssue.jspa?issuetype=21&pid=10134

内容参考:

https://issues.sonatype.org/browse/OSSRH-37470

备注:

  1. group id 可以是io.dreamfly这种,然后所有的子域名就都可以用
  2. 需要提供信息,说明域名是自己所有的

提交之后等待答复,因为时差原因,一般是隔天。

如果审批通过,会有回复,同时issue状态修改为 resolved。

发布准备

生成gpg秘钥

使用gpg --gen-key命令生成gpg秘钥:

  1. gpg --gen-key
  2. Please select what kind of key you want:
  3. (1) RSA and RSA (default)
  4. (2) DSA and Elgamal
  5. (3) DSA (sign only)
  6. (4) RSA (sign only)
  7. Your selection? 1
  8. RSA keys may be between 1024 and 4096 bits long.
  9. What keysize do you want? (2048)
  10. Requested keysize is 2048 bits
  11. Please specify how long the key should be valid.
  12. 0 = key does not expire
  13. <n> = key expires in n days
  14. <n>w = key expires in n weeks
  15. <n>m = key expires in n months
  16. <n>y = key expires in n years
  17. Key is valid for? (0) 0
  18. Key does not expire at all
  19. Is this correct? (y/N) y

然后会要求输入信息:

  1. Real nameSky Ao
  2. Email address:aoxiaojian@gmail.com
  3. Comment:aoxiaojian

再要求输入密码You need a Passphrase to protect your secret key.为了简单起见,设置为和sonatype登录账号一致。

之后有个奇怪的环节:

  1. gpg: gpg-agent is not available in this session
  2. We need to generate a lot of random bytes. It is a good idea to perform
  3. some other action (type on the keyboard, move the mouse, utilize the
  4. disks) during the prime generation; this gives the random number
  5. generator a better chance to gain enough entropy.
  6. Not enough random bytes available. Please do some other work to give
  7. the OS a chance to collect more entropy! (Need 242 more bytes)

只好乱敲一顿键盘,哗哗哗。

  1. gpg: /home/sky/.gnupg/trustdb.gpg: trustdb created
  2. gpg: key 732796B4 marked as ultimately trusted
  3. public and secret key created and signed.
  4. gpg: checking the trustdb
  5. gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
  6. gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u
  7. pub 2048R/732796B4 2017-11-16
  8. Key fingerprint = DD69 ###
  9. uid Sky Ao$$$
  10. sub 2048R/400AA044 2017-11-16

总算生成了,验证一下:

  1. gpg --list-keys
  2. /home/sky/.gnupg/pubring.gpg
  3. ----------------------------
  4. pub 2048R/732796B4 2017-11-16
  5. uid Sky Ao (aoxiaojian) <aoxiaojian@gmail.com>
  6. sub 2048R/400AA044 2017-11-16

注意这里的732796B4后面会用到。

发布gpg公钥

  1. gpg --keyserver hkp://pool.sks-keyservers.net --send-keys 732796B4
  2. gpg: sending key 732796B4 to hkp server pool.sks-keyservers.net

验证公钥是否发布成功:

  1. gpg --keyserver hkp://pool.sks-keyservers.net --recv-keys 732796B4
  2. gpg: requesting key 732796B4 from hkp server pool.sks-keyservers.net
  3. gpgkeys: key 732796B4 not found on keyserver
  4. gpg: no valid OpenPGP data found.
  5. gpg: Total number processed: 0
  6. gpg: keyserver communications error: key not found
  7. gpg: keyserver communications error: bad public key
  8. gpg: keyserver receive failed: bad public key

这里很无耻的失败了,看错误提示是没有找到资料,但是提交时没有报错。反复几次也是如此,最后灵机一动,是不是要翻墙?

  1. hp gpg --keyserver hkp://pool.sks-keyservers.net --send-keys 732796B4
  2. gpg: sending key 732796B4 to hkp server pool.sks-keyservers.net
  3. hp gpg --keyserver hkp://pool.sks-keyservers.net --recv-keys 732796B4
  4. gpg: requesting key 732796B4 from hkp server pool.sks-keyservers.net
  5. gpg: key 732796B4: "Sky Ao (aoxiaojian) <aoxiaojian@gmail.com>" not changed
  6. gpg: Total number processed: 1
  7. gpg: unchanged: 1

这次终于对了,走http proxy就可以发布成功,验证也通过了。

修改maven设置

修改maven的全局配置文件settings.xml,增加下面的内容,用户名密码为Sonatype上面注册的用户名和密码:

  1. <servers>
  2. <server>
  3. <id>oss</id>
  4. <username>skyao</username>
  5. <password><![CDATA[ao$$$$$]]></password>
  6. </server>
  7. </servers>

然后修改项目的pom.xml文件,加入需要的信息:

  1. <name>Dreamfly Dependencies</name>
  2. <description>Dependency definitions for all dreamfly projects</description>
  3. <url>https://github.com/dreamfly-io/dreamfly-dependencies/</url>
  4. <organization>
  5. <name>Dreamfly</name>
  6. <url>http://dreamfly.io</url>
  7. </organization>
  8. <licenses>
  9. <license>
  10. <name>Apache License, Version 2.0</name>
  11. <url>http://www.apache.org/licenses/LICENSE-2.0</url>
  12. </license>
  13. </licenses>
  14. <developers>
  15. <developer>
  16. <name>Sky Ao</name>
  17. <email>aoxiaojian@gmail.com</email>
  18. </developer>
  19. </developers>
  20. <scm>
  21. <connection>scm:git:git@github.com:dreamfly-io/dreamfly-dependencies.git</connection>
  22. <developerConnection>scm:git:git@github.com:dreamfly-io/dreamfly-dependencies.git</developerConnection>
  23. <url>git@github.com:dreamfly-io/dreamfly-dependencies.git</url>
  24. </scm>

再增加一个profile,名为oss

  1. <profiles>
  2. <profile>
  3. <id>oss</id>
  4. <build>
  5. <plugins>
  6. <!-- Source -->
  7. <plugin>
  8. <groupId>org.apache.maven.plugins</groupId>
  9. <artifactId>maven-source-plugin</artifactId>
  10. <version>${maven-source-plugin.version}</version>
  11. <executions>
  12. <execution>
  13. <phase>package</phase>
  14. <goals>
  15. <goal>jar-no-fork</goal>
  16. </goals>
  17. </execution>
  18. </executions>
  19. </plugin>
  20. <!-- Javadoc -->
  21. <plugin>
  22. <groupId>org.apache.maven.plugins</groupId>
  23. <artifactId>maven-javadoc-plugin</artifactId>
  24. <version>${maven-javadoc-plugin.version}</version>
  25. <executions>
  26. <execution>
  27. <phase>package</phase>
  28. <goals>
  29. <goal>jar</goal>
  30. </goals>
  31. </execution>
  32. </executions>
  33. </plugin>
  34. <!-- GPG -->
  35. <plugin>
  36. <groupId>org.apache.maven.plugins</groupId>
  37. <artifactId>maven-gpg-plugin</artifactId>
  38. <version>${maven-gpg-plugin.version}</version>
  39. <executions>
  40. <execution>
  41. <phase>verify</phase>
  42. <goals>
  43. <goal>sign</goal>
  44. </goals>
  45. </execution>
  46. </executions>
  47. </plugin>
  48. </plugins>
  49. </build>
  50. <distributionManagement>
  51. <snapshotRepository>
  52. <id>oss</id>
  53. <url>https://oss.sonatype.org/content/repositories/snapshots/</url>
  54. </snapshotRepository>
  55. <repository>
  56. <id>oss</id>
  57. <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
  58. </repository>
  59. </distributionManagement>
  60. </profile>
  61. </profiles>

特别注意:snapshotRepository 与 repository 中的 id 一定要与 setting.xml 中 server 的 id 保持一致。这里我们都设置为oss。

上传构件到OSS

执行下面maven发布命令,注意指定profile为pom.xml里面对应的oss

  1. mvn clean deploy -P oss
  2. mvn clean deploy -P oss -Darguments="gpg.passphrase=密钥密码"

mvn命令执行中,在每个构件上传时,都会要求输入密码,这个密码就是前面gpg加密用的密码:

  1. Enter passphrase: gpg: gpg-agent is not available in this session

看到一下提示信息,说明deploy成功:

  1. Uploading: https://oss.sonatype.org/content/repositories/snapshots/io/openfoundation/dependencies/foundation-dependencies-standard/0.1.0-SNAPSHOT/maven-metadata.xml
  2. Uploaded: https://oss.sonatype.org/content/repositories/snapshots/io/openfoundation/dependencies/foundation-dependencies-standard/0.1.0-SNAPSHOT/maven-metadata.xml (816 B at 0.6 KB/sec)

此时构件已经部署在oss仓库中,但还不是中央仓库。

发布

在下里面地址登录,用户名和密码就是在sonatype注册的:

https://oss.sonatype.org/

在Staging Repositories找到自己的仓库,可以用模糊搜索。

备注:切记是要发布release版本的构件,不能是snapshot,不然不会出现在Staging Repositories里面。

状态为 Open,需要勾选然后点击 Close 按钮。当系统自动验证完成后,状态会变为 Closed。最后,点击 Release 按钮来发布。

第一次发布时,需要回到issue页面回复。然后等待审批。

验证中央仓库

同样上述步骤完成10分钟之后就可以同步到maven中央仓库,可以通过直接浏览仓库的方式做验证,比如访问下列地址:

http://repo1.maven.org/maven2/io/openfoundation/

gpg错误处理

mvn命令执行中,在每个构件上传时,都会要求输入密码,注意错误信息:

  1. Enter passphrase: gpg: gpg-agent is not available in this session

但是在命令行中已经有gpg-agent命令了。gogole之后发现是版本问题:

https://askubuntu.com/questions/860370/gpg-agent-cant-be-reached

首先安装gpg2:

  1. sudo apt install gpgv2

然后在maven的settings.xml中加入两个属性,主要要在激活的profile里面:

  1. <profile>
  2. <properties>
  3. <gpg.executable>gpg2</gpg.executable>
  4. <gpg.useagent>true</gpg.useagent>
  5. </properties>
  6. </profile>

再次执行mvn命令:

  1. mvn clean deploy -P oss

这是就换成gpg2了,但是依然不能直接免密码输入,还是会有一个弹窗要求输入密码,不过总算可以选择保存密码了。参考下文:

TBD:还是需要找到更好的办法。

参考资料

参考:https://www.dexcoder.com/selfly/article/4352