Android库发布到Maven Central超详细攻略

掘金迁移地址

前言

最近写了一个自动化打包上传到蒲公英等三方平台,在飞书的群机器人中发送消息,解放双手,方便测试人员下载的项目,想发布到远程服务器供方便调用,但是记得JCenter已经宣布在2020年5月1日,停止新的库的提交(只能使用,不能再提交),在2022年2月21号以前,连库的解析服务也停止,所以,尝试将打包库发布到maven central上。

需要哪些工具

1: sonatype

2: nexus

3: Github

第一步 · Sonatype Jira配置

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

注册

首先需要到issues.sonatype.org注册账号,界面如图:

04E02CD9-6E13-44CC-9CC7-B5B02EC91430.png

填写邮箱、用户名、密码信息即可注册成功

注意:邮箱很重要,建议是你常用的邮箱,以便及时收到 Sonatypeissue 中的答复。

注册成功后再次回到登录页面,填写刚才注册的用户名和密码即可在Sonatype完成登陆,如下图。

4A0B9BBB-8A8C-4FAA-ADDF-D5D81D6CB15E.png

注册需要填写邮箱(重要,请填写真实的邮箱)、名字、用户名(重要,用于登录)、密码(需要含符号、英文和数字的复杂密码),和验证码完成注册。

创建问题

按照图中所示,我们创建一个问题。

79104820-340E-47C6-B82D-53447DCD7C3A.png

该步骤中唯一需要注意的地方就是 Group Id,填写错sonatype工作人员会给你提一个issue,有两种情况:

  • 无网站域名:使用 github 的子域名 io.github.username,比如我的 github 账号名是 Eegets,那么可以填写 io.github.eegets
  • 有网站域名:可以填写个人或公司域名,比如:com.eegets,另外,还需要在 DNS 配置中配置一个 TXT 记录来验证域名所有权,具体请看:central.sonatype.org/pages/produ…

创建以后,会有管理员处理你的这个issue,等待管理员回复你的issue,一般需要设置一步:在github上创建一个空的仓库,我的空仓库名为:OSSRH-75861。第二就是是否要修改groupId。

管理员回复我的如下图:

DD293434-2C4D-41D5-9758-212923BEBB12.png

当该问题状态变为已解决,则证明我们sonatype项目已经完成了申请,如下图

5E17FDBF-A9A3-442D-8A57-FBF1AA6AE47E.png

第二步·Gradle配置

接下来打开你的项目,在项目根目录创建一个后缀为.gradle的文件「我创建的文件名为:publish-mavencentral.gradle」,如下:

该文件是通用的文件配置,直接copy修改里边的一些配置项即可

apply plugin: 'maven-publish'
apply plugin: 'signing'

task androidSourcesJar(type: Jar) {
    classifier = 'sources'

    exclude "**/R.class"  //排除`R.class`
    exclude "**/BuildConfig.class"  //排除`BuildConfig.class`
}
//第 1 处
ext["signing.keyId"] = '' //签名的密钥后8位
ext["signing.password"] = ''  //签名设置的密码
ext["signing.secretKeyRingFile"] = '' //生成的secring.gpg文件目录
ext["ossrhUsername"] = ''  //sonatype用户名
ext["ossrhPassword"] = ''  //sonatype密码

