使用过 Android Studio 的同学应该都会对 Gradle 这个强大的构建系统留下了深刻的印象,Gradle 可以方便地集成各种开源库,又能编写自动化脚本处理任务,大有取代 Maven 之势。 业余时间我有在维护一个开源项目,也收到了几个 PR 要求发布到 Maven Central 以供 Gradle 使用,所以自己摸索着找了些文章,终于把项目发布上去了。
大概有以下 5 个步骤:
- 到 issues.sonatype.org 注册个帐号,申请发布权限
- 编写 Gradle 自动化发布脚本
- 下载 GPGTools,创建 Signing Key
- 执行 Gradle 发布脚本
- 申请激活 Maven Central Sync 进程
其中***步和第五步都需要人工审核,两个工作日(美帝时间)内会有答复。
1. 申请 Maven Central 发布权限
将你的项目主要信息放到 issue 里面就好了,其中 Group Id 要谨慎填写,申请通过后,你只能在你的 Group Id下发布项目。
创建完 issue 后,静候几天,通过了就会给你发邮件。
2. 编写 Gradle 发布脚本
感谢 Chris Banes 大神提供的脚本,稍作修改,弄了一个我自己的版本。
https://github.com/SpecialCyCi/AndroidResideMenu/blob/master/maven_push.gradle
将上面的脚本放到项目的根目录下,然后到开源库所在的 module 目录,添加以下代码 build.gradle :
apply from: '../maven_push.gradle'
修改项目根目录下的gradle.properties,添加项目的信息:
VERSION_NAME=1.6 VERSION_CODE=8 POM_GROUP_ID=com.specyci POM_DESCRIPTION=.... POM_URL=https://github.com/SpecialCyCi/AndroidResideMenu POM_SCM_URL=https://github.com/SpecialCyCi/AndroidResideMenu POM_SCM_CONNECTION=scm:git@github.com:SpecialCyCi/AndroidResideMenu.git POM_SCM_DEV_CONNECTION=scm:git@github.com:SpecialCyCi/AndroidResideMenu.git POM_LICENCE_NAME=The MIT License (MIT) POM_LICENCE_URL=https://raw.githubusercontent.com/SpecialCyCi/AndroidResideMenu/master/LICENSE POM_LICENCE_DIST=repo POM_DEVELOPER_ID=specialcyci POM_DEVELOPER_NAME=Special Leung POM_INCEPTION_YEAR=2013
***到开源库所在的 module 目录,添加编译信息到 gradle.properties :
- POM_NAME=AndroidResideMenu
- POM_ARTIFACT_ID=residemenu
- POM_PACKAGING=aar
3. 下载 GPGTools,创建 Signing Key
Signing Key 可以看作是作者信息的一个签名,签名分为 public 和 private,其中 public key 要上传到keyservers.net 储存。
先在本地命令行生成 Signing Key :
➜ AndroidResideMenu git:(master) gpg --gen-key Please select what kind of key you want: (1) RSA and RSA (default) (2) DSA and Elgamal (3) DSA (sign only) (4) RSA (sign only) Your selection? 1 RSA keys may be between 1024 and 8192 bits long. What keysize do you want? (2048) Requested keysize is 2048 bits Please specify how long the key should be valid. 0 = key does not expire <n> = key expires in n days <n>w = key expires in n weeks <n>m = key expires in n months <n>y = key expires in n years Key is valid for? (0) 0 Key does not expire at all Is this correct? (y/N) y GnuPG needs to construct a user ID to identify your key. Real name: Special Leung(Testing) Email address: specialcyci+test@gmail.com Comment: This is just a testing key. You selected this USER-ID: "Special Leung(Testing) (This is just a testing key.) <specialcyci+test@gmail.com>" Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O You need a Passphrase to protect your secret key. ... pub 2048R/8C1761A2 2015-01-24 Key fingerprint = xxx uid [ultimate] Special Leung(Testing) (This is just a testing key.) <specialcyci+test@gmail.com> sub 2048R/E32D1186 2015-01-24
然后把 public key 上传到 keyservers.net :
$ gpg --keyserver hkp://pool.sks-keyservers.net --send-keys 8C1761A2 gpg: sending key 8C1761A2 to hkp server pool.sks-keyservers.net
***将 Signing Key 的信息填充到 ~/.gradle/gradle.properties :
# 查看 key 信息 ➜ ~ gpg --list-secret-keys /Users/special/.gnupg/secring.gpg # <- key 目录 --------------------------------- sec 2048R/8C1761A2 2015-01-24 # <- 8C1761A2 是 key id uid Special Lenung(Testing) (This is just a testing key.) <specialcyci+test@gmail.com> ssb 2048R/E32D1186 2015-01-24
# ~/.gradle/gradle.properties signing.keyId=8C1761A2 signing.password=password signing.secretKeyRingFile=/Users/special/.gnupg/secring.gpg nexusUsername=username nexusPassword=password
4. 执行 Gradle 发布脚本
%GRADLE_HOME%/bin/gradle uploadArchives
如果版本名含有 SNAPSHOT 字串,项目将会上传到 snapshots 节点;如果要发布到 Maven Central 的正式库,去掉版本名中的 SNAPSHOT 就可以,SNAPSHOT 版本不需要进行第五步 Central Sync。
Snapshots 节点:https://oss.sonatype.org/content/repositories/snapshots
5. 激活 Maven Central Sync 进程
第 4 步成功了的话,就可以在 oss.sonatype.org (https://oss.sonatype.org/) 的 stagingRepositories 看到项目了,然后按下「Close」,准备发布项目。
成功 Close 了项目后,到***步的 issue 地址,发个评论让工作人员给你开启 Sync 进程,这个一般一个工作日就有答复。
在工作人员回复可以之后,执行「Release」操作,没啥意外的话,两小时后就可以在 search.maven.org 搜到你的项目了。
6. 结语
总的来说,发布还是挺方便的,人工审核可能会浪费点时间,偶尔还可能遇到些问题,不过 sonatype 还是很专业的,将你遇到的问题告诉他们之后,都可以得到一个有效的解决办法。
不过最近 Android Studio 把 jCentral 作为默认的节点了,也许下次就得折腾 jCentral 了。