给Android开发者的MavenCentral发布指南

一、前言

  1. 本文讲解如何将Android开源库发布到MavenCentral上,属于保姆级教程
  2. MavenCentral会检查开源库包路径对应的域名是否属于你,因此你需要拥有一个域名。比如你开源库的包路径为:com.hurryyu.mylib,则你必须是域名hurryyu.com的拥有者
  3. 关于2,域名可以自购,也可以用GithubPage等免费方案,如username.github.io
  4. 关于域名,只会在第一次发布时验证域名是否属于你,后续将不再需要
  5. 本文将基于自购域名进行讲解

二、注册账号并登录账号

浏览器访问https://issues.sonatype.org/
注册(Sign up)一个账号,然后登录。

三、创建工单

登录后,你可以在网页左上方的菜单栏中看到新建的按钮,如下图所示:

image

点击后,需要填写一些信息:

  • 项目:Community Support - Open Source Project Repository Hosting (OSSRH)
  • 问题类型:New Project
  • 概要:android lib(或者你也可以填写其它适合的概要信息)
  • 描述(非必填):不管
  • 附件(非必填):不管
  • Group Id:非常重要,建议填写你自己的顶级域名,例如:hurryyu.com而不是www.hurryyu.com
  • Project URL:随便填一个你项目的github仓库地址即可
  • SCM url:将上面那个github仓库地址后面加上.git即可
  • Username(s)(非必填):不管
  • Already Synced to Central:默认No即可

参考如图:

image-20211209155809212

Group Id答疑

这里我需要特别说明一下Group Id,强烈建议你填写顶级域名。在Maven中定位一个库,是通过GroupIdArtifactId共同确定的,如果需要精确到版本号,则还需要配合Version来确定。

implementation("com.squareup.okhttp3:okhttp:4.9.3")这里的GroupIdcom.squareup.okhttp3ArtifactIdokhttpVersion4.9.3,故GroupId:ArtifactId:Version三坨信息通过冒号分隔。

那上面的GroupId填了顶级域名,是不是意味着我的GroupId就固定死了,只能是这个顶级域名呢?

比如我填写的是com.hurryyu是不是意味着以后我的GroupId只能是com.hurryyu了呢?假如我想要的是com.hurryyu.android:libname:1.0.0这样就不行了?

答案是否定的,只要你填的是顶级域名,验证通过后,你可以无限制的扩展出二级、三级域名,比如你填写的GroupIdcom.hurryyu,只要验证通过,那么后续你上传开源库的时候,GroupId可以指定但不限于下面任意一个:

  • com.hurryyu
  • com.hurryyu.android
  • com.hurryyu.nice.lib
  • com.hurryyu.hehe

四、验证域名

提交工单后,进入到工单页面,稍等一段时间,你会收到工作人员的回复:

image-20211209162231707

意思是你需要给域名添加一条TXT解析,内容为工单编号:

image-20211209162511539

完成后你需要回复这个工单,告诉工作人员你已经添加了解析记录,请他们继续接下来的验证工作,记得用英文回复,提供一个模板:I have already finished it.

image-20211209162705636

稍等一段时间,如果你收到了如下回复,表示已经通过了验证。这里请留意一下s01.oss.sonatype.org,等下还需要访问这个地址进行操作。

五、GunPG创建密钥

Windows用户访问https://www.gnupg.org/download/下载安装

Linux用户可用命令安装sudo apt install gnupg

Mac用户可用HomeBrew安装brew install gpg

安装完成后,控制台输入gpg --full-generate-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)
  (14) Existing key from card
Your selection? 1

输入1(选择RSA and RSA (default))

第二步:

RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (3072)

直接回车(默认3072)

第三步:

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)

直接回车

第四步:

Key does not expire at all
Is this correct? (y/N) y

输入y,回车

第五步:

GnuPG needs to construct a user ID to identify your key.

Real name:
Email address:
Comment:

输入你的名字,回车;输入你的邮箱,回车。接下来的Comment不用写,直接回车

第六步:

You selected this USER-ID:
    "HurryYu <11111@qq.com>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o

输入o,回车

第七步:

设置密钥的密码

六、上传公钥&导出私钥

上传公钥

至此,我们就完成了密钥的创建。你将得到如下信息:

image-20211209175829568

这里请务必记录第二行的后八位,以此图为例是03C831C6。接下来,我们需要将公钥上传到GPG服务器:

gpg --keyserver keyserver.ubuntu.com --send-keys 03C831C6

请将上面命令最后8位替换为你自己的。

现在我们可以验证一下是否真的上传成功了:

gpg --keyserver keyserver.ubuntu.com --recv-keys 03C831C6

同样需要将后8为替换为你自己的,如果得到下图结果,则上传成功:

image-20211209180849920

导出私钥

使用命令导出私钥:

gpg --export-secret-keys  -o C:\secring.gpg

