向 MavenCentral 丢个包

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

以前 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

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

1aac47556042832e5d0036dd90adbf3.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 的信息是否有遗漏?

9d357668bd4fb7001203bd1c1346f3b.png

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

6ad814cb39481a05458e7841f06d9ec.png

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


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


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

目录
相关文章
|
Java Apache Maven
Apache Maven、Maven仓库、Jcenter仓库
版权声明:本文为sydMobile原创文章,转载请务必注明出处! https://blog.csdn.net/sydMobile/article/details/78460169 文章最早发布于我的微信公众号 Android_De_Home 中,欢迎大家扫描下面二维码关注微信公众获取更多知识内容。
2541 0
|
12月前
|
Java 关系型数据库 MySQL
Maven的使用及安装
Maven的使用及安装
95 0
|
12月前
|
Java Maven
18Maven - Maven私服介绍
18Maven - Maven私服介绍
73 0
|
存储 缓存 安全
【Maven二】——maven仓库
【Maven二】——maven仓库
558 0
|
Java Linux Maven
Maven 安装
Maven 安装
|
存储 安全 IDE
AAPT: error: reso 1. mavenCentral():2. jcenter():3. mavenLocal()
AAPT: error: reso 1. mavenCentral():2. jcenter():3. mavenLocal()
122 0
AAPT: error: reso 1. mavenCentral():2. jcenter():3. mavenLocal()
|
Java Apache Maven
安装maven
安装maven
111 0
|
存储 安全 Java
【Maven系列1】很简单的Maven仓库
开始以为Maven需要掌握的东西很少,结果发现还是有些内容的。Maven实操的内容比较多,我就先专门通过本篇文章,对Maven进行简单介绍,然后重点讲解Maven仓库相关知识。 感觉Maven相对简单,网上相关的资料也很多,那我为啥还需要专门写这个系列呢?其实主要还是记录自己的学习轨迹,便于后续查询学习内容,仅此而已!
350 0
【Maven系列1】很简单的Maven仓库
|
Java Maven
maven 打包jar到maven私服
maven 打包jar到maven私服
maven 打包jar到maven私服
|
Java Maven 容器
build.gradle里repositories的mavenCentral实现原理解析
build.gradle里repositories的mavenCentral实现原理解析
267 0
build.gradle里repositories的mavenCentral实现原理解析