再见JCenter,将你的开源库发布到MavenCentral上吧

Posted guolin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了再见JCenter,将你的开源库发布到MavenCentral上吧相关的知识,希望对你有一定的参考价值。

本文同步发表于我的微信公众号,扫一扫文章底部的二维码或在微信搜索 郭霖 即可关注,每个工作日都有文章更新。

关于JCenter废弃这件事情,相信许多朋友早就已经知道了。我在几个月前也专门写过一篇文章分析JCenter废弃事件的前前后后,感兴趣的朋友可以去阅读下这篇文章 浅谈JCenter即将被停止服务的事件

在上面这篇文章当中提到了几个比较关键的点:

  1. 自2021年3月31日之后,JCenter就不再接受任何新库的提交。
  1. 自2022年2月1日之后,JCenter将停止提供库的下载服务。
  1. Google会在其android开发者官网发布如何将开源库从JCenter迁出的方案。

当时整体的计划是这个样子的,然后几个月时间过去了,真是不得不说计划永远赶不上变化。

首先,Google修改了Android开发者官网的声明,没有再提到会给出迁出方案。只是告知开源库的发布者,以后发布库建议都发布到MavenCentral上。并告知开源库的使用者,你得自己去找这些库具体在哪里。

Google的这波操作可真是把锅甩的干干净净,JCenter废弃的事情与“我”再无关系,那是第三方开发者与JCenter之间的事情。

当时我看到Google修改声明之后心想,那这老库的迁移怎么办啊,Google是完全不管了。

不过再仔细一看,我才发现,原来JCenter也改了声明。在JCenter的最新声明中,2022年2月1日之后停止下载服务的那一条被删除了。也就是说,虽然JCenter不再允许开发者向其提交新的库,但是已经上传的老库会继续提供下载服务,这样也就不需要对它们做迁移了。

不知道为什么JCenter会改变态度做出这种善事,我猜测难不成是Google跟他们私下里进行了什么协商?不过不管怎么说,这对于开源库的开发者来说都是一件好事情,意味着老库的问题我们不需要再考虑了。

现在的问题就是,以后的新库怎么办?

为什么要使用MavenCentral

Google已经给出了其官方态度,建议开发者以后发布库都发布到MavenCentral上。

官方的态度其实是很重要的,因为以前JCenter也是这样被Google扶正的(结果Google被坑惨了),不然JCenter也无法在Android领域产生这么大的影响力。

如果你现在用最新版的Android Studio来创建一个新的项目,你会发现build.gradle文件中仓库的声明变成了这样:

allprojects {
    repositories {
        google()
        mavenCentral()
        jcenter() // Warning: this repository is going to shut down soon
    }
}

可以看到,mavenCentral()仓库成了创建项目时的默认仓库,而jcenter()仓库被标为了废弃。

许多国内的开发者可能会觉得MavenCentral太麻烦了,远不如JitPack用起来简单。

然而JitPack的问题就是并没有被Google官方推荐,你如果将库发布到JitPack上,开发者想要使用你的库,还得要额外引入一下JitPack的仓库才行,这无疑就增加了使用成本。

因此,即使是麻烦,我仍然建议广大开发者们要将自己的开源库发布到MavenCentral上。

那么接下来,我们就看看如何实现。

准备域名

相比于JCenter,MavenCentral的发布标准要远远高得多。不光是操作更麻烦的问题,而且MavenCentral还会对你是否拥有这个包路径所对应的域名进行检查。

比如你提交了一个库,它的包路径格式如下:

com.example.test:library:1.0.0

那么你就必须要拥有example.com这个域名才行。

相比之下,JCenter就完全不检查你是否真的拥有这个域名,谁先提交了使用这个包路径的库,这个包路径就是谁的了。

另外,注册自己的域名是要花钱的,如果你不想花钱的话也可以借助GitHub来完成,但是这样你的包路径就必须以io.github为前缀,而不能使用自定义的包路径了。

本篇文章介绍的是使用自己的域名来提交到MavenCentral的方式,如果你想要了解使用io.github域名的方式,可以参考这篇文章 发布Android Lib到Maven Central

那么不用多说,域名肯定是要自己先准备好的。我在阿里云上注册了一个叫guolindev.com的域名,因此我就可以使用以com.guolindev为前缀的包路径了。

创建工单

接下来访问以下地址去注册一个Sonatype账号:

https://issues.sonatype.org/secure/Dashboard.jspa

注册完之后重新访问该地址即可进入Sonatype Dashboard界面。

现在点击顶部工具栏上的Create按钮创建一个工单:

这个工单虽然看上去要填很多项内容,但其实还是非常简单的,我这里贴一下我当初填写的一个工单截图:

