Gradle发布Java Library到Maven中央仓库

标签: gradle   maven  

最近打算将一些基础的Jar包上传到Maven中央仓库,方便在自己项目中引用。本文将结合Gradle的两个插件maven-publishsigning来讲解如何发布一个Jar包。

在开始之前,先对OSSRH做下了解是很必要的。

OSSRHSonatype Open Source Software Repository Hosting Service,为开源软件提供maven仓库托管服务。你可以在上面部署snapshotrelease等,最后你可以申请把你的release同步到Maven Central RepositoryMaven中央仓库)。

注册Sonatype JIRA账号

JIRA是Atlassian公司出品的项目与事务跟踪工具,被广泛应用于缺陷跟踪、客户服务、需求收集、流程审批、任务跟踪、项目跟踪和敏捷管理等工作领域。

网址:https://issues.sonatype.org/

注册好了之后,记住用户名和密码,下面会用到。

创建Issue

地址:https://issues.sonatype.org/secure/CreateIssue.jspa?issuetype=21&pid=10134

  • Summary:简单的写一个描述即可

  • Group Id

    • 自己有域名 可以使用子域名作为Group Id注意:不能瞎编一个,因为后面审核人员会来审核你是否是该域名的拥有者
    • 自己没域名 可以借助github,例:我的用户名为amuguelove,那么就用com.github.amuguelove作为作为Group Id,例如:我就是这样提供的,审核人员会让你新建一个仓库来验证你是否是github账号的拥有者。
  • Project URL:最好与Group Id有一定关联性,例如:

    Project URL: https://github.com/amuguelove/spring-boot-projects
    Group Id: com.github.amuguelove
    
  • SCM url:版本仓库的拉取地址

可以看考一下我成功了的例子:https://issues.sonatype.org/browse/OSSRH-55962

等待回复

提交Issue后,如果存在问题,审核者会在jira中指出,可以直接回复,见下图。

如果一切顺利,那么你会收到审核人员,这样的一个评论:

OSSRH对提交文件的要求

为了确保中央存储库中可用组件的质量水平,OSSRH对提交的文件有明确的要求。

一个基础的提交,应该包含一下文件:

example-1.0.0.pom
example-1.0.0.pom.asc
example-1.0.0.jar
example-1.0.0.jar.asc
example-1.0.0-sources.jar
example-1.0.0-sources.jar.asc
example-1.0.0-javadoc.jar
example-1.0.0-javadoc.jar.asc

下面我们会使用Gradle构建工具来帮助我们来生成。

GPG

OSX下可以通过brew来安装gpg命令行工具。

$ brew update
$ brew install -v gpg

也可以去官网下载安装,地址:https://gpgtools.org/

新建一个密钥

gpg --generate-key

查看已经生成的密钥

$ gpg -k

/Users/bo.liang/.gnupg/pubring.kbx
----------------------------------
pub   dsa2048 2010-08-19 [SC] [expires: 2020-06-15]
      85E38F69046B44C1EC9FB07B76D78F0500D026C4
uid           [ unknown] GPGTools Team <team@gpgtools.org>
sub   elg2048 2010-08-19 [E] [expires: 2020-06-15]
sub   rsa4096 2014-04-08 [S] [expires: 2024-01-02]

pub   rsa2048 2020-03-19 [SC] [expires: 2022-03-19]
      CD62FE125D651206FBC76C88DF58A148A2AAA46C
uid           [ultimate] liangbo <bo.liang0212@gmail.com>
sub   rsa2048 2020-03-19 [E] [expires: 2022-03-19]

CD62FE125D651206FBC76C88DF58A148A2AAA46C,是密钥指纹(用来做唯一识别),后面8位**A2AAA46C**叫做标识KEY ID,在后面需要加到Gradle插件配置中。

导出私钥文件

$ gpg --export-secret-keys [密钥指纹] > secret.gpg

例如:
[16:56:48] bo.liang:gnupg $ gpg --export-secret-keys A2AAA46C > secret.gpg
[17:00:06] bo.liang:gnupg $ pwd
/Users/bo.liang/Documents/workspace/myProjects/gnupg

会生成一个二进制的私钥文件,后面需要配置到gradle中,让signing插件帮我们给文件批量签名。

上传公钥到公钥服务器

$ gpg --keyserver keyserver.ubuntu.com --send-keys [密钥指纹]

在sonatype的仓库提交后,会需要一个校验步骤 会需要从多个公钥服务器上下载匹配的公钥,然后来校验你上传的文件的签名。

以下是sonatype会去拉取的公钥服务器列表。

keys.gnupg.net
pool.sks-keyservers.net
keyserver.ubuntu.com

准备好了以上几项,我们就可以开始撸Gradle了

配置Gradle插件

build.gradle参数

plugins {
    id "java-library"
    id "maven-publish"
    id "signing"
}

