转载请注明出处
https://blog.csdn.net/aa464971/article/details/124132601
JCenter宣布停用后,今后只能发布到Maven Central,相对JCenter,首次发布到Maven Central要麻烦很多
注册Sonatype账号
https://issues.sonatype.org/secure/ForgotLoginDetails.jspa
创建问题
填写项目信息,Group Id
可以填自己的域名,或者com.github.自己的用户名
,后面会验证所有权
验证Group Id
几分钟后会有一个机器人回复,要求验证域名的所有权
- 用域名作为Group Id:域名解析一个__TXT记录__,内容就是当前__问题编号__
- 用Github用户名作为Group Id:创建一个名称为当前__问题编号__的仓库
将问题标记为打开
等待几分钟会回复验证成功,就可以上传项目了
发布项目
在要工程根目录创建publish.gradle
,粘贴模板,此模板支持Android、Java、Kotlin、Gradle Plugin
publish.gradle
代码地址:https://gist.github.com/xiandanin/6a215a24acee9e8194bc4668b3e8f133
apply plugin: 'maven-publish'
apply plugin: 'signing'
Properties localProperties = new Properties()
// 合并local.properties
localProperties.load(project.rootProject.file('local.properties').newDataInputStream())
localProperties.each { name, value -> project.ext[name] = value }
Map<String, String> projectProperties = new HashMap<>()
// 合并project.ext
projectProperties.putAll(project.ext.getProperties())
// 合并rootProject.ext
rootProject.ext.getProperties().each { name, value -> if (!projectProperties.containsKey(name)) projectProperties.put(name, value) }
//println(properties)
def mavenUsername = localProperties.getProperty("sonatype.username")
def mavenPassword = localProperties.getProperty("sonatype.password")
def projectGroupId = projectProperties.get('groupId')
def projectArtifactId = project.getName()
def projectVersionName = projectProperties.getOrDefault('version', project.extensions.findByName("android")["defaultConfig"].versionName)
def projectDescription = projectProperties.get('description')
def projectGitUrl = projectProperties.get('gitUrl')
def projectLicense = projectProperties.get('license')
def projectLicenseUrl = projectLicense ? "https://opensource.org/licenses/${projectLicense.toString().replace(" ", "-")} " : null
def developerAuthorId = mavenUsername
def developerAuthorName = mavenUsername
def developerAuthorEmail = projectProperties.get('authorEmail')
println("${mavenUsername} ${mavenPassword} - ${projectGroupId}:${projectArtifactId}:${projectVersionName}")
println("${projectLicense} - ${projectLicenseUrl}")
if (!projectGroupId || !projectArtifactId || !projectVersionName) {
println("${project.name} 缺少项目信息")
return
}
if (!mavenUsername || !mavenPassword || !localProperties.containsKey("signing.keyId") || !localProperties.containsKey("signing.password") || !localProperties.containsKey("signing.secretKeyRingFile")) {
println("${project.name} 缺少认证信息")
return
}
if (!projectDescription || !projectGitUrl || !projectLicense || !projectLicenseUrl || !developerAuthorId || !developerAuthorName || !developerAuthorEmail) {
println("${project.name} 缺少项目描述信息")
}
android {
publishing {
singleVariant("release") {
withSourcesJar()
withJavadocJar()
}
}
}
afterEvaluate {
publishing {
publications {
aar(MavenPublication) {
from components.release
groupId = projectGroupId
artifactId = projectArtifactId
version = projectVersionName
pom {
name = projectArtifactId
description = projectDescription
// If your project has a dedicated site, use its URL here
url = projectGitUrl
if (projectLicense) {
licenses {
license {
name = projectLicense
url = projectLicenseUrl
}
}
}
developers {
developer {
id = developerAuthorId
name = developerAuthorName
email = developerAuthorEmail
}
}
// Version control info, if you're using GitHub, follow the format as seen here
scm {
connection = "scm:git:${projectGitUrl}"
developerConnection = "scm:git:${projectGitUrl}"
url = projectGitUrl
}
withXml { xmlProvider ->
def node = xmlProvider.asNode()
def getAt = node.getAt('dependencies')
def dependenciesNode
if (getAt == null) {
dependenciesNode = node.appendNode('dependencies')
} else {
dependenciesNode = getAt[0]
}
configurations.api.allDependencies.each { dependency ->
if (!dependency.hasProperty('dependencyProject')) {
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', dependency.group)
dependencyNode.appendNode('artifactId', dependency.name)
dependencyNode.appendNode('version', dependency.version)
}
}
}
}
}
}
repositories {
maven {
name = projectArtifactId
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 mavenUsername
password mavenPassword
}
}
}
}
}
signing {
sign publishing.publications
}
在要发布的Library工程下的build.gradle最后引用发布模板
apply from: '../publish.gradle'
在工程根目录的build.gradle
最后添加项目信息
ext {
// 版本号
versionCode = 3
// 版本名称
versionName = "1.0.2"
// groupId
groupId = 'io.xiandan'
// 项目描述
description = 'JSONObject、JSONArray、Gson的Koltin扩展'
// 项目git地址
gitUrl = 'https://github.com/xiandanin/json-ktx'
// 作者邮箱
authorEmail = 'denghahae@gmail.com'
// 开源协议
license = 'MIT'
}
创建密钥
- Gpg4win :https://www.gpg4win.org/download.html
- 签名凭证 :https://docs.gradle.org/current/userguide/signing_plugin.html
创建证书
生成密钥对
创建个人OpenPGP密钥对
勾选Protect the generated key with a passphrase.
,输入密码
复制指纹后8位作为signing.keyId
生成撤销证书
右键证书,在服务器上发布,最后会发布在http://keys.gnupg.net
右键Backup Secret Keys...
导出私钥证书,后缀名改为gpg
填写认证信息
将Sonatype账号和密钥信息填写到local.properties
,signing.secretKeyRingFile
就是最后导出的.gpg
路径
sonatype.username=
sonatype.password=
signing.keyId=
signing.password=
signing.secretKeyRingFile=
发布
执行publish
任务,或者命令行执行gradlew publish
任务执行完成后,登录https://s01.oss.sonatype.org/#stagingRepositories,选中刚刚上传的提交,点击Close
无报错提示Repository Closed
说明执行完成,点击Release
,等待几十分钟就会同步到Maven Central
了
首次发布同步
因为这个Group Id是首次发布,发布项目后,要手动通知同步到Maven Central,将Already Synced to Central
标记为Yes
,等待几个小时就可以在Maven Central看到项目了