我们只需要填写带星号的必填项即可。

  • Project和Issue Type保持默认选项,不用做修改。
  • Summary可以随便填,这里我填写的是项目名称。
  • Group Id非常重要,决定着库的包路径是什么。前缀使用你刚才申请好的域名的倒排方式,后面可以自定义一些与库名相关的路径。
  • Project URL填写该项目的Github地址。
  • SCM url只需要在上面的Github地址后面加上.git后缀即可。

点击Create完成工单创建。

创建完工单之后需要等待工作人员审核,我测试下来非工作时间是没人审核你的工单的。所以如果你是在周末创建的工单,那么可能需要等待两到三天的时间才会有人处理。

有工作人员处理你的工单之后,他会在你的工单里留下一条评论,如下图所示:

这条评论的意思就是,你要证明刚才你在Group Id里填写的包路径所对应的域名是你的。

证明的方式就是,在你的域名中添加一条类型为TXT的解析,并将它指向你这条工单的URL地址。

如果你的域名是在阿里云注册的话,可以到域名管理界面,对着域名点击解析,然后按下图的示例添加解析记录即可:

添加完解析记录后,你需要在工单里回复一下,可以直接简单评论一句Done即可。这样工作人员会去验证你添加的解析记录是否已生效,验证没有问题之后,将会在评论里告诉你申请已通过:

从评论里得知,我们现在已经有权限向s01.oss.sonatype.org这个地址发布库了。

创建密钥

MavenCentral还要求,所有发布的库都必须使用GPG来进行签名才行,所以接下来我们就进行这个操作。

GPG在一些Linux系统上是内置的,如果你使用的Linux系统没有内置的话可以通过以下命令进行安装:

sudo apt install gnupg

Mac系统可以借助HomeBrew进行安装,命令如下:

brew install gpg

Windows系统需要访问下面的地址手动下载安装:

http://www.gnupg.org/download/

安装完成之后,输入以下命令创建密钥:

gpg --full-generate-key

接下来会弹出一系列的选项让你选择,比如密钥的类型,密钥的长度,密钥过期时间等。如果没有什么特殊需求的话,一路点击回车,使用默认选项就好了。

除此之外,还会要求你填写姓名、邮箱等内容,以及为这个密钥设置密码。

以上内容都填写完成之后,你就可以看到你创建的密钥了:

紧接着,我们需要把刚刚创建好的密钥上传到GPG服务器。这样MavenCentral到时候可以从GPG服务器上拿到我们的密钥,从对上传的包进行验证。

上传命令如下:

gpg --keyserver hkp://pgp.mit.edu --send-keys C37AF927

注意,最后send-keys后面使用的密钥ID是你刚刚创建的密钥ID的最后8位。这里一定要使用最后8位,我之前因为使用了完整的密钥ID,结果一直出现奇奇怪怪的错误。

最后一步,执行以下命令生成私钥文件:

gpg --export-secret-keys  -o 文件路径/secring.gpg

这个私钥文件一定要在你本地保存好,后面提交库的时候还需要用到它。

开始发布

以上所有步骤全部完成之后,下面就可以开始发布我们编写的开源库了。

为了让发布过程变得更加简单,我使用了gradle-maven-publish-plugin这样一个第三方开源插件。当然如果你直接使用官方的maven-publish插件也是可以实现同样的功能的,只是得额外写不少代码才行。

gradle-maven-publish-plugin插件的开源库地址是:

https://github.com/vanniktech/gradle-maven-publish-plugin

这个库的使用方法非常简单,将以下代码复制粘贴到你要发布的开源库所在模块的build.gradle文件的最底部即可:

...

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.vanniktech:gradle-maven-publish-plugin:0.17.0'
    }
}

allprojects {
    plugins.withId("com.vanniktech.maven.publish") {
        mavenPublish {
            sonatypeHost = "S01"
        }
    }
}

apply plugin: "com.vanniktech.maven.publish"

接来下打开项目根目录下的gradle.properties文件,并且按照下面的模板填入如下内容:

GROUP=com.guolindev.glance
POM_ARTIFACT_ID=glance
VERSION_NAME=1.0.0

POM_NAME=Glance
POM_DESCRIPTION=A simple and handy Android database debugging library.
POM_INCEPTION_YEAR=2020
POM_URL=https://github.com/guolindev/Glance/

POM_LICENSE_NAME=The Apache Software License, Version 2.0
POM_LICENSE_URL=https://www.apache.org/licenses/LICENSE-2.0.txt
POM_LICENSE_DIST=repo