task sourceJar(type: Jar) {
    classifier "sources"
    from sourceSets.main.allJava
}

task javadocJar(type: Jar, dependsOn: javadoc) {
    classifier "javadoc"
    from javadoc.destinationDir
}

javadoc {
    description = "生成jar格式的javadoc。"
    // 只显示 protected 和 public 的类和成员
    options.memberLevel = org.gradle.external.javadoc.JavadocMemberLevel.PROTECTED
    options.author = true
    options.version = true
    options.header = project.name
    // 静默javadoc检查(比如不支持@date会报错等),jdk 8+
    options.addStringOption('Xdoclint:none', '-quiet')
    // 防止本地打开中文乱码
    options.addStringOption("charset", "UTF-8")
    // suppress warnings due to cross-module @see and @link references;
    // note that global 'api' task does display all warnings.
    logging.captureStandardError LogLevel.INFO
    // suppress "## warnings" message
    logging.captureStandardOutput LogLevel.INFO
    // 编码一定要配置否则直接出错
    options.encoding = "UTF-8"
    options.charSet = "UTF-8"
}

publishing {
    publications {
        mavenJava(MavenPublication) {
            groupId = 'com.github.amuguelove'
            artifactId = 'p6spy-spring-boot-autoconfigure'
            version = '1.0.0'
            from components.java

            artifact sourceJar
            artifact javadocJar

            pom {
                name = 'p6spy-spring-boot-autoconfigure'
                description = 'quickly integrate p6spy for spring boot'
                url = 'https://github.com/amuguelove/spring-boot-projects'
                licenses {
                    license {
                        name = 'Apache License, Version 2.0'
                        url = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
                        distribution = 'repo'
                        comments = 'A business-friendly OSS license'
                    }
                }
                developers {
                    developer {
                        name = 'liangbo'
                        email = 'bo.liang0212@gmail.com'
                        roles = ['Java Developer']
                        url = "https://amuguelove.github.io"
                    }
                }
                scm {
                    url = 'https://github.com/amuguelove/spring-boot-projects'
                    connection = 'scm:git:https://github.com/amuguelove/spring-boot-projects.git'
                    developerConnection = 'scm:git:git@github.com:amuguelove/spring-boot-projects.git'
                }
            }
        }
    }

    repositories {
        maven {
            name "oss"
            def releasesRepoUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2"
            def snapshotsRepoUrl = "https://oss.sonatype.org/content/repositories/snapshots"
            url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl
            credentials {
                username = sonatypeUsername
                password = sonatypePassword
            }
        }
    }
}

signing {
    sign publishing.publications.mavenJava
}

在项目根目录或者gradle根目录新增gradle.properties(我推荐在本地的gradle根目录新建,毕竟有敏感信息)

signing.keyId=密钥keyId(后8位)
signing.password=密钥password(gpg新建秘钥时输入的密码)
signing.secretKeyRingFile=私钥keyRingFile路径

sonatypeUsername=sonatype账号
sonatypePassword=sonatype密码

提交到Sonatype仓库

首先,用Gradle执行publishToMavenLocal任务,先在本地发布下,看看生成了哪些文件,或还有什么问题

然后,用Gradle执行publish任务,发布到指定的maven仓库

如果没有报错,那么恭喜你,已经成功提交到了sonatype的仓库中

但是提交成功,并不代表发布成功。

到Sonatype OSS发布

用你之前注册的账号密码,登录:https://oss.sonatype.org/

登录后查看左侧的Build Promotion->Staging Repositories

点击Close按钮后,中央仓库会验证你上传的文件签名,回去公钥服务器拉取公钥,如果验证失败会提示你,根据提示修改你的操作。

需要等待一会,等它执行完毕,状态会从open变成closed

一般情况下,感觉如果顺利close后,再次选中点击Release,耐心等待一会,就大功告成了!

可以在侧边栏Artifact Search中搜索下你的groupId,此时应该能看到对应的构件名称和版本了

但是!!!

目前为止你的Jar包还无法在Maven Search页面找到,根据上面审核人员的提示需要2个小时,但是我实际的等待不止两个小时。看来从sonatype同步到中央仓库,的确是需要一定的时间。

但是文件其实会比索引同步得早,所以你可以先到 https://repo1.maven.org/maven2/ 上按照坐标找下,是否能找到你的包。如果能找到,那你就可以开始引用它了。

之后可以间隔不同的时间去 https://search.maven.org/ 上搜一下。

新版本更新

你可以在groupId范围内发布任意名称的构件

参考

Sign and publish on Maven Central a Project with the new maven-publish Gradle plugin

OSSRH Guide

Maven Publish Plugin

The Sign Plugin

Generating a new GPG key

「真诚赞赏,手留余香」

请我喝杯咖啡?

使用微信扫描二维码完成支付