【记】(已失效)发布AAR包至Maven Central

1,573 阅读8分钟

注意! 目前issues.sonatype.org官方已停用,该教程已过期。发布教程请参考官网说明文档 :central.sonatype.org/

最近开发了一个Android串口库LSerialPort。想着既然做成开源库,不如试着把库上传到Maven Central,一来是方便集成使用,二来是以前开发一直通过maven下载引入别人的开源库使用,但是从没了解过如何把库上传到maven。现在正好通过开发LSerialPort的契机学习一下,同时也写个笔记记录下整个上传流程。

1.注册Sonatype账号

Maven Central是由Sonatype运营的,那么首先需要去注册一个Sonatype的账号并获得仓库使用许可。

注册地址issues.sonatype.org/

image.png

4588210ff905aa607558ce589851b7f.png


2.提交Issue,注册Group Id

因为项目发布到Maven Central需要一个已经在Sonatype 开源社区托管服务(Sonatype OSSRH Open Source Project Repository Hosting) 上注册过GroupID。这里需要提交New Project Issue来注册我们自己的GroupID

创建Project Issue

登录账号以后进入主页面,点击【新建】创建Issue

94f7306139a2daa993873dde668d61f.png

选择【New Project issue】创建一个Project Issue

70b91cab5fbb624becc8e73c9807718.png

填写信息并提交Issue

创建Project需要注意Group Id的填写。如果你没有自己的网站, 那么一般是推荐用Github的Id注册为Group Id。

填写格式: io.github.你的github用户名

比如下图例子中的io.github.RedRackham-R。全部填写完毕后点击下方按钮提交即可。

如果有你自己的域名,需要按照官方的要求,在DNS配置配置一个TXT记录指向你的Github地址来完 验证。

关于Group Id填写官方说明:central.sonatype.org/publish/req…

deec3c84cbe6bb3b214e44591302d16.png

e7376317b3ef7271f6cc7c8adb22289.png

根据Issue处理回复进行操作

提交Issue后,官方一般会在十分钟内会有回复。我们根据回复的要求进行操作即可。
在活动日志-注释中我们可以看到官方给我们的回复内容。

下面例子中官方要求我们在github用刚才提交的id用户创建一个名为OSSRH-91342的公开仓库, 然后把Issue状态设置为Open,操作完后等待官方进行认证。

不同的托管仓库账号创建Group Id(比如GitLab,Gitee等)基本上操作都大同小异, 如果是个人网站,则按具体照要求配置。

c3a28dda360893dc19c03eceb65cb3d.png

cb19c38e970a7977d80e05b70d7912c.png

完成Group Id注册

看到下图的提示,说明Group Id已经创建成功。到此我们已经能够上传库到托管平台。当我们提交的库 在平台验证通过后,托管平台会把库自动同步到Maven Central。

上传发布服务:s01.oss.sonatype.org

21a6581b24a7d12fe076764900f472e.png

3.发布GPG密钥

因为Sonatype对安全性有要求,我们必须发布自己的密钥到公共服务器上。当我们上传工程到Maven时,Maven会拿我们上传的秘钥信息去和服务器上发布的密钥做验证,确保这个上传库是我们本人发布的。
(GPG密钥说明:www.gnupg.org/index.html)

下面是GPG密钥从下载创建到发布的教程。

下载GPG

GPG下载地址gnupg.org/download/in…

48aa96478d89c1a3eb0feaf355fcfd4.png

5bed0308f60b96d78710b79bc71c325.png

使用命令 创建注册并且发布密钥

创建密钥

gpg --full-gen-key

9d3e4f15294e32a8ff44f53056dcba4.png

ae739547fbd1e27c5c186835255fb83.png

e9689fe9572e6e6dd03c6cbc5c5e5e6.png

查看密钥

gpg --list-keys

主要是查看密钥是否创建成功

060ef5dbd520d70123281764247b76d.png

导出密钥对

主要还是导出私钥,用于后面上传Maven使用。

//1.查看密钥,复制【密钥ID】
gpg --list-keys

//2.导出私钥,建议导出的密钥文件名带密钥ID后八位,方便管理。
gpg --export-secret-keys -o -k 密钥ID 文件名.gpg

如:gpg --export-secret-keys -o -k D4F5B628D6FE5F08F9C4E089C2A0C987DC3F6FD4 secret_DC3F6FD4.gpg

c73a4907cfc7a08140aa993b07a6e22.png

8224795ddd61a5e91a1ebb8289cdebb.png

发布密钥

发布密钥主要按照下面几个步骤走:

//1.查看密钥,复制【密钥ID】
gpg --list-keys

//2.上传发布密钥到公共服务器
gpg --keyserver hkp://keyserver.ubuntu.com:11371 --send-keys 密钥ID

如:gpg --keyserver hkp://keyserver.ubuntu.com:11371 --send-keys D4F5B628D6FE5F08F9C4E089C2A0C987DC3F6FD4

//3.查询密钥是否上传成功
gpg --keyserver hkp://keyserver.ubuntu.com:11371 --recv-keys 密钥ID

