转载

教你如何将开源项目发布到maven中央仓库

如何将开源项目发布到 maven 中央仓库,让别人通过依赖使用你的开源项目,想必很多朋友都有过这个想法。

去年我就想将自己开源的一个 miniexcel 工具包发布到 maven 仓库,在项目中通过依赖导入使用,但那时候感觉太麻烦了,然后看到有文章介绍说可以使用 jitpack ,这个就非常简单了。但是最近在项目中,由于是使用 maven ,配置 jitpack 总是导入不了依赖,一直报错,为了不拖慢进度,我还是放弃了使用这个工具。

因此,我还是想将项目打包发布到 maven 中央仓库。折腾了一天,踩了很多坑才成功的。希望本篇对大家有所帮助。

项目构建工具: Gradle ,版本: 6.2.2 ,官方文档当前最新版本。原本是使用 gradle4.5.1 版本的,但是找不到 4.5 版本的 MavenPublication 的文档,倒不如直接将 Gradle 切换到 6.2.2 版本。关于 MavenPublication 看到后面你就知道了。

首先是到 https://issues.sonatype.org/ 注册账号,注册成功后登陆。需要注意的一点是,账号的密码必须要包含大写字母、小写字母、数字加特殊符号。登陆成功后,首次登陆会让你选择语言,可以选择中文,非常友好。

如果选择的是中文,那么下一步就是在首页点击“新建”,可以理解为工单,或者英文叫 issue ,或者可以理解为新建项目。在弹出窗口填写 issue 信息。

教你如何将开源项目发布到maven中央仓库

项目选择 Community Support - Open Source Project Repository Hosting ,问题类型选择 New Project 。概要随便填,描述写项目的介绍。最后就是填写 Group Id 、项目地址、 git 仓库地址。

这里 Group Id 我使用我的 gitbub 的地址。如果是填写你自己的域名,是需要验证的,如 com.wujiuye ,那么后面需要证明这个域名是你的,怎么证明后面提到。填写 github 的域名也是需要验证的,下一步介绍。

填写完之后点击右下角的新建按钮即可创建项目。

教你如何将开源项目发布到maven中央仓库

在项目创建成功后,你注册时填写的邮箱会收到一封邮件,你可以通过查看邮件看下一步要做说明,或者你也可以直接在项目详情页的底部“注释”栏看评论,此时会有一个评论,与邮件收到的内容是一样的。意思是需要你在你的 github 上创建一个名为 OSSRH-56052 的项目。

如果你在创建项目时,填写的 Group Id 是你自己的域名,这时就会要求你配置 DNS 来验证这个域名是你的,或者其它方式,这个我没去试,具体怎么验证我也不清楚。

教你如何将开源项目发布到maven中央仓库

在你的 github 上创建完项目之后,还需要回到 sonatype 网站的项目详情页面,在“注释”下面回复说你已经完成这一步了。

教你如何将开源项目发布到maven中央仓库

稍等一会之后,你会收到它的新回复。

教你如何将开源项目发布到maven中央仓库

意思是现在你可以将 SNAPSHOTRELEASE 的构件( jar )部署到仓库 xxx 了。现在回到你的项目,在 build.gradle 配置文件下,添加配置,使用 maven-publish 插件将项目打包发布到仓库。

这里参考了 gradle 官方文档给的配置: https://docs.gradle.org/current/javadoc/org/gradle/api/publish/maven/MavenPublication.html

先添加 maven-publish 插件

plugins {
    id 'java'
    // maven 发布插件
    id 'maven-publish'
}
复制代码

group 改为你在 sonatype 创建的项目的 Group Id 。我们先简单配置看下是否能够发布成功,所以先发布一个 SNAPSHOT 版本,需要在版本名后面加上 -SNAPSHOT ,否则发布到 SNAPSHOT 仓库会失败。

group 'com.github.wujiuye'
version '1.0.0-SNAPSHOT'
复制代码

注意,以 -SNAPSHOT 结尾的版本号发布到 release 仓库会失败,只能发到 snapshot 仓库,所以后面发布 release 版本时,需要去掉 -SNAPSHOT

接着是 publishing 的配置。

publishing {
    publications {
        // 推送配置
        publishMyProjectMiniexcel(MavenPublication) {
            // 编译jar包
            from components.java
            // 打包源码
            artifact sourcesJar
        }
    }
    // 到 https://oss.sonatype.org/#nexus-search; 搜索是否上传成功
    repositories {
    }
}
复制代码

