前言
最近考虑将自己的开源项目发布到Maven的中央仓库,中央仓库地址,在网上搜了一把资料,看了其他人总结的文章,有些做的不错,但自己实践起来还是遇到些问题,比如使用gpg生成私钥时会出现一些兼容上的问题,经过一番研究,最终问题还是能解决掉的,这里先做个基本知识的整理:
- 什么是OSSRH(OSS Repository Hosting),官方资料 --> https://central.sonatype.org/pages/ossrh-guide.html
- 什么是GPG(The GNU Privacy Guard),是一种加密软件,它是PGP加密软件的满足GPL的替代物。GnuPG依照由IETF订定的OpenPGP技术标准设计[2]。GnuPG用于加密、数字签名及产生非对称钥匙对的软件。(资料)。Sonatype会要求任何一方在deploy时,进行信息验证,做安全验证那么就需要一个可信任的中间机构,所以他会要求你使用gpg的工具生成私钥和公钥,并将公钥传送到这个公钥托管机构中(目前有三个大的公钥托管机构,后面会讲到),然后在你deploy所有的内容之后,开始做验证;
- groupId的重要性,当在sonatype提交ticket之后,那边的管理员都会询问:“Do you own the domain eventcenter.io? If not, please read: http://central.sonatype.org/pages/choosing-your-coordinates.html You may also choose a groupId that reflects your project hosting, in this case, something like io.github.usiboy or com.github.usiboy”。如果你的代码托管在oschina或者github,并且没有独立的域名,那么就按照这个io.github.usiboy或者com.github.usiboy格式定义,如果有独立的域名,请设置域名作为groupId。域名建议和软件的内容保持一致,对于开源的项目,尽可能的选用org,io,com这样的域名,对于国内cn的域名不要去使用。
发布前的准备
我使用的环境是Mac,JDK使用的是1.8,Maven的版本是3.3。
代码需要发布到托管中心,例如码云或者Github中等等,Maven的pom的scm后面设置需要用到。
在电脑中安装gpg工具,windows下请到www.gnupg.org 这里下载安装,Mac机器可以使用brew install gpg
进行安装。
到https://issues.sonatype.org/ 注册一个账号,已经注册的可以忽略,sonatype的账号中的email, username和password需要牢记,后面的操作中需要使用到。
操作步骤
在Sonatype Issues中创建Ticket
首次在sonatype中发布时,需要在issues系统中申请一个ticket。申请地址如下: https://issues.sonatype.org/secure/CreateIssue.jspa?issuetype=21&pid=10134 加*的是必填的,需要使用英文进行填写,英语不好的没关系,可以使用Google、有道翻译啊,翻译之后,稍微修改下,就能用了。可以参考如下示例: https://issues.sonatype.org/browse/OSSRH-41598?focusedCommentId=501310&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-501310 注意:
- sonatype比较关注groupId,提交ticket之后,审核人员首要问的就是groupId,如果自己有域名的,可以回答他这是你自己的域名,这里也不一定要给他看凭证。如果这个groupId随意定的,项目后期维护会比较麻烦,建议没有域名,还是尽可能的按照他的规范来定义。
- SCM url是指源码的存放地址
- usernames 是指sonatype中的用户,如果有多人参与,则填写其他人的sonatype的username进来,使用','逗号分开,如果只有自己,那么就写自己的username
审核一般都比较快,sonatype在中国也有分公司的,我这个ticket从open到resolve总共耗时也不超过1天。通过之后,Ticket状态变为Resolve,同时,管理员会要求你尽快deploy,并在deploy成功之后回复这个Ticket。
使用gpg生成秘钥
这里为什么需要使用gpg生成秘钥?我们不是有了sonatype的账号和密码了吗?
这个还完全不够,Sonatype的仓库服务每天要处理很多deploy的操作,除了基本的账号校验,还需要使用更为安全的验证方式,通过gpg可以生成RSA的非对称加密,并且需要你将公钥发布到秘钥托管服务中,他们要经过这两层的校验,具体可以参考:https://central.sonatype.org/pages/working-with-pgp-signatures.html
接下来我们开始生成RSA秘钥
# 我机器上使用的是brew安装的,版本号为2.2.9,这个版本比较新,还不能直接使用gpg --gen-key,生成的格式和sonatype所要求的会有所出入,所以直接使用下面的指令进行生成
gpg --full-gen-key
gpg (GnuPG) 2.2.9; Copyright (C) 2018 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.
请选择您要使用的密钥种类:
(1) RSA and RSA (default)
(2) DSA and Elgamal
(3) DSA (仅用于签名)
(4) RSA (仅用于签名)
您的选择? 1
RSA 密钥长度应在 1024 位与 4096 位之间。
您想要用多大的密钥尺寸?(2048)
# 直接回车
您所要求的密钥尺寸是 2048 位
请设定这把密钥的有效期限。
0 = 密钥永不过期
= 密钥在 n 天后过期
w = 密钥在 n 周后过期
m = 密钥在 n 月后过期
y = 密钥在 n 年后过期
密钥的有效期限是?(0) 0
# 为了简单,这个秘钥直接设置为永不过期,但是出于安全来看,最好还是设置一个有效期
密钥永远不会过期
以上正确吗?(y/n)y
You need a user ID to identify your key; the software constructs the user ID
from the Real Name, Comment and Email Address in this form:
"Heinrich Heine (Der Dichter) "
# 这里填写的是sonatype的账号名字
真实姓名:jueming
# 这里填写的是sonatype的注册邮箱
电子邮件地址:[email protected]
注释:xxxx
您选定了这个用户标识:
“jueming (xxxx) ”
更改姓名(N)、注释(C)、电子邮件地址(E)或确定(O)/退出(Q)?O
我们需要生成大量的随机字节。这个时候您可以多做些琐事(像是敲打键盘、移动
鼠标、读写硬盘之类的),这会让随机数字发生器有更好的机会获得足够的熵数。
# 我在MAC上生成时,不需要敲那么多,它直接就过去了
# 这个密码是给公钥加密的密码,切记,一定要记住,如果你想简单点,那就和sonatype的登录密码一样
请输入密码:*********
# 注意这个33F38C0F7F755D60,这个一定要保存下来,发布key时需要用到,以及在后面做deploy时,需要Maven的settings中进行设置
gpg: 密钥 33F38C0F7F755D60 被标记为绝对信任
gpg: revocation certificate stored as '~/.gnupg/openpgp-revocs.d/407618CE258C725171487B6233F38C0F7F755D60.rev'
公钥和私钥已经生成并经签名。
pub rsa2048 2018-08-02 [SC]
407618CE258C725171487B6233F38C0F7F755D60
uid jueming (xxxx)
sub rsa2048 2018-08-02 [E]
看到这个信息,恭喜你成功的生成秘钥了
使用gpg 2.9的版本的问题
我这边遇到了一个这样的问题:gpg: signing failed: Inappropriate ioctl for device
由于高版本gpg的目录下的结构和老版本有些不同,在执行mvn的gpg插件时会出现这个问题,google了一把,终于找到解决方案了。
在~/.gnupg目录下增加两个文件 gpg-agent.conf,添加如下内容:
allow-loopback-pinentry
gpg.conf,添加如下内容:
use-agent
pinentry-mode loopback
之后再运行就没报这个错误了,也希望未来maven的gpg的插件也能够跟着升级下,避免出现这个错误,这里可以在issues.sonatype.org中给他们提BUG。
发布公钥到托管服务
gpg使用了RSA加密方式,所以需要将公钥send到秘钥托管服务中,为了提高deploy的成功率,建议一次提交到三个秘钥托管服务中,sonatype会分别去查找三个托管服务,如果都找不到则会报错
gpg --keyserver hkp://pool.sks-keyservers.net --send-keys 33F38C0F7F755D60
gpg --keyserver hkp://keyserver.ubuntu.com --send-keys 33F38C0F7F755D60
gpg --keyserver hkp://pgp.mit.edu --send-keys 33F38C0F7F755D60
send完成之后,可以通过--recv-keys查询服务是否有秘钥
gpg --keyserver hkp://pool.sks-keyservers.net --recv-keys 33F38C0F7F755D60
gpg: 密钥 33F38C0F7F755D60:“jueming (xxxx) ”未改变
gpg: 合计被处理的数量:1
gpg: 未改变:1
配置pom.xml
这里主要说下比较关键的一些信息
http://eventcenter.io
Jue Ming
http://eventcenter.io
MIT License
http://www.opensource.org/licenses/mit-license.php
repo
Jue Ming
[email protected]
scm:git:[email protected]:usiboy/event-center.git
scm:git:[email protected]:usiboy/event-center.git
https://github.com/usiboy/event-center
utf-8
UTF-8
3.0.1
2.10.4
1.6
oss
maven-deploy-plugin
true
org.apache.maven.plugins
maven-source-plugin
${version.maven-source-plugin}
package
jar-no-fork
org.apache.maven.plugins
maven-javadoc-plugin
${version.maven-javadoc-plugin}
-Xdoclint:none
org.apache.maven.plugins
maven-gpg-plugin
${version.maven-gpg-plugin}
sign-artifacts
verify
sign
org.sonatype.plugins
nexus-staging-maven-plugin
1.6
true
oss
https://oss.sonatype.org/
deploy-to-sonatype
deploy
deploy
release
oss
https://oss.sonatype.org/content/repositories/snapshots/
oss
https://oss.sonatype.org/service/local/staging/deploy/maven2/
设置settings.xml
已经到设置的最后一步了,马上就要成功了,注意settings.xml可以和你现在正在使用的settings.xml分为两个文件管理,比如在~/.m2/目录下再开辟一个目录然后在这里更新:sonatype/settings.xml。
mvn 使用--settings sonatype/settings.xml指令,可以指定具体的配置文件进行操作。
以下是settings.xml的部分内容:
oss
jueming
oss
~/.gnupg
36CB9C06A5883FF4
oss
deploy项目
前面都设置完成之后,可以开始运行如下命令:
mvn clean deploy -Poss --settings sonatype/settings.xml
如果你是直接修改~/.m2/settings.xml的文件:
mvn clean deploy -Poss
需要等待一段时间,首先要经过编译、打包,然后开始加密,有上传文件的过程,全部上传完之后,需要等待服务端的验证响应,这个过程一般比较耗时,需要耐心等待2-5分钟。
一切顺利的话,在控制台中会告诉你发布成功啦。
但是到这里还没完,还需要做几步操作即可。
回复Resolved的Ticket
之前Ticket申请成功之后,管理员还会要求你deploy成功之后,还需要回复下:如下图所示 他们一般会很快回复你的,并告诉你这个库已经激活,你可以随时将staging中的repository发布上线。
之所以有这个阶段,也是为了让你在本地引用这个临时的库,用于测试下deploy的jar是否都是有效的。
Release staging repository
登录https://oss.sonatype.org 按照如上箭头点击,找到自己的repository(不知道这里为什么别人的repository也能看到,但是你点击别人的release又不能发布)。前面我们使用mvn deploy的时候,他会返回一个staging id,截图中是我之前deploy失败的id,失败的是不能release。只有成功deploy的才能Release,所以找到成功发布那个id,点击它之后,工具栏中的Release按钮会被激活,于是,点击Release,没过多久,他就会告诉你成功发布啦。