File secretPropsFile = project.rootProject.file('local.properties')
if (secretPropsFile.exists()) {
    println "Found secret props file, loading props"
    Properties p = new Properties()
    p.load(new FileInputStream(secretPropsFile))
    p.each { name, value ->
        ext[name] = value
    }
} else {
    println "No props file, loading env vars"
}
publishing {
    publications {
        release(MavenPublication) {
            println("publish-maven Log-------> PUBLISH_GROUP_ID: $PUBLISH_GROUP_ID; PUBLISH_ARTIFACT_ID: $PUBLISH_ARTIFACT_ID; PUBLISH_VERSION: $PUBLISH_VERSION")
            // The coordinates of the library, being set from variables that
            
            //第 2 处
            groupId PUBLISH_GROUP_ID
            artifactId PUBLISH_ARTIFACT_ID
            version PUBLISH_VERSION

            // Two artifacts, the `aar` and the sources
            artifact("../plugin/com/eegets/plugin/upload/${PUBLISH_VERSION}/upload-${PUBLISH_VERSION}.jar")
            artifact androidSourcesJar

            // Self-explanatory metadata for the most part
            pom {        
                //第 3 处
                name = PUBLISH_ARTIFACT_ID
                description = '自动化打包上传到蒲公英等三方平台,解放双手,方便测试人员下载' //项目描述
                // If your project has a dedicated site, use its URL here
                url = 'https://github.com/eegets/UploadApkPlugin' //项目github链接
                licenses {
                    license {
                        //协议类型,一般默认Apache License2.0的话不用改:
                        name = 'The Apache License, Version 2.0'
                        url = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
                    }
                }
                developers {
                    developer {
                        //第 4 处
                        id = 'xxx' //你的sonatype用户名
                        name = 'xxx' //你的sonatype用户名
                        email = 'xxx' //你的sonatype注册邮箱
                    }
                }
                // Version control info, if you're using GitHub, follow the format as seen here
                scm {
                    //第 5 处
                    //修改成你的Git地址:
                    connection = 'scm:git@github.com:eegets/UploadApkPlugin.git'
                    developerConnection = 'scm:git@github.com:eegets/UploadApkPlugin.git'
                    //分支地址:
                    url = 'https://github.com/eegets/UploadApkPlugin/tree/master'
                }
                // A slightly hacky fix so that your POM will include any transitive dependencies
                // that your library builds upon
                withXml {
                    def dependenciesNode = asNode().appendNode('dependencies')

                    project.configurations.implementation.allDependencies.each {
                        def dependencyNode = dependenciesNode.appendNode('dependency')
                        dependencyNode.appendNode('groupId', it.group)
                        dependencyNode.appendNode('artifactId', it.name)
                        dependencyNode.appendNode('version', it.version)
                    }
                }
            }
        }
    }
    repositories {
        // The repository to publish to, Sonatype/MavenCentral
        maven {
            //第 6 处
            name = "UploadApkPlugin"
            //此处用'https://s01.oss.sonatype.org'替代'https://oss.sonatype.org',因为`https://oss.sonatype.org`会出现nexus后台无法登陆以及发布出现`Received status code 403 from server: Forbidden`问题
            def releasesRepoUrl = "https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/"
            def snapshotsRepoUrl = "https://s01.oss.sonatype.org/content/repositories/snapshots/"
            // You only need this if you want to publish snapshots, otherwise just set the URL
            // to the release repo directly
            url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl

            // The username and password we've fetched earlier
            credentials {
                username ossrhUsername
                password ossrhPassword
            }
        }
    }
}
signing {
    sign publishing.publications
}

如上述代码,我们需要配置 6

第 1 处

在项目的根目录local.properties文件中增加如下配置

#//刚才获取的秘钥后8位
signing.keyId=XXXX

#//步骤4中设置的密码
signing.password=XXXX

#//生成的secring.gpg文件目录
signing.secretKeyRingFile=/Users/xxxx/xxxx/secring.gpg

#//sonatype用户名
ossrhUsername=xxxx

#//sonatype密码
ossrhPassword=xxxx

第 2 处

在要提交的module下的build.gradle文件中,添加如下代码:

注意:此处的ext{}apply from: '../publish-mavencentral.gradle'顺序一定不能乱,必须是先ext,再apply from

ext {
    PUBLISH_ARTIFACT_ID = "uploadPlugin" //你的artifact_id,一般是module的名字
    PUBLISH_VERSION = "1.0.3"  //发布版本号
    PUBLISH_GROUP_ID = 'xxx'  //你的sonatype的group_id
}
apply from: '../publish-mavencentral.gradle'

第 3 处

publish-mavencentral.gradle配置项目描述和项目GitHub地址,如下:

name = PUBLISH_ARTIFACT_ID description = '项目描述' //项目描述

url = 'https://github.com/eegets/UploadApkPlugin' //项目github链接

第 4 处

配置sonatype的信息,如下:

id = 'xxx' //你的sonatype用户名 
name = 'xxx' //你的sonatype用户名 
email = 'xxx' //你的sonatype注册邮箱

第 5 处

配置github信息,如下:


connection = 'scm:git@github.com:eegets/UploadApkPlugin.git'  //分支地址