repositories 详细配置如图:

教你如何将开源项目发布到maven中央仓库

详细的 build.gradle 后文会给出。这里配置两个仓库,一个是 Release 仓库,一个是 Snapshot ,名称 name 是自己随便填的, url 就是上一步在 sonatype 你的项目详情页收到的回复的两个地址。 credentials 配置的是你登陆 sonatype 的账号和密码。在你项目的 build.gradle 同级目录下,新建一个 gradle.properties 文件,将账号密码写在这个配置文件中。

注意,不要把这个文件提交到 github ,不然你密码就泄漏了。最好是在你安装的 gradle 的全局 gradle.properties 文件中配置,这也是推荐的做法。

教你如何将开源项目发布到maven中央仓库

如何做到安全(这一步可以先忽略,等后面测试发布成功了,再回来完成这个步骤):

  • 把用户名和密码的配置移动到 GRADLE_USER_HOME 目录下的 gradle.properties 文件中;
  • 项目目录下的 gradle.properties 中相同的变量则会覆盖 GRADLE_USER_HOME/gradle.properties 中的配置。在执行 build 的时候,用户名和密码会被读取,如果不存在的话会报错,比如别人下载了你的源码调试,将不能构建成功,所以项目目录下的 gradle.properties 中保留用户名和密码并且是错误的用户名和密码;
  • 在打包构建的时候,手动去除掉项目中 gradle.properties 的用户名和密码配置。让构建的时候获取 GRADLE_USER_HOME/gradle.properties 中的配置,构建完成后,再还原回来,防止别人构建失败。

现在就可以在 idea 中点击右侧的 gradle ,也就是前面一张图的红色箭头指向(配置仓库的那张)。在任务下的 publishing 选择 publish+你配置的推送任务名称+PublicationToSnapshotRepository 任务执行。

教你如何将开源项目发布到maven中央仓库

推送成功后到 https://oss.sonatype.org/#nexus-search 搜索,看看是不是发布成功了。

教你如何将开源项目发布到maven中央仓库

现在我们需要完善配置,发布 Release 版本到 Release 仓库。我们先只是修改下版本后,去掉 -SNAPSHOT ,然后执行 publish+你配置的推送任务名称+PublicationToReleaseRepository 任务。注意,与发布快照版本不是同一个任务,仔细看区别。

然后到 https://oss.sonatype.org/#stagingRepositories 查看发布好的构件。点击左侧的 Staging Repositories ,第一个就是刚刚发布的 jar ,此时的构件状态为 Open

教你如何将开源项目发布到maven中央仓库

选中构件,并点击上方的 Close ,然后会提示你是否确认,继续点击 Confirm

教你如何将开源项目发布到maven中央仓库

点击 Refresh ,在下边的 Activity 选项卡中查看状态。不出意外,是不会成功的!因为这才是填坑的开始。

教你如何将开源项目发布到maven中央仓库

上图中,当前这次 close 的状态,有很多项是验证失败的,就是图标打个叉叉的。

失败的选项有:

  • POM 验证失败,原因是没有配置 POM 信息
  • Javadoc 验证失败,原因是没有上传 Javadoc
  • Signature 签名验证失败,这个就比较复杂了。

我们先解决 pomjavadoc 验证失败的问题。回到项目中,在 build.gradle 文件完善配置,如下:

plugins {
    id 'java'
    // maven 发布插件
    id 'maven-publish'
}

group 'com.github.wujiuye'
version '1.1.0-RELEASE'

repositories {
    mavenCentral()
}

dependencies {
    // excel表格
    compile group: 'org.apache.poi', name: 'poi', version: '3.17'
    compile group: 'org.apache.poi', name: 'poi-ooxml', version: '3.17'
    compile group: 'org.apache.poi', name: 'poi-ooxml-schemas', version: '3.17'

    testCompile group: 'junit', name: 'junit', version: '4.12'
}

// 打包源码
task sourcesJar(type: Jar) {
    classifier = 'sources'
    from sourceSets.main.allJava
}

// 生成 javadoc jar
task javadocJar(type: Jar) {
    classifier = 'javadoc'
    from javadoc.destinationDir
}

