发布AAR至MavenCentral(推荐)本文复制自:这里这里, 作者写了好几种方法,我挑了一种作者推荐的,保存一下
2021年04月12日更
Maven Central的申请和配置是要比jForg那边的bintray麻烦得多的,由于jCenter要逐渐关闭了,所以将aar发布到mavenCetral重要性又提高了不少,如何注册上传库到Maven Central就变得非常困难了,但是还好,我把这些坑都踩完了,现在也觉得不是那么困难了,下面我来简单的介绍操作步骤
1.注册sonatype账号
与jCenter是由jForg运营,在http://bintray.com做管理一样,Maven Central是由sonatype运营的,那么首先需要去注册一个sonatype的账号并获得仓库使用许可。
你需要先前往https://issues.sonatype.org注册账号
注册需要填写邮箱(重要,请填写真实的邮箱)、名字、用户名(重要,用于登录)、密码(需要特别复杂的组合密码),和验证码完成注册。
2.创建一个issue
注册完成以后在这个页面https://issues.sonatype.org/projects点击Create创建一个创建一个问题(如上图所示),由于sonatype可能升级了,哪里的提示可以看到,这里需要点击我标注的“clicking HERE”然后进入如下图所示的界面
项目名随便就行,重点是Group ID,这里如果你没有自己的网站域名,那么一般建议按照Github填写,例如你的Github为http://github.com/qydq,那么这里可以写成com.github.qydq,
如果有你自己的域名,需要按照官方的要求,在DNS配置配置一个TXT记录指向你的Github地址来完成验证,这个比较麻烦,具体参考: https://central.sonatype.org/pages/producers.html
创建后请耐心等待官方的回复,一般10分钟,会有管理员回复你,那么就说明申请成功了,如果有任何不成功的,官方会在下方给出注释,你也可以通过注释回复官方,完成申请
看到管理员回复你的issue,他告诉你,要在你的github创建一个repo,repo的名字是这个issue的id,比如我的是OSSRH-66975,创建repo完成以后你再回复管理员,等待issues状态变为已解决。如上图
这个跟bintray操作其实很像,这样你就完成了一个issue的创建了
3.创建GPG秘钥
根据官网介绍,sonatype对安全性有要求,所以需要我们注册GPG密钥才可以发布AAR,这也是比jfrog复杂的地方
在这个网站下载GPG客服端:
https://www.gnupg.org/download/
(1)第一步:
打开在命令行中执行命令gpg --full-gen-key
,加密方式选择RSA and RSA,长度输入4096,过期时间直接回车不用管,然后输入一个user ID并且提供一个邮箱,我直接用的我sonatype的用户名和邮箱。最后一步输入'O',表示OK
注意(坑):一定要在命令行中执行命令,不能在客户端界面做。
(2)第二步:弹出一个对话框,让输入密码。
弹出对话框,输入你的私钥密码,输入以后会生成一些相关信息
gpg: 密钥 4972XXXXXF7F4B 被标记为绝对信任
gpg: 目录‘/Users/sun/.gnupg/openpgp-revocs.d’已创建
gpg: 吊销证书已被存储为‘/Users/sun/.gnupg/openpgp-revocs.d/005D2D6FAF7F09E3A420366449722604ADBF7F4B.rev’
公钥和私钥已经生成并被签名。
pub rsa4096 2021-04-08 [SC]
005D2D6FAF7F09E3A4203664497226XXX4B
uid sunsxxx (livery) <qyddai@gmail.com>
sub rsa4096 2021-04-08 [E]
这会在你的目录‘/Users/sun/.gnupg/openpgp-revocs.d’创建一个.rev文件,请记住截图pub中后面的8位字母,这里我的是:ADBF7F4B,复制下来,一会要用
(3)第三步:创建secring.gpg文件
命令行执行gpg --export-secret-keys -o secring.gpg
,这会要求你输入在第二步中设置的密码,在你用户根目录下会出现secring.gpg文件
再会到gpg客户端,选择我们刚生成的秘钥条目,右键,选择Send Public Key to Key Server
send成功以后会返回,这样就可以再sona中发布aar了
4.android studio中配置文件准备
(1).gradle配置文件
在你项目根目录下的build.gradle文件添加classpath:
apply from: "config.gradle"
buildscript {
ext {
gradle_build_version = '3.6.3'
bintray_version = '1.7.3'
gms_service_version = '3.1.1'
dokka_version = '1.4.10.2'
}
repositories {
google()
jcenter()
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle:$gradle_build_version"
//livery框架添加-2021年04月08日前-原jcenter依赖
classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:$bintray_version"
classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'
classpath 'com.novoda:bintray-release:+' // 2021年04月08日前-原jcenter依赖
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
/*添加Google服务:Google Firebase cloud messaging
* 参考如下链接:https://www.jianshu.com/p/b50f5aee4403
* */
classpath "com.google.gms:google-services:$gms_service_version"
// 2021 年04月08日以后 - mavenCentral增加
classpath "org.jetbrains.dokka:dokka-gradle-plugin:$dokka_version"
}
}
allprojects {
version = VERSION_NAME
group = GROUP
repositories {
google()
jcenter()
maven { url "https://jitpack.io" }
// maven {
// url "https://raw.githubusercontent.com/HyphenateInc/Hyphenate-SDK-Android/master/repository"
// }
}
/*todo fix:
防止-Xlint:unchecked 重新编译。错误*/
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
// Try to turn them all off automatically
options.compilerArgs << '-Xlint:none'
options.compilerArgs << '-nowarn' // same as '-Xlint:none'
// Turn them off manually
options.compilerArgs << '-Xlint:-auxiliaryclass'
options.compilerArgs << '-Xlint:-cast'
options.compilerArgs << '-Xlint:-classfile'
options.compilerArgs << '-Xlint:-deprecation'
options.compilerArgs << '-Xlint:-dep-ann'
options.compilerArgs << '-Xlint:-divzero'
options.compilerArgs << '-Xlint:-empty'
options.compilerArgs << '-Xlint:-fallthrough'
options.compilerArgs << '-Xlint:-finally'
options.compilerArgs << '-Xlint:-options'
options.compilerArgs << '-Xlint:-overloads'
options.compilerArgs << '-Xlint:-overrides'
options.compilerArgs << '-Xlint:-path'
options.compilerArgs << '-Xlint:-processing'
options.compilerArgs << '-Xlint:-rawtypes'
options.compilerArgs << '-Xlint:-serial'
options.compilerArgs << '-Xlint:-static'
options.compilerArgs << '-Xlint:-try'
options.compilerArgs << '-Xlint:-unchecked'
options.compilerArgs << '-Xlint:-varargs'
}
}
/*todo fix :
忽略java编译时的警告*/
tasks.withType(JavaCompile) {
configure(options) {
incremental = true
}
// options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
options.encoding = "UTF-8"
}
configurations {
all*.exclude group: 'com.android.support', module: 'support-compat'
all*.exclude group: 'com.android.support', module: 'support-v4'
all*.exclude group: 'com.android.support', module: 'support-annotations'
all*.exclude group: 'com.android.support', module: 'support-fragment'
all*.exclude group: 'com.android.support', module: 'support-core-utils'
all*.exclude group: 'com.android.support', module: 'support-core-ui'
}
tasks.withType(Javadoc) {
options.addStringOption('Xdoclint:none', '-quiet')
options.addStringOption('encoding', 'UTF-8')
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
主要是:2021 年04月08日添加的这一行
classpath "org.jetbrains.dokka:dokka-gradle-plugin:$dokka_version"
在你要提交的module下的build.gradle文件中,末尾追加如下配置:
ext {
PUBLISH_ARTIFACT_ID = 'livery'
}
apply from: '../publish.gradle'
新建一个publish.gradle,内容如下:
apply plugin: 'maven-publish'
apply plugin: 'signing'
task androidSourcesJar(type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.source
exclude "**/R.class"
exclude "**/BuildConfig.class"
}
ext {
PUBLISH_GROUP_ID = 'com.github.qydq这里是group id需要修改成你自己的'
PUBLISH_VERSION = '1.2.0版本号需要修改成你自己的'
}
//ext {
// PUBLISH_GROUP_ID = 'com.sunsta.livery'
// PUBLISH_ARTIFACT_ID = 'livery'
// PUBLISH_VERSION = '1.2.0'
//}
ext["signing.keyId"] = ''
ext["signing.password"] = ''
ext["signing.secretKeyRingFile"] = ''
ext["ossrhUsername"] = ''
ext["ossrhPassword"] = ''
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) {
// The coordinates of the library, being set from variables that
// we'll set up in a moment
groupId PUBLISH_GROUP_ID
artifactId PUBLISH_ARTIFACT_ID
version PUBLISH_VERSION
// Two artifacts, the `aar` and the sources
artifact("$buildDir/outputs/aar/${project.getName()}-release.aar")
artifact androidSourcesJar
// Self-explanatory metadata for the most part
pom {
name = PUBLISH_ARTIFACT_ID
description = 'maven_test项目描述-需要修改成你自己的'
// If your project has a dedicated site, use its URL here
url = 'https://github.com/qydq/livery(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 {
id = 'qyddai@gmail.com这里sonatype用户名修改为自己的'
name = 'sun这里sonatype名字修改为自己的'
email = 'qyddai@gmail.com这里sonatype注册邮箱'
}
}
// Version control info, if you're using GitHub, follow the format as seen here
scm {
//修改成你的Git地址:
connection = 'scm:git:github.com/qydq/livery.git这里需要修改成你自己的'
developerConnection = 'scm:git:ssh://github.com/qydq/livery.git这里需要修改成你自己的'
//分支地址:
url = 'https://github.com/qydq/livery/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 {
// This is an arbitrary name, you may also use "mavencentral" or
// any other name that's descriptive for you
name = "mavenCentral"
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
}
(2).设置local.properties文件
打开local.properties文件,设置密钥等信息
signing.keyId=ADBF7F4B //pub中获取的秘钥后8位
signing.password=3小点,第二步中设置的密码
signing.secretKeyRingFile=刚才生成的secring.gpg文件目录
ossrhUsername=qyddai@gmail.com //sonatype用户名
ossrhPassword=sonatype密码
备注:公钥给出来无所谓,但有的私钥就需要自己记住,保存在本机,local.properties文件一般不会公开,记得在.gitignore文件中添加不上传该文件的配置
5.android studio中执行打包AAR和上传
关于如何打包AAR,可以看我之前的文章介绍
Bgwan:android Studio如何打包和引用AARzhuanlan.zhihu.com
完成上面4个小点以后,就可以利用AndroidStudio右侧的gradle tasks中找到你想提交的module,先后执行以下两个任务
任务1:打包AAR 的 assemble命令
任务2:发布AAR 的 publishReleasePublicationToMavenLocalRepository命令
执行两个任务后在控制台看到成功的信息
这就意味着你的AAR已经提交到sonatype管理的Nexus Repository Manager这个,然后在你问题[OSSRH-66523] 上传sdk到maven供团队使用 - Sonatype JIRA恢复管理员,等待管理员审核回复你以后(第一次一定要等管理员回复你再操作),就可以打开Nexus Repository Manager,登录你的sonatype账号,在左侧Staging Repositories
页面(标注1)找到你的group id,选中,就能看到你提交的信息
点击上边的content内容,可以看到具体信息(这里是我的Livery边界框架提交的内容)
重要的一步,点击Close关闭
等待几分钟十几分钟后刷新状态,等其状态变为closed后,再点击Release按钮发布到MavenCentral,等待一般2个小时后可以在https://search.maven.org/查询发布结果
6.使用刚刚发布的Livery,
在你项目的build.gradle文件中,添加如下mavenCentral,jcenter可以废弃掉了,最新android studio默认没有jcenter了
repositories {
google()
// jcenter() // Warning: this repository is going to shut down soon in 2022/02/01
maven { url 'https://jitpack.io' }
mavenCentral()
maven { url 'https://maven.aliyun.com/repository/releases' }
}
再在app moudle的build.gradle,添加livery的引用,同步一下
implementation 'com.github.qydq:livery:1.2.12'