developerConnection = 'scm:git@github.com:eegets/UploadApkPlugin.git' //分支地址: 

url = 'https://github.com/eegets/UploadApkPlugin/tree/master'

第 6 处

配置项目名称和发布地址

name = "UploadApkPlugin" 

releasesRepoUrl = "https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/" def 

snapshotsRepoUrl = "https://s01.oss.sonatype.org/content/repositories/snapshots/"

注意:此处用https://s01.oss.sonatype.org 替代 https://oss.sonatype.org ,因为https://oss.sonatype.org会出现nexus后台无法登陆以及发布出现Received status code 403 from server: Forbidden问题

创建GPG秘钥

  1. https://www.gnupg.org/download/,从这里下载并安装GPG客户端,我的是mac,所以选择如下框中的,点击下一步安装即可。如下图
E56F12AC-2F2E-4AB3-9DDE-508108C35DEA.png
  1. 安装成功后,打开终端,在命令行中执行命令gpg --full-gen-key,注意,一定要在命令行中执行命令,不能在客户端界面做。
image.png
  1. 如上图,加密方式选择RSA and RSA,长度输入4096,过期时间直接回车不用管,然后输入一个user ID并且提供一个邮箱,我直接用的我sonatype的用户名和邮箱。最后一步输入'O',表示OK。

  2. 之后会弹出一个对话框,让输入密码。

image.png

gpg: revocation certificate stored as '~/.gnupg/openpgp-revocs.d/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXE478F7CC.rev' public and secret key created and signed.

pub rsa4096 2021-03-22 [SC] XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXEE478F7CC uid boybeak boybeak@gmail.com sub rsa4096 2021-03-22 [E] ```

这会为你在~/.gnupg/openpgp-revocs.d/目录下创建一个.rev文件,记住pub的末尾8位。

  1. 接下来创建secring.gpg文件,命令行执行gpg --export-secret-keys -o secring.gpg,这会要求你输入在步骤4中设置的密码,在你项目根目录下会出现secring.gpg文件。因我我是在当前项目目录下执行,所以secring.gpg文件生成在项目根目录下。如下图:
  1. 回到gpg客户端,选择我们刚生成的秘钥条目,右键,选择Send Public Key to Key Server。记住后边八位,如下图圈起来的八位:

做完以上gpg的配置之后我们就可以完善我们上边第 1 步了。

local.properties配置

#//刚才获取的秘钥后8位
signing.keyId=XXXX

#//步骤4中设置的密码
signing.password=XXXX

#//生成的secring.gpg文件目录
signing.secretKeyRingFile=/Users/xxxx/xxxx/secring.gpg

#//sonatype用户名
ossrhUsername=xxxx

#//sonatype密码
ossrhPassword=xxxx

执行打包和上传

设置完这些后,在AndroidStudio右侧的gradle tasks中找到你想提交的module,先后执行以下两个任务。

image.png

按照上述这么多配置之后,不出意外打包和上传都将成功[如有编译失败,请再翻翻上述文章]

上传成功后,打开Nexus Repository Manager,登录你的sonatype账号,在左侧Staging Repositories页面找到你的group id,选中,点击上边的close,等待几分钟十几分钟后刷新状态,等其状态变为closed后,再点击Release,则所有人都用使用你的库了。

备注: 最好是登陆https://s01.oss.sonatype.orghttps://oss.sonatype.org亲测无法登陆,原因请看:https://issues.sonatype.org/browse/OSSRH-65499

image.png

接下来,需要等待一段时间,待Activity选项卡中出现对号的“Repository closed”即完成准备,然后点击Release按钮发布到MavenCentral,等待几个小时后可以在 search.maven.org/ 查询发布结果。

Missing: no javadoc jar found in folder解决办法

按照上述方式我们就算完成了maven的打包和发布,如果在nexus最后执行Close的时候出现Close 失败,并且报:Missing: no javadoc jar found in folder解决办法,请移步我写的另外一篇文章 Missing: no javadoc jar found in folder解决办法,关于 Missing: no javadoc jar found in folder解决办法的解决办法

注意以上几处引用的需要注意的地方,这些注意的地方可以祝你避坑!!!

源码

https://github.com/eegets/UploadApkPlugin

参考资料

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

推荐阅读更多精彩内容