publishing {
    publications {
        // 推送
        publishMyProjectMiniexcel(MavenPublication) {
            // 编译jar包
            from components.java
            // 打包源码
            artifact sourcesJar
            // javadoc
            artifact javadocJar

            pom {
                name = "miniexcel"
                description = "基于poi封装的一套excel文件读写工具,完美解决oom问题。优雅的使用设计模式提供更简单的使用姿势!更有详细的使用教程。如需获取帮助,关注微信公众号:Java艺术"
                url = "https://github.com/wujiuye/miniexcel"
                licenses {
                    license {
                        name = "The Apache License, Version 2.0"
                        url = "http://www.apache.org/licenses/LICENSE-2.0.txt"
                    }
                }
                developers {
                    developer {
                        id = "wujiuye"
                        name = "wujiuye"
                        email = "419611821@qq.com"
                    }
                }
                scm {
                    connection = "scm:git:https://github.com/wujiuye/miniexcel.git"
                    developerConnection = "scm:git:https://github.com/wujiuye/miniexcel.git"
                    url = "https://github.com/wujiuye/miniexcel"
                }
            }
        }
    }
    // 到 https://oss.sonatype.org/#nexus-search; 搜索是否上传成功
    repositories {
        // 发布Release版本可在版本号后面带上'-RELEASE',也可不带
        maven {
            name 'Release'
            url 'https://oss.sonatype.org/service/local/staging/deploy/maven2'
            credentials {
                username = "${NEXUS_USERNAME}"
                password = "${NEXUS_PASSWORD}"
            }
        }
        // 发布Snapshot快照版本必须在版本号后面加上'-SNAPSHOT'
        maven {
            name = 'Snapshot'
            url = 'https://oss.sonatype.org/content/repositories/snapshots'
            credentials {
                username = "${NEXUS_USERNAME}"
                password = "${NEXUS_PASSWORD}"
            }
        }
    }
}
复制代码

现在重新执行一遍 publish+你配置的推送任务名称+PublicationToReleaseRepository 任务,再回到 https://oss.sonatype.org/#stagingRepositories 。由于前面有提交过,现在刷新会有两个构件,看最后一个,或者看时间,选择最新上传的那个构件,继续完成 Close 步骤。

教你如何将开源项目发布到maven中央仓库

这次已经少了两个错误了,只剩一个签名验证失败。而这个相对来说比较复杂。

我们需要使用 gpg 生成密钥,以我的电脑为例, mac 下安装 gpg 非常简单,使用 brew 安装就可以了。 windows 下更容易了,一大堆教程, mac 下的教程还比较难找。

brew install gpg
复制代码

使用 gpg --gen-key 命令生成密钥。

MacBook-Pro:~ wjy$ gpg --gen-key
gpg (GnuPG) 2.2.19; Copyright (C) 2019 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.

注意:使用 “gpg --full-generate-key” 以获得一个功能完整的密钥产生对话框。
GnuPG 需要构建用户标识以辨认您的密钥。
真实姓名: wujiuye
电子邮件地址: 419611821@qq.com
.....
复制代码

填完电子邮箱后会要求输入密钥的密码。

教你如何将开源项目发布到maven中央仓库

在创建完成后,可以使用 gpg --list-keys 命令查看。

MacBook-Pro:~ wjy$ gpg --list-keys
gpg: 正在检查信任度数据库
gpg: marginals needed: 3  completes needed: 1  trust model: pgp
gpg: 深度:0  有效性:  1  已签名:  0  信任度:0-,0q,0n,0m,0f,1u
gpg: 下次信任度数据库检查将于 2022-03-23 进行
/Users/wjy/.gnupg/pubring.kbx
-----------------------------
pub   rsa2048 2020-03-23 [SC] [有效至:2022-03-23]
      5FE36BC89979FABF8D48ADD0B6559088974BA646
uid           [ 绝对 ] wujiuye <419611821@qq.com>
sub   rsa2048 2020-03-23 [E] [有效至:2022-03-23]
复制代码

build.gradle 配置文件添加签名插件。

plugins {
    id 'java'
    // maven 发布插件
    id 'maven-publish'
    // 签名插件
    id 'signing'
}
.......

publishing {
  ....... 
}

// 必须在 publishing 配置之后
signing {
    sign publishing.publications.publishMyProjectMiniexcel
}
复制代码

