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

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

去年我就想将本身开源的一个miniexcel工具包发布到maven仓库,在项目中经过依赖导入使用,但那时候感受太麻烦了,而后看到有文章介绍说可使用jitpack,这个就很是简单了。可是最近在项目中,因为是使用maven,配置jitpack老是导入不了依赖,一直报错,为了避免拖慢进度,我仍是放弃了使用这个工具。java

所以,我仍是想将项目打包发布到maven中央仓库。折腾了一天,踩了不少坑才成功的。但愿本篇对你们有所帮助。git

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

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

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

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

这里Group Id我使用个人gitbub的地址。若是是填写你本身的域名,是须要验证的,如com.wujiuye,那么后面须要证实这个域名是你的,怎么证实后面提到。填写github的域名也是须要验证的,下一步介绍。apache

填写完以后点击右下角的新建按钮便可建立项目。ubuntu

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

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

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

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

意思是如今你能够将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详细配置如图:

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

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

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

  • 把用户名和密码的配置移动到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任务执行。

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

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

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

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

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

上图中,当前此次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步骤。

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

咱们须要使用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
.....
复制代码

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

在建立完成后,可使用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查询出来。

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

若是签名仍是验证失败,失败信息以下:

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就可以成功了。

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

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

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

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

成果:

https://search.maven.org/search?q=miniexcel
复制代码

最后不要忘记了在sonatype上的项目详情页回复下已经完成,通知sonatype的工做人员关闭issue。之后想发布开源项目到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
复制代码

后记

在迭代升级版本的时候,Close成功,但点击Release按钮,发布失败了。报以下异常:

typeId  RepositoryWritePolicy
failureMessage	| Artifact updating: Repository ='releases:Releases' does not allow updating artifact='/com/github/wujiuye/miniexcel/maven-metadata.xml.sha512'
failureMessage	| Artifact updating: Repository ='releases:Releases' does not allow updating artifact='/com/github/wujiuye/miniexcel/maven-metadata.xml.sha256'
复制代码

意思是不运行更新maven-metadata.xml.sha512maven-metadata.xml.sha256这两个文件。

后面在sonatype上找到一样的问题,也是说升级的时候Release失败,用的Gradle 6.0版本,而后禁掉sha256sha512校验后就能够Release成功,且不会影响正常依赖使用。Unable to release staging repository due to maven-metadata.xml.sha512/256 files

可是没说是怎么禁用的,而后我就照着这个思路,想找怎么禁用sha256sha512校验的方法,找到了这篇。 maven-metadata.xml SHA256 and SHA512 checksums prevent publishing to Nexus

在项目的gradle.properties文件中添加以下配置便可:

### 禁用Gradle 6.x 版本 SHA-256和SHA-512校验和的发布
systemProp.org.gradle.internal.publish.checksums.insecure=true
复制代码

文中的项目地址:https://repo1.maven.org/maven2/com/github/wujiuye/miniexcel/1.1.1-RELEASE/,欢迎使用!

相关文章
相关标签/搜索