如何将开源项目发布到Maven中央仓库

前言

最近考虑将自己的开源项目发布到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>  = 密钥在 n 天后过期
      <n>w = 密钥在 n 周后过期
      <n>m = 密钥在 n 月后过期
      <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) <heinrichh@duesseldorf.de>"
# 这里填写的是sonatype的账号名字
真实姓名:jueming
# 这里填写的是sonatype的注册邮箱
电子邮件地址:usiboy@163.com
注释:xxxx
您选定了这个用户标识:
    “jueming (xxxx) <usiboy@163.com>”

更改姓名(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) <usiboy@163.com>
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) <usiboy@163.com>”未改变
gpg: 合计被处理的数量:1
gpg:           未改变:1

配置pom.xml

这里主要说下比较关键的一些信息

<!-- 项目主页,如果没有,请直接使用代码托管的地址 -->
<url>http://eventcenter.io</url>

	<!-- 组织信息 -->
	<organization>
		<name>Jue Ming</name>
		<url>http://eventcenter.io</url>
	</organization>
	
	<!-- 开源许可证,不知道如何选择,请参考https://github.com/qyxxjd/License -->
	<licenses>
		<license>
			<name>MIT License</name>
			<url>http://www.opensource.org/licenses/mit-license.php</url>
			<distribution>repo</distribution>
		</license>
	</licenses>

	<!-- 开发者信息 -->
	<developers>
		<developer>
			<name>Jue Ming</name>
			<email>usiboy@163.com</email>
		</developer>
	</developers>

	<!-- 开源地址 -->
	<scm>
		<connection>scm:git:git@github.com:usiboy/event-center.git</connection>
		<developerConnection>scm:git:git@github.com:usiboy/event-center.git</developerConnection>
		<url>https://github.com/usiboy/event-center</url>
	</scm>
	
	<properties>
		<project.build.sourceEncoding>utf-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<!-- ...... 这里我省略了一些properties,下面几个是后面配置plugins需要使用到 -->
		<version.maven-source-plugin>3.0.1</version.maven-source-plugin>
		<version.maven-javadoc-plugin>2.10.4</version.maven-javadoc-plugin>
		<version.maven-gpg-plugin>1.6</version.maven-gpg-plugin>
	</properties>
	
	<!-- ..... 中间省略掉一些配置,我们直接跳到profile的设置中 ...... -->
	<profiles>
		<profile>
			<id>oss</id>
			<build>
				<plugins>
					<plugin>
						<artifactId>maven-deploy-plugin</artifactId>
						<configuration>
							<skip>true</skip>
						</configuration>
					</plugin>
					<!-- Source -->
					<plugin>
						<groupId>org.apache.maven.plugins</groupId>
						<artifactId>maven-source-plugin</artifactId>
						<version>${version.maven-source-plugin}</version>
						<executions>
							<execution>
								<phase>package</phase>
								<goals>
									<goal>jar-no-fork</goal>
								</goals>
							</execution>
						</executions>
					</plugin>
					<!-- Javadoc -->
					<plugin>
						<groupId>org.apache.maven.plugins</groupId>
						<artifactId>maven-javadoc-plugin</artifactId>
						<version>${version.maven-javadoc-plugin}</version>
						<configuration>
							<!-- 这个配置看情况加,因为我的电脑上使用的是JDK1.8,我这个库需要使用1.6编译,不加这个,对于javadoc的编译会存在问题 -->
							<additionalparam>-Xdoclint:none</additionalparam>
						</configuration>
					</plugin>
					<!-- GPG -->
					<plugin>
						<groupId>org.apache.maven.plugins</groupId>
						<artifactId>maven-gpg-plugin</artifactId>
						<version>${version.maven-gpg-plugin}</version>
						<executions>
							<execution>
								<id>sign-artifacts</id>
								<phase>verify</phase>
								<goals>
									<goal>sign</goal>
								</goals>
							</execution>
						</executions>
					</plugin>
					<plugin>
						<groupId>org.sonatype.plugins</groupId>
						<artifactId>nexus-staging-maven-plugin</artifactId>
						<version>1.6</version>
						<extensions>true</extensions>
						<configuration>
							<!-- 这个id不要乱设置,需要和后面的settings.xml中的server的id保持一致 -->
							<serverId>oss</serverId>
							<nexusUrl>https://oss.sonatype.org/</nexusUrl>
						</configuration>
						<executions>
							<execution>
								<id>deploy-to-sonatype</id>
								<phase>deploy</phase>
								<goals>
									<goal>deploy</goal>
									<goal>release</goal>
								</goals>
							</execution>
						</executions>
					</plugin>
				</plugins>
			</build>
			<distributionManagement>
				<snapshotRepository>
					<id>oss</id>
					<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
				</snapshotRepository>
				<repository>
					<id>oss</id>
					<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
				</repository>
			</distributionManagement>
		</profile>
	</profiles>

设置settings.xml

已经到设置的最后一步了,马上就要成功了,注意settings.xml可以和你现在正在使用的settings.xml分为两个文件管理,比如在~/.m2/目录下再开辟一个目录然后在这里更新:sonatype/settings.xml。

mvn 使用--settings sonatype/settings.xml指令,可以指定具体的配置文件进行操作。

以下是settings.xml的部分内容:

	<servers>
		<server>
		<!-- 这个id不要乱设置,需要和前面的pom.xml中的sonatype的插件中的serverId保持一致 -->
        <id>oss</id>
		<!-- 这个是sonatype中注册的username -->
        <username>jueming</username>
		<!-- 这个是sonatype中的登录密码 -->
        <password><![CDATA[***********]]></password>
    </server>
	</servers>
	
	<profiles>
		<profile>
      		<id>oss</id> 
      		<properties>
				<!-- 前面pom.xml中配置了gpg的maven插件,最好使用最新版本1.6,这样只需要在settings.xml中配置properties,这个目录就是你本地机器存放gpg秘钥的目录 -->
        		<gpg.homedir>~/.gnupg</gpg.homedir>
				<!-- 这个就是前面我强调需要记录下的key -->
				<gpg.keyname>36CB9C06A5883FF4</gpg.keyname>
				<!-- 公钥的加密密码 -->
				<gpg.passphrase><![CDATA[*********]]></gpg.passphrase>
			</properties>
    	</profile>
	</profiles>
	
	<activeProfiles>
    <activeProfile>oss</activeProfile>
  </activeProfiles>

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,没过多久,他就会告诉你成功发布啦。

然后再过个大概10分钟,你到中央仓库搜索一把,你的库都出来了,大功告成!

转载于:https://my.oschina.net/u/861925/blog/1921733

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值