请替换C:\secring.gpg为你自己想要保存的路径。私钥稍后在发布开源库的时候需要用到,请妥善保管。

七、发布开源库

在项目根目录的build.gradle中添加如下代码:

buildscript { 
    // ...
    dependencies {
        // ...
        classpath 'com.vanniktech:gradle-maven-publish-plugin:0.18.0'
    }
}

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

这里其实是用的一个Gradle插件,插件的主页是:https://github.com/vanniktech/gradle-maven-publish-plugin

接着,在要发布的开源库所在的模块build.gradle最后一行添加apply plugin: "com.vanniktech.maven.publish"Sync一下,插件就集成进来了,接下来需要按要求编写一些配置信息。

打开项目根目录下的gradle.properties文件,在里面追加以下内容:

GROUP=com.hurryyu.android
POM_ARTIFACT_ID=cornerlayout
VERSION_NAME=1.2

POM_NAME=CornerLayout
POM_DESCRIPTION=给任意View/ViewGroup边角加上横幅.
POM_INCEPTION_YEAR=2020
POM_URL=https://github.com/HurryYU/CornerLayout

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/HurryYU/CornerLayout
POM_SCM_CONNECTION=scm:git:git://github.com/HurryYU/CornerLayout.git
POM_SCM_DEV_CONNECTION=scm:git:ssh://git@github.com/HurryYU/CornerLayout.git

POM_DEVELOPER_ID=hurryyu
POM_DEVELOPER_NAME=Zihao Yu
POM_DEVELOPER_URL=https://github.com/HurryYU/

这里面的内容都是与你准备发布的这个开源库相关的,下面我解释一下部分变量的含义:

  • GROUP:这个就是开源库的GroupId,如果你对这个GROUP有疑问,比如你好奇为什么与当时提交工单时的GroupId不同?这里可以随意填写吗?等疑问,请倒回去看看Group Id答疑部分的内容。
  • POM_ARTIFACT_ID:这个就是之前说的ArtifactId,如果你对此有疑问,请倒回去看看Group Id答疑部分的内容。
  • VERSION_NAME:本次发布开源库的版本号。如果你对此有疑问,请倒回去看看Group Id答疑部分的内容。

其它的变量就不需要多解释了,根据自己的开源库填写就行。

光有这些信息是不够的,因为这个插件凭借这些信息,是没办法帮我们完成后续的发布任务的,因此我们还需要配置sonatype平台(就是最开始注册的那个)的账号和密码,以及密钥Id(之前让你记住的8位)、密钥密码(生成密钥时最后输入的那个密码)、GPG私钥文件(最后导出的那个secring.gpg)的绝对路径。

然而,以上信息属于机密,肯定不能暴露在项目文件中,更不可能将其应用在版本管理中。故我推荐一个做法,将这些信息配置再本地的Gradle的gradle.properties中,这个文件的路径根据系统的不同也有所不同,大概在{Users}/.gradle/gradle.properties,你可以根据自己的系统找一下,本文就不再多说:

signing.keyId=03C831C6
signing.password=********
signing.secretKeyRingFile=C:\\secring.gpg

mavenCentralUsername=*****
mavenCentralPassword=*****
  • signing.keyId:密钥的Id(只要后8位)
  • signing.password:密钥的密码
  • signing.secretKeyRingFile:私钥的路径
  • mavenCentralUsername:sonatype平台的登录用户名
  • mavenCentralPassword:sonatype平台的登录密码

完事了,双击即可完成发布:

image-20211209224139366

八、同步到MavenCentral

还记得工单审核成功后,管理员发给我们消息中的那个网址吗?

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

现在,我们需要访问这个地址,完成最后的操作!使用之前注册的账号登录后,在左侧可以看到Staging Repositories

image-20211210011603077

点击后,右边的列表中就会出现我们刚刚发布的开源库,我们对其做两个操作:

  1. Close

    image-20211210011836182

    需注意,Close需要一定的时间,一般1分钟以内能完成,在这期间,可以不断Refresh,直到Release按钮可点击。

  2. Release

    image-20211210012114794

完成这两步后,就触发了将我们的开源库同步到MavenCentral的动作,剩下的,就是等待一段时间了。

具体要等多久呢?这个不一定,差不多10多分钟吧,就能在https://repo1.maven.org/maven2/ 看到了,只要在这里面能看到,就表示成功了,用户也可以正常引入你的开源库了。但是想要在https://search.maven.org/ 搜索到,大概需要等半天左右吧(没太注意)。

到此本文就结束了,如果对你有帮助,别忘了一键三连哦!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,165评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,720评论 1 298
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,849评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,245评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,596评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,747评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,977评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,708评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,448评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,657评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,141评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,493评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,153评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,890评论 0 198
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,799评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,685评论 2 272

推荐阅读更多精彩内容