POM_SCM_URL=https://github.com/guolindev/Glance/
POM_SCM_CONNECTION=scm:git:git://github.com/guolindev/Glance.git
POM_SCM_DEV_CONNECTION=scm:git:ssh://github.com/guolindev/Glance.git

POM_DEVELOPER_ID=guolindev
POM_DEVELOPER_NAME=Lin Guo
POM_DEVELOPER_URL=https://github.com/guolindev/

signing.keyId=密钥ID的后8位
signing.password=密钥密码
signing.secretKeyRingFile=私钥文件路径

mavenCentralUsername=Sonatype账号
mavenCentralPassword=Sonatype密码

这个模板的前三项决定着你的开源库的包路径是什么,比如按照我上面的写法,那么这个开源库的包路径就是:

com.guolindev.glance:glance:1.0.0

其他几项大多是一些说明型的内容,根据自己的实际情况填写就可以了。

最后密钥部分要填写你刚才创建的公钥ID和密码,以及私钥的文件路径,另外还要填写Sonatype的账号密码。

由于我们在这个文件当中填写了很多隐私内容,一定要记得将它排除在版本控制之外。

现在,我们可以通过在Android Studio右侧工具栏的Gradle页签当中找到publish这个任务,双击执行即可将这个库发布出去。

如果一切顺利的话,就应该能在控制台中看到库已经发布成功了。


同步到MavenCentral

但是到这里还没完。

需要知道的是,我们刚才并没有将库发布到MavenCentral,MavenCentral也不允许我们直接将库发布上去。

回顾一下一开始创建的工单,工作人员回复我们的是什么?

可以看到,我们只是可以向s01.oss.sonatype.org这个地址发布库,而这并不是MavenCentral。

另外我们刚才在build.gradle文件中编写的发布脚本也证实了这一点:

allprojects {
    plugins.withId("com.vanniktech.maven.publish") {
        mavenPublish {
            sonatypeHost = "S01"
        }
    }
}

这里将sonatypeHost指定成了S01,而S01指的就是将库发布到s01.oss.sonatype.org。

那么要如何才能将库发布到MavenCentral呢?接下来我们还需要做一下同步操作。

访问以下网址,并使用你的Sonatype账号密码登录(登录按钮在页面右上角):

https://s01.oss.sonatype.org/

登录成功之后,页面的左侧边栏当中将会多出一个Staging Repositories选项:

点击该选项,你就能看到刚刚发布成功的开源库了:

现在我们需要将这个库同步到MavenCentral仓库。操作方法是,先勾选中这个仓库,然后点击Close按钮关闭仓库,并在弹出的确认窗口中点击Confirm。

Close完毕之后,刷新界面,你会发现Release按钮就变成可点击的状态了:

点击Release按钮,并在弹出窗口中点击Confirm,这样就可以将这个开源库同步到MavenCentral上了。

不久之后,你会在之前创建的工单界面看到一条新的留言:

这是在告诉我们,同步工作已经开始了,通常大概需要30分钟左右的时间。但是如果想要在search.maven.org中可以搜到我们提交的仓库,最多可能需要4小时之久。

我并没有具体去验证一下同步到底需要多长时间,反正我是点击了Release按钮之后,第二天再到search.maven.org中去搜索,已经可以找到昨天提交的库了:

提交完成之后,想要在项目中引用这个库的话,只需要这样写即可:

dependencies {
    implementation 'com.guolindev.glance:glance:1.0.0'
}

和之前使用JCenter仓库的写法并无差别。

到这里,我们就把将开源库发布到MavenCentral的所有流程都走了一遍。只要跟着这些流程去操作,相信大家都可以成功将库发布到MavenCentral上。

同时本篇文章又成为了《第一行代码 第3版》的又一篇DLC。伴随着Google的高速技术迭代,我已经不知道为这本书发了多少篇补丁文章了。

另外,细心的朋友可能注意到了,本文我一直在用Glance这个库进行演示,这意味着Glance的新版本很快就要发布了。那么下篇原创文章,我会跟大家聊一聊新版的Glance又多了哪些新功能,我们下期见。


如果想要学习Kotlin和最新的Android知识,可以参考我的新书 《第一行代码 第3版》点击此处查看详情


关注我的技术公众号,每天都有优质技术文章推送。

微信扫一扫下方二维码即可关注:

以上是关于再见JCenter,将你的开源库发布到MavenCentral上吧的主要内容,如果未能解决你的问题,请参考以下文章

再见JCenter,将你的开源库发布到MavenCentral上吧

踩坑速记全面解析开源库打包发布到Bintray/Jcenter全过程(新),让开源更简单~

AndroidStudio怎么将开源项目发布到jcenter

提交项目到jcenter

Android Studio发布到Jcenter

Android 发布开源库到 JitPack (详细步骤)