向 MavenCentral 丢个包

最近申请了个公众号:策码编腾,尝试下在公众号平台写文章,感兴趣的可以关注下。

以前 Android 开发都是往 jCenter 发包,然后 jCenter 就玩完了。

现在基本上都是往 MavenCentral 丢包了, 不过往 MavenCentral 丢包的流程还是复杂了不少,一个是 Sonatype 的账号申请、管理后台有点奇特,另一个是发包的流程也多了几步。 虽然多的流程是为了校验、签名以保证上传库文件的完整与安全,但也容易让开发者踩坑,花费好长时间才能成功完成上传。

所以本文来梳理下打包脚本和完整的发包流程。

一. 打包

一般而言,如果是纯 java/kotlin 工程, 我们可以打成 jar 包, 如果是 android library 工程,因为有资源文件等,我们需要打 成 aar 包。

但是 jar 包和 aar 包都是 .class 文件了, 引入到工程后我们不能看到方法的具体实现,对于 debug 是件很痛苦的事情,因为我们还需要上传 soures 文件和 javadoc 文件,如果是 kotlin,业界生成 doc文件主流使用的是 dokka。除此之外, 为了包上传过程不被网络劫持而篡改,我们需要对每个文件进行签名,MavenCentral 支持 GPG 或者 GnuPG 进行签名 生成 asc 文件,这个也是必须的。

首先需要引入 maven-publish 插件:

plugins {    
    `maven-publish`
}
复制代码

注:脚本都是用 kts 语法

打 jar 包:

afterEvaluate {
     publishing {
         publications {
             create<MavenPublication>("release") {
                 from(components.getByName("java"))
             }        
         }    
     }
}
复制代码

打 aar 包的话,以前也比较麻烦,components 只提供了 java 的实现,所以需要开发主动去 build 目录里去捞 aar 文件(也许现在很多陈年老代码还是这么做的)。后面官方终于在 components 提供了, 所以也是需要多关注下官方的动态,可以少点 copy-paste 开发,这种场景下文还会提到。

afterEvaluate {
    publishing {
        publications {
            create<MavenPublication>("release") { 
                from(components.getByName("release"))
            }
        }
    }
}
复制代码

那么如何生成 sources 文件和 javadoc 文件呢?

如果是纯 java/kotlin 工程,则比较简单:

java {
    withJavadocJar()
    withSourcesJar()
}
复制代码

那么如果是 android library 工程呢, 以前是比较麻烦的,要自己去定义这些 task。好在官方终于不忍每个项目都要做 copy-paste 编程,终于在 AGP 7.1 后提供了官方支持:

android {
    publishing {
        singleVariant("release") {
            withJavadocJar()
            withSourcesJar()
        }
    }
}
复制代码

所以强烈建议还没升级 AGP 7 的工程赶紧升,反正 Compose 也是要依赖 AGP 7 的,早升早享受 Compose 编程。

二. 签名

一般公司内网的 Maven 库是不会要求这个,但是 Sonatype 是强制要求的,所以我们也得搞。

首先我们得安装 GPG 或者 GunPG,Sonatype 其实是提供了很好的文档的,链接:central.sonatype.org/publish/req…

我是去 gnupg.org/download/in… 下载安装的 GnuPG。安装好后就需要创建自己  key pair 并将 key 发布出去。

创建 key pair:

gpg --gen-key
复制代码

按照指引,输入密码、过期时间、用户名、邮箱等,最终完成创建:

image.png

我们也可以稍后通过 gpg --list-keys,列出已经存在的 keys。

gpg --list-keys
复制代码

然后我们需要将 public key 发布出去,MavenCentral  才可以拿到 key 进行之后的校验。

gpg --keyserver keyserver.ubuntu.com --send-keys 58D80640
复制代码

最后,我们怎么告诉 gradle 我们的gpg 私钥等信息呢?

我们配置在 gradle 的全局配置 ~/.gradle/gradle.properties 里:

signing.keyId=58D80640
signing.password=xxxxxx
signing.secretKeyRingFile=/Users/cgspine/.gnupg/secring.gpg
复制代码

完成了这些,我们终于可以回到工程的配置脚本了。

首先,引入 sign 插件:

plugins {
    signing
}
复制代码

然后在 publish 脚本中使用:

afterEvaluate {
    publishing {
        publications {
            create<MavenPublication>("release") { 
                from(components.getByName("release")) 
                signing {
                    sign(this@create)
                }
            }
        }
    }
}
复制代码

终于,我们的脚本都配置好了,但是呢, 如果每个工程都要进行下这种配置,那还是挺糟心的,特别是 QMUI 现在好多个子工程了,一些是纯 java, 一些需要发布成 aar。 

所以我们需要抽取,抽取有两种方式, 一种是将这些代码用publish.gradle.kts 来承载,然后每个工程的 build.gradle.kts 引入这个文件,不过不知道是不是之前我使用的姿势的问题,每次都编译不起来,报的错误我也不懂。所以我就换成了第二种方式, 用 gradle 插件的形式。通过 Composing builds 或者以前的 buildSrc,随时修改插件还是比较容易的。QMUI 我抽取出了 QMUIPublish.kt 文件,就是处理发布的,兼容了纯 java 工程以及 android library 工程,有兴趣的可以去看看代码。

三. 发包

发布第一步就是要有 maven 仓库的权限,正常来说,只要我们注册、登录、申请发包权限就行了,但是MavenCentral 的这个流程比较奇葩,首先,它自己没有注册功能, 因而我们需要用到前文提到的 Sonatype,而且很奇葩的是注册功能是在 Issue Tracker 网站上, 地址:issues.sonatype.org/secure/Sign…, 然后权限是怎么申请呢?是我们要在 Issue Tracker 网站上创建一个 issue,然后再由网站管理员操作、在 issue 下留言以告知进度或者要求提供更多的证明资料,一个主要的是目的是要你证明你的库的 package 是合法的。我们都知道 java 是用网络域名来作为 package 以标明唯一性的。 所以不是任何人都能以 com.qmuiteam 发包的。

有了用户名和密码,我们的发布脚本终于能够跑起来了,由于这部分信息是私有的,因而肯定不能提交到 github 上去, QMUIPublish 脚本会从 gradle/deploy.properties 文件中读取,文件内容格式如下:

maven.url=https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/
maven.username=xxx
maven.password=xxx
复制代码

然后我们运行脚本,发包成功,但好像通过 MavenCentral 访问不到刚发布的版本?

原来脚本的发布成功, 只是将库文件推送到了 Sonatype 后台,但是处于 staging 状态。我们还需要登录管理后台去后续的操作:

管理后台:s01.oss.sonatype.org/

Staging 是个什么状态呢?它相当于开启了一个事务,在这个事务周期中,你可以发布多个包,或者发布多次覆盖之前的发布。 你需要主动结束这个事务才能算是发布成功,当然当你结束这个事务时,Sonatype 会检查你上传的包的信息是否完整:是否有签名文件?pom 的信息是否有遗漏?

image.png

点击 close 结束当前这次事务:

image.png

点击 close 后, 我们可以通过下方的 activity 查看进度,你可以看到,它会做很多的校验工作,如果失败的话,也是通过它看具体信息,然后修正、重新发布、再次尝试 close。如果成功 close, 你可以看到上方的 Relase 按钮就变成可点击状态了, 之后点击就是完成真正的 release 了。

官方文档:central.sonatype.org/publish/rel…

之后就可以通过 MavenCentral 访问了,就可以继续过“一杯茶,一包烟,几个间距调一天的生活”了。

猜你喜欢

转载自juejin.im/post/7074773046707355661