一、前言

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

二、注册账号并登录账号

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

三、创建工单

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

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

  • 项目: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/ 搜索到,大概需要等半天左右吧(没太注意)。

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



Android技术   我的开源库      maven sonatype

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!