记一次上传开源构件到maven中央仓库的辛酸历程

    技术2022-07-12  74

    概要

    这段时间我在负责公司的一个开源项目,需要将该项目的jar包上传到maven中央仓库,以供客户二次开发的依赖引用。由于第一次涉及这块的知识内容,所以耗费了整整两天的时间,因此本文做一次总结,亦或给他人提供点学习资料。

    废话不多说,直接上干货。

     

    目录

    概要

    一、本地环境

    二、环境准备

    1、准备SonaType 账户

    2、准备开源项目

    3、安装PGP

    三、创建Issues

    1、登录SonaType

    2、创建Issues

    3、等待审核

    四 发布构件

    1、Maven配置Settings

    2、开源项目配置pom

    3、构建

    4、发布

    五 附录

    六 资料


    一、本地环境

    Windows10 Gpg3.1.1 IDEA 2018.2.5 x64 Maven 3.6.0 JDK 8

     

    二、环境准备

    1、准备SonaType 账户

    如果已有账户,请跳过,如果没有,请进入SonaType注册页面注册账户。这个账户很重要,贯穿上传构件到maven中央仓库的整个流程。

    在注册时,一定要记住邮箱(Email)、用户名(Username)和密码(Password),后面很多地方都用的到。注册成功后,使用注册的用户名(Username)和密码(Password)登录。

    注册成功后,使用注册的用户名(Username)和密码(Password)登录,选择语言 →点击“浏览当前项目”就会跳转到首页,首页左侧显示仪表盘,右侧显示当前所有项目的活动日志。

     

    2、准备开源项目

    由于上传构件到maven中央仓库,是需要其源码开源的,因此需要提前处理好开源仓库地址。这个条件必不可少,后面会用到。至于如何将项目开源可自行百度,后期如果有时间我补一篇文章吧。

     

    3、安装PGP

    为了防止构件被他人篡改,上传到maven中央仓库的构件需要被GPG/PGP签名。

    下载

    尽量下载最新版本的Gpg4win,容易出现各种问题,我就被坑了,我下载的是gpg4win-vanilla-2.3.4.exe,deploy的时候出现各种问题,折腾的都要疯了。进入Gpg4win下载页面,找到并点击 GNUPG BINARY RELEASES 部分windows版本的Gpg4win。

     

    点击 Gpg4win 后进入选择下载版本页面。

    点击当前版本即可,进入下载页,有钱的就捐献,没钱的以后再说。

    安装

    安装这块很简单,按照提示一步步来即可。安装完成后,打开DOS窗口,输入gpg --version命令,验证gpg是否安装成功。

    gpg --version

    执行上述命令后,如果出现以下信息说明gpg安装成功。

    生成密钥对

    新版本的gpg4win可以使用完整版gps --full-gen-key 命令或者简洁版gps --gen-key 命令生成的密钥对,建议使用完整版命令,因为可以看到更多的密钥信息。

    gpg --full-gen-key

    执行上述命令后,依据提示依次输入相关信息。

    2号表示加密算法,输入默认1即可。

    3号表示密钥长度,输入默认2048即可

    4号表示密钥有效期,输入默认0即可,表示永不过期

    5号是对4号操作的确认,输入y即可

    6号表示需要输入真实的名字

    7号表示需要输入邮箱

    8号表示对以上信息进行确认,输入o表示ok

    9号是在8号输入o弹出的一个对话框,需要填写passphrase值,该值是密钥很重要,需要记住,后面deploy鉴权的时候需要用到。

     

    最后的打印输出:

    gpg: /c/Users/Administrator/.gnupg/trustdb.gpg: trustdb created gpg: key XXXXXX1 marked as ultimately trusted public and secret key created and signed. gpg: checking the trustdb gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u pub 2048R/XXXXXX2 2020-06-29  Key fingerprint = XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX uid your-real-name<your-email> sub 2048R/XXXXXX 2020-06-29

    上面输出中第二行的XXXXXX1与第六行的XXXXXX2有时显示的值不一样,但是代表的是同一个key,XXXXXX1XXXXXX2的子字符串(XXXXXX1截取了XXXXXX2末尾部分)。

    当填写完后,密钥对就创建成功,在命令行输入 gpg --list-keys 即可查看创建的密钥对。

     

    发布公钥

    当我们向仓库deploy构件的时候,仓库会用服务器上的公钥验证上传的构件,因此我们要将上面生成的公钥传到服务器上,供验证获取。公钥服务器有以下几个:

    http://pgp.mit.edu:11371 http://keyserver.ubuntu.com:11371 http://pool.sks-keyservers.net:11371

    上传公钥时,一定要带上公钥服务器的端口号,我就是被这块坑了,切记切记。

    执行以下命令:

    gpg --keyserver hkp://pool.sks-keyservers.net:11371 --send-keys 公钥 gpg --keyserver hkp://pool.sks-keyservers.net:11371 --recv-keys 公钥

    或执行命令

    gpg --keyserver hkp://pgp.mit.edu:11371 --send-keys 公钥 gpg --keyserver hkp://pgp.mit.edu:11371 --recv-keys 公钥

    或执行命令:

    gpg --keyserver hkp://keyserver.ubuntu.com:11371 --send-keys 公钥 gpg --keyserver hkp://keyserver.ubuntu.com:11371 --recv-keys 公钥

    出现以下信息表示公钥发送成功。

     

    三、创建Issues

    1、登录SonaType

    如果是第一次登录SonaType,进入页面时有个使用指引,选择“语言”→点击“浏览当前项目”就会跳转到首页。非第一次登录SonaType,会直接进入主页。SonaType首页左侧显示仪表盘,右侧显示当前所有项目的活动日志。

     

    2、创建Issues

    点击首页上方新建(对应的英文是Create)按钮,进入“创建问题”(Create Issue)界面。

    说明:

    项目(Project),选择Community Support - Open Source Project Repository Hosting (OSSRH)。

    问题类型(Issue Type),选择 New Project。

    概要(Summary),填写开源项目名称,就是要上传构件的那个项目。

    描述(Description),填写开源项目描述,就是要上传构件的那个项目的项目描述。

    附件(Attachment),默认即可。

    Group Id,填写要上传构件的开源项目的pom文件中的项目Group Id(创建maven项目时填写的那个),注意开源项目的Group Id不能随便写,官网有要求。

    大体意思:groupId是从所有项目中区分自己项目的唯一标识,与Java包的命名约定类似,它以反向方式重用域名系统。也就是说,如果你是域名的所有者或维护者,你就可以使用反向域名开头+自定义部分命名groupId。

    如果该开源项目的构件已经上传过中央仓库,你可以使用之前上传的groupId。确定groupId粒度的一个好方法是使用项目结构。也就是说,如果当前项目是一个多模块项目,它应该父项目的groupId后面追加一个新的标识符

    域名

    groupId

    备注

    www.springframework.org

    org.springframework.www

     

    org.springframework.xxx

    xxx是自定义的名字

     

     

    项目开源地址

    groupId

    备注

    github.com/yourusername

    io.github.yourusername

    yourusername是对应平台上你创建的账户名

    gitee.com/yourusername

    com.gitee.yourusername

    父项目groupId

    子模块groupId

    备注

    org.apache.maven

    org.apache.maven.plugins

    plugins子模块

    org.apache.maven.reporting

    reporting子模块

     

     

     

    artifactId是项目本身的名称可以选择任何想要的名称小写字母和其他非特殊符号构成。对于较长的名称,可以使用破折号分隔如xxx-xxxxxx-xxxx

    Project URL,填写项目的开源网址地址,https://github.com/账户名/项目名

    SCM url,源码的版本控制地址,https://github.com/账户名/项目名.git

    Username(s),填写希望上传构件到该groupId的用户列表,用逗号分隔。

    Already Synced to Central,存储库是否已经同步到中央仓库?按实际选择,工作人员需要知道是否关闭现有的同步

    当以上信息填写完毕,点击下方的创建(Create)按钮,即完成问题的创建,等待工作人员审核。

     

    3、等待审核

    点击首页的问题(Issues)按钮,在下拉菜单中的“最近的问题”选项卡可以找到刚刚新建的问题,点击该问题即可查看详情。

    问题创建后,工作人员很快就会审核(几分钟),如果填写的信息没有问题,状态由“开放”变为“已解决”,相应的解决结果由“未解决”变为“已修复”。如果填写的信息有问题,工作人员会在下面留言(评论),告知哪些信息有问题,可以根据提示进行修改。

    比如我填写的信息中groupId(cn.iot.xxx.xxx)写错了,因为我没有域名(iot.cn),所以我把groupId改成了com.gitee.我的gitee账户名,改完后在评论区留言告知对方。

     

    当信息都符合要求,审核就会通过,工作人员会继续留言,让你在gitee平台上你的账户下创建一个公共仓库,验证groupId中的gitee账户是你的gitee账户,留言中公共仓库的地址已经给出,你按照要就创建即可,创建完成后留言告知工作人员即可。

    工作人员通过上面创建的公共仓库,验证了你的gitee账户后,会留言告知你groupId已经准备好了,你可以进行你的操作了。特别留意最后一句话:当你成功发布第一个release版本时,记得留言告知工作人员。

     

    四 发布构件

    1、Maven配置Settings

    在maven的settings配置文件中添加一个server,id可以自定义,该id在后面会用到,用户名是Sonatype的用户名,密码是Sonatype的密码。

    <servers> <server> <id>oss</id> <username>SonaType的用户名</username> <password>SonaType的密码</password> </server> </servers>

    2、开源项目配置pom

    上传构件到中央仓库时,除了构件本身,还需要上传一些规定的必要信息。

    开发者信息 <!--开发者信息 --> <developers> <developer> <name>开发者名</name> <email>开发者邮箱</email> </developer> </developers> 开源许可协议 <!-- 开源许可协议 --> <licenses> <license> <name>开源协议名称</name> <url>开源协议正文页面地址</url> <distribution>项目发布方式:repo</distribution> </license> </licenses> 源码控制信息 <!-- 源码控制信息--> <scm> <connection>scm:git:git@gitee.com:账户名/开源项目名.git</connection> <developerConnection>scm:git:git@gitee.com:账户名/开源项目名.git</developerConnection> <url>git@gitee.com:账户名/开源项目名.git</url> </scm> 构件上传地址 <!--定义snapshots库和releases库的nexus地址--> <distributionManagement> <snapshotRepository> <!--oss需要对应到settings.xml下的server的id--> <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> 源码构建插件 <!-- 源码构建插件 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <version>3.0.1</version> <executions> <execution> <id>attach-sources</id> <goals> <goal>jar-no-fork</goal> </goals> </execution> </executions> </plugin> 文档生成插件 <!--javadoc插件--> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-javadoc-plugin</artifactId> <version>2.9.1</version> <executions> <execution> <id>attach-javadocs</id> <!--<phase>install</phase>--> <goals> <goal>jar</goal> </goals> <configuration> <!--<failOnError>false</failOnError>--> <!--<doclint>none</doclint>--> <encoding>UTF-8</encoding> <charset>UTF-8</charset> <additionalparam>-Xdoclint:none</additionalparam> </configuration> </execution> </executions> </plugin> 加密构建插件 <!--gpg加密插件--> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-gpg-plugin</artifactId> <version>1.6</version> <executions> <execution> <id>sign-artifacts</id> <phase>verify</phase> <goals> <goal>sign</goal> </goals> </execution> </executions> </plugin>

    完整的pom文件内容详见文章末尾。

     

    3、构建

    执行构建命令构建,命令:

    mvn clean deploy -P release

    在构建过程中,会弹出对话框,要求输入Passphrase值,就是在生成密钥对时要求输入的那个值。

    输入passphrase值后,构件构建成功,且上传成功。

     

    4、发布

    查看构件

    登录OSS系统,用户名是注册Sonatype的用户名,密码是注册Sonatype的密码。

    登录成功后,点击下图中的,就可以看到右侧(如)上传的构件,选中该构件,点击下方的Content(如),逐层打开,就可以看到目录结构(如)。此时构件的状态为open,表示只是将构件上传上来,并没有进行校验发布。

    执行进行校验。

    等待几分钟(有的构件比较大,保证系统处理完成),刷新页面,点击close左侧的(Refresh)按钮(一定要先刷新页面,再点击Refresh),如果验证成功,处状态变为closed。如果状态还是open,则可点击(Activity)事件查看失败的原因,根据原因解决问题,然后重新执行构建命令,再校验。可以看到下图校验成功,可点击(Release)进行发布,(Drop)是删除上传的构建,在校验前后(Close)、发布前后(Release)都可以执行。

    执行(Release)

    等待几分钟(有的构件比较大,保证系统处理完成),刷新页面,点击close左侧的Refresh按钮,点击下方的Activity事件查看执行结果,没有报错说明发布成功!

    通知工作人员同步构件到仓库

    是否还记得创建问题后,工作人员审核通过(上面3部分)的最后,“当你成功发布第一个release版本时,记得留言告知工作人员”,所以返回SonaType,继续评论即可。

    留言后,很快工作人员就会回复你:中央仓库已经激活对某某构件的同步,大约10分钟就可以了,但是2个小时左右才能在仓库中真正搜索到,因为仓库更新周期就是2小时。

    过了一段时间以后,进入maven中央仓库,输入构件名称,点击查询。

    即可查到上传的构件。

    五 附录

    完整的pom文件示例

    <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>你的groupId</groupId> <artifactId>你的构件名</artifactId> <version>版本</version> <packaging>打包方式jar或者war</packaging> <description>构件描述</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.5.RELEASE</version> <relativePath/> </parent> <properties> <java.version>1.8</java.version> </properties> <dependencies> <!--spring boot依赖--> <dependency> ... </dependency> </dependencies> <!-- 开发者信息 --> <developers> <developer> <name>开发者名</name> <email>开发者邮箱</email> </developer> </developers> <!-- 开源许可协议 --> <licenses> <license> <name>GNU Lesser General Public License Version 3</name> <url>http://www.gnu.org/licenses/lgpl.txt</url> <distribution>repo</distribution> </license> </licenses> <!-- 源码控制信息 --> <scm> <connection>scm:git:git@gitee.com:cmcc-iot-api/iot-card-open-core.git</connection> <developerConnection>scm:git:git@gitee.com:cmcc-iot-api/iot-card-open-core.git</developerConnection> <url>git@gitee.com:cmcc-iot-api/iot-card-open-core.git</url> </scm> <!--定义snapshots库和releases库的nexus地址--> <distributionManagement> <snapshotRepository> <!--oss需要对应到settings.xml下的server的id--> <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> <build> <finalName>${project.artifactId}</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>${java.version}</source> <target>${java.version}</target> </configuration> </plugin> </plugins> <resources> <resource> <directory>src/main/webapp</directory> <filtering>false</filtering> </resource> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> </resource> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> </resources> </build> <profiles> <profile> <!-- 本地开发环境--> <id>dev</id> <properties> <profiles.active>dev</profiles.active> </properties> <activation> <!-- 设置默认激活这个配置--> <activeByDefault>true</activeByDefault> </activation> </profile> <profile> <!--打包环境--> <id>release</id> <properties> <profiles.active>release</profiles.active> </properties> <build> <plugins> <!--生产源码文件插件--> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <version>3.0.1</version> <executions> <execution> <id>attach-sources</id> <goals> <goal>jar-no-fork</goal> </goals> </execution> </executions> </plugin> <!--生产javadoc插件--> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-javadoc-plugin</artifactId> <version>2.9.1</version> <executions> <execution> <id>attach-javadocs</id> <goals> <goal>jar</goal> </goals> <configuration> <encoding>UTF-8</encoding> <charset>UTF-8</charset> <additionalparam>-Xdoclint:none</additionalparam> </configuration> </execution> </executions> </plugin> <!--gpg加密插件--> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-gpg-plugin</artifactId> <version>1.6</version> <executions> <execution> <id>sign-artifacts</id> <phase>verify</phase> <goals> <goal>sign</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </profile> </profiles> </project>

    六 资料

    完成本文,参考了以下博文资料

    1、https://www.cnblogs.com/wxisme/p/8728008.html

    2、https://www.cnblogs.com/rstyro/articles/10811744.html

    3、https://blog.csdn.net/xiajiqiu/article/details/77607492

    Processed: 0.021, SQL: 9