如:gpg --keyserver hkp://keyserver.ubuntu.com:11371 --recv-keys D4F5B628D6FE5F08F9C4E089C2A0C987DC3F6FD4

注意!
1.如果 【查询】 时返回【No Data】,可能是还没同步完成,等一会再查应该就会有了。
2.如果【上传发布】时返回【No keyserver available】,可以用下面的服务器上传,只要有一个上传就可以了。

gpg --keyserver hkp://keyserver.ubuntu.com:11371 --send-keys 密钥ID
gpg --keyserver hkp://keys.openpgp.org:11371 --send-keys 密钥ID
gpg --keyserver hkp://pool.sks-keyservers.net:11371 --send-keys 密钥ID

0ec92b7145d999a429939eaac5485af.png

到此我们就已经完成了密钥的发布。

使用Kleopatra 创建注册并且发布密钥

创建秘钥

Win下安装完成后打开Kleopatra然后按照下面步骤操作:

选择右上角 【文件】->New OpenGPG key pair

97e78ae6675ca8536d70a647c331203.png

填写密钥信息:
1.填写 【名字】 以及 【电子邮件地址】,并且勾选 【使用密码句保护生成的密钥】
2.点击 【高级设置】
3.选择秘钥类型RSA,并且修改大小为4096 byte (可选)
4.取消勾选秘钥结束日期 (可选)
5.选择ok开始生成

58ea230c5f4e2b590546f41b7b4c073.png

填写密码。(注意,一定要记好,后续上传库也需要这个密码)

5a5729fbaf7ae0f9c0516a60655c05a.png

完成创建

c6bd910a58f5c13d947796e73038588.png

创建撤销证书

由于发布秘钥到公共服务器后无法删除,如果不想继续使用证书可以使用【吊销证书】, 声明这个秘钥不再使用。下面我们来创建吊销证书。

d03f50f014540e09ec75be40c056d34.png

be73e136b0e4016855c3935797d04f2.png

0b570e825dc94a5fb7b0995eb764413.png

导出密钥对

选择我们刚才创建的秘钥,分别导出【公钥】和【私钥】进行备份。

默认格式为:用户名_0x密钥ID后八位_密钥类型.asc

注意!这里保存时的文件格式后缀要做修改,把 【.asc】 修改为 【.gpg】

修改后:用户名_0x密钥ID后八位_密钥类型.gpg

c2967997869fb18a717251eb34f92c9.png

5e598296e43273c285742ccfc2e3357.png

72068b8267fe02d91ba76275ec01044.png

发布秘钥

952b46b7bd2471a87366d9e051f72ad.png

bacdf89247f73247c946304f569664e.png

到此我们就已经完成了密钥的发布。

4.发布AAR包至Maven Central

配置local.properties

打开工程目录中的local.properties,增加以下参数声明。

7da27b5d36e505498f201681a694598.png local.properties

#【秘钥ID】的后8位
signing.keyId=xxx
# 创建gpg秘钥时设置的密码
signing.password=xxx
# 导出的私钥文件目录
signing.secretKeyRingFile=xxx
# Sonatype账号
ossrhUsername=xxx
# Sonatype密码
ossrhPassword=xxx
# 上传者的名称(任意填写)
PUBLISH_NAME=xxx
# 上传的Group Id,填写注册好的Group Id  (重要!!!)
PUBLISH_GROUP_ID=xxx
# 上传者的邮箱(最好是用你注册Sonatype的邮箱)
PUBLISH_EMAIL=xxx

这是一个例子

signing.keyId=DC3F6FD4
signing.password=123456
signing.secretKeyRingFile=secret_DC3F6FD4.gpg
ossrhUsername=abc
ossrhPassword=123
PUBLISH_NAME=RedRackham
PUBLISH_GROUP_ID=io.github.RedRackham-R
PUBLISH_EMAIL=409875745@qq.com

配置publish

上传发布我们这里使用【maven-publish】工具。

打开工程Modulebuild.gradle,进行配置。

这是我的开源库LSerialPort配置的build.gradle,给提供参考。

下面是build.gradle配合详细说明:

plugins {
    ...
  //添加publish
  id 'maven-publish'
  //添加signing
  id 'signing'
}

android {...}

dependencies{...}

var signingKeyId = ""//签名的密钥后8位
var signingPassword = ""//签名设置的密码
var secretKeyRingFile = ""//生成的secring.gpg文件目录
var ossrhUsername = ""//sonatype用户名
var ossrhPassword = "" //sonatype密码
var PUBLISH_NAME = ""//推送用户名
var PUBLISH_GROUP_ID = ""//groupid
var PUBLISH_EMAIL = ""//email