然后在 gradle.properties 文件中添加密钥项的配置。

### gpg --list-keys --keyid-format short 查出来的
signing.keyId=52FEDB1A
### 创建密钥时的密码
signing.password=wujiuye950605
### .gpg文件的路径
signing.secretKeyRingFile=/Users/wjy/.gnupg/secring.gpg
复制代码

使用 gpg --gen-key 命令创建密钥并没有生成 secring.gpg 文件,现在我们可以通过命令 gpg --export-secret-keys 生成 secring.gpg ,生成的 secring.gpg 文件的路径便是 gradle.properties 配置文件中 signing.secretKeyRingFile 这项的值。

gpg --export-secret-keys -o /Users/wjy/.gnupg/secring.gpg
复制代码

还有一个 signing.keyId 可以通过 gpg --list-keys --keyid-format short 查询出来。

教你如何将开源项目发布到maven中央仓库

注意,是红框中的那个。现在重新执行一遍 publish+你配置的推送任务名称+PublicationToReleaseRepository 任务,再回到 https://oss.sonatype.org/#stagingRepositories 。可以继续完成 Close 步骤了。

教你如何将开源项目发布到maven中央仓库

如果签名还是验证失败,失败信息如下:

failureMessage	No public key: Key with id: (4e999e3952fedb1a) was not able to be located on <a href="http://keyserver.ubuntu.com:11371/">http://keyserver.ubuntu.com:11371/</a>. Upload your public key and try the operation again.
failureMessage	No public key: Key with id: (4e999e3952fedb1a) was not able to be located on <a href="http://keys.openpgp.org:11371/">http://keys.openpgp.org:11371/</a>. Upload your public key and try the operation again.
failureMessage	No public key: Key with id: (4e999e3952fedb1a) was not able to be located on <a href="http://pool.sks-keyservers.net:11371/">http://pool.sks-keyservers.net:11371/</a>. Upload your public key and try the operation again.
复制代码

说明我们还需要将密钥发送到 keyserver.ubuntu.com:11371keys.openpgp.org:11371pool.sks-keyservers.net:11371 这几个地址中的其中一个,按照验证顺序,首选第一个。

MacBook-Pro:.gnupg wjy$ gpg --keyserver http://keyserver.ubuntu.com:11371 --send-keys 5FE36BC89979FABF8D48ADD0B6559088974BA646
gpg: 正在发送密钥 B6559088974BA646 到 http://keyserver.ubuntu.com:11371
复制代码

现在重试 Close 就能够成功了。

教你如何将开源项目发布到maven中央仓库

耐心等待邮件吧,这个过程是需要很久的。我大概等了一个小时,才收到邮件。

教你如何将开源项目发布到maven中央仓库

邮件中提示说,我还需要选中最后一次 Close 成功的构件,点击 Release 按钮。继续返回 https://oss.sonatype.org/#stagingRepositories

教你如何将开源项目发布到maven中央仓库

现在 Release 按钮已经变成可点击了,愉快的点击发布吧。大概过了二十多分钟,收到一封邮件。此时已经凌晨一点半了。

教你如何将开源项目发布到maven中央仓库

意思是说,再过十分钟,就可以在 maven 中央仓库中搜索到了,不过对于 https://search.maven.org 这个网站可能还要两个小时才能搜索到。

成果:

https://search.maven.org/search?q=miniexcel
复制代码
教你如何将开源项目发布到maven中央仓库

最后不要忘记了在 sonatype 上的项目详情页回复下已经完成,当然不是必须的。以后想发布开源项目到 maven ,只要 Group Id 不变,就可以省略很多步骤了。

参考资料:

【如何将自己的开源项目发布到Maven中央仓库】
https://blog.csdn.net/sinat_23290725/article/details/85018092
【Gradle 发布 JAR 包到 maven 中央仓库(sonatype )】
https://blog.csdn.net/mr_zhuqiang/article/details/84564256
【gradle签名插件配置问题】
https://stackoverflow.com/questions/27936119/gradle-uploadarchives-task-unable-to-read-secret-key
【MavenPublication配置参考】
https://docs.gradle.org/current/javadoc/org/gradle/api/publish/maven/MavenPublication.html
复制代码
原文  https://juejin.im/post/5e78b557e51d452707650394
正文到此结束
Loading...