//这里加载我们配置local.properties的参数
var localProperties = project.rootProject.file("local.properties")
if (localProperties.exists()) {
    Properties properties = new Properties()
    properties.load(project.rootProject.file('local.properties').newDataInputStream())
    signingKeyId = properties.getProperty("signing.keyId")
    signingPassword = properties.getProperty("signing.password")
    secretKeyRingFile = properties.getProperty("signing.secretKeyRingFile")
    ossrhUsername = properties.getProperty("ossrhUsername")
    ossrhPassword = properties.getProperty("ossrhPassword")
    PUBLISH_NAME = properties.getProperty("PUBLISH_NAME")
    PUBLISH_GROUP_ID = properties.getProperty("PUBLISH_GROUP_ID")
    PUBLISH_EMAIL = properties.getProperty("PUBLISH_EMAIL")
} else {
    println("No props file, loading env vars")
}

afterEvaluate {
    publishing {
        publications {
            uploadToMavenCentral(MavenPublication) {
                /* groupId:注册的Sonatype Group Id
                 * artifactId:项目唯一标识,一般是工程名
                 * version:库的版本号
                 * artifact:工程项目,这里是上传aar包,所以指向aar包的生成地址
                 *
                 * gradle引入:implementation ‘groupId:artifactId:version’
                 
                 * 如:implementation 'io.github.RedRackham-R:LSerialPort:1.0.0-debug'
                 *
                 * */
                groupId = PUBLISH_GROUP_ID
                artifactId = "LSerialPort"
                version = "1.0.0"
                artifact("$buildDir/outputs/aar/${project.getName()}-${mVersionName}-debug.aar")
                pom {
                    //项目名 (任意填)
                    name.value("LSerialPort")
                    //项目介绍 (任意填)
                    description.value("LSerialPort A C++ implementation of multi-threaded management read and write serial port Android library")
                    //项目地址
                    url.value("https://github.com/RedRackham-R/LSerialPort")
                    //协议类型 默认是Apache License,你想要换也可以改成别的
                    licenses {
                        license {
                            name = 'The MIT License'
                            url = "https://github.com/RedRackham-R/LSerialPort/blob/master/LICENSE"
                        }
                    }
                    //开发者信息,id,名字,邮箱之类的
                    developers {
                        developer {
                            id.value(PUBLISH_NAME)
                            name.value(PUBLISH_NAME)
                            email.value(PUBLISH_EMAIL)
                        }
                    }
                    //版本控制信息,下面是github格式参考,把地址替换成自己的
                    scm {
                        //git地址
                        connection.value("scm:git@github.com/RedRackham-R/LSerialPort.git")
                        developerConnection.value("scm:git@github.com/RedRackham-R/LSerialPort.git")
                        //工程url地址
                        url.value("https://github.com/RedRackham-R/LSerialPort")
                    }
                }
            }
        }
        //提交的仓库地址
        repositories {
            maven {
                url = uri("https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/")
                credentials {
                    //你的sonatype账号
                    username = ossrhUsername
                    //你的sonatype密码
                    password = ossrhPassword
                }
            }
        }
    }
}
//signing的配置数据在编译后必须是project的properties,即在全局可识别。
//这里的配置的数据可供整个Project全局访问。
gradle.taskGraph.whenReady {
    allprojects {
        ext["signing.keyId"] = signingKeyId
        ext["signing.password"] = signingPassword
        ext["signing.secretKeyRingFile"] = secretKeyRingFile
    }
}
//这里是使用gpg秘钥进行签名
signing {
    sign(publishing.publications)
}

上传AAR到临时仓库

./gradlew clean
./gradlew build
./gradlew publish

工程内依次执行上面命令等待上传即可。

如果上传出现错误。我们可以在命令后面加上【--scan】查看具体错误,以便我们排查。

如:./gradlew publish --scan

image.png

从临时仓库发布到公共仓库

首先,我们打开仓库管理后台 s01.oss.sonatype.org/#welcome 然后登录我们的【Sonatype账号】,登录以后就能操作临时仓库了。

image.png

然后点击【临时仓库】,在这里我们可以查看仓库内已经上传的包信息

fc466b658687ddce85cd59c4387ec87.png

确认上传的包内容没问题后,【勾选工程】,然后点击【Close】关闭。

如果无法关闭是的话可能是上传的包有问题,这时候可以点击下方的【Activity】查看是哪一步错了。

要删除包的话,点击【Drop

a1335c6f5d93a591e217d30358a6f5f.png 7bf2974aaf5427cc4fa7237bce03bb3.png

关闭后点击【Refresh】查看更新状态,如果状态【Status】是【closed】的话,说明关闭成功。这时候我们再点击【Release】提交。提交完成以后,大概等一两小时左右就能在公共库查询到我们发布的库了。

(不一定这么久,我提交LSerialPort等10分钟左右就完成发布)

如果提交有问题,也可点击【Activity】查看错误。

15b907489f5669afda7c9d364f74043.png

2a64de565c55a336af427c972589b58.png

查看-引用提交的AAR库

由于提交发布到公共仓库需要一定时间,【请等待至少十分钟】再去公共库查询。

查询地址:central.sonatype.com/


63e94e00afe4a9348c76827a89f014b.png

0a194dd17e507abd0ac570481d8e5a6.png

到此,我们完成了一套完整Maven Central发布aar包的流程