前言
开发者可能都会做自己的开源库,像我以前只做一些单平台的,如Android或JVM平台,这时候直接使用jitpack即可,很简单就能发布远程依赖
jitpack参考:
发布开源库的踩坑经历:jitpack.io_李小白lt的博客
而现在Kotlin可以通过expect来实现原生多平台项目(或库),这时我们开发出来一个多平台的库,可以使用MavenCentral来发布
expect参考:
KMM Kotlin expect的几种声明方式_李小白lt的博客
正文
接下来我们来看一下如何发布Kotlin多平台库
1.首先可以创建一个多平台的库,可以参考:
KMM+Compose 开发一个Kotlin多平台应用_kotlin kmm_李小白lt的博客
Create and publish a multiplatform library – tutorial | Kotlin Documentation (kotlinlang.org)
2.注册Sonatype Jira帐户(如果是第一次操作从这一步开始,否则,请从第11步开始看)
Sign up for Jira - Sonatype JIRA
进入上面的链接,然后填入信息注册,注册完成后续需要使用Username和Password
3.创建问题(没错!)
注册成功后,一般会跳到这个页面,可以点这个位置创建一个问题
然后这样填:
4.验证Group Id归属
上面的问题提交完之后,会有机器人回复你的消息,如下:
它让你创建一个名字是他发的 OSSRH-XXX的public的Github的仓库
你用你的Github创建完成后,在这里将状态改为打开,一般是下拉后的第一行(我这里做过了)
设置完状态后,一会就会看见机器人的留言
5.生成密钥
接下来需要使用GPG来生成密钥
windows可以使用以下链接下载安装,其他系统自己找找吧:
Gpg4win - Secure email and file encryption with GnuPG for Windows
安装就一路下一步吧
然后打开cmd命令行,输入:
gpg --full-gen-key
然后他会让你输入各种信息(中间提示y/n就输入y):
密钥种类 RSA
密钥大小 4096
过期时间 0 (表示永不过期)
姓名
邮箱 (后续使用)
评论 可以不填
密码 (后续使用)
6.获取密钥信息
输入命令验证上述步骤是否成功:
gpg --list-keys
得到这样的信息就成功了
红框选中的(密钥ID)后八位后续需要使用,也就是密钥的指纹
然后上传你的公钥到服务器
gpg --keyserver keyserver.ubuntu.com --send-keys <你的密钥指纹>
然后通过以下命令保存私钥到本地,后续需要使用
gpg --export-secret-keys -o <保存的文件地址>
一般文件名使用 secring.gpg
ps:linux或macos可能需要使用下面这个命令(我的windows上反正是用不了)
gpg --export-secret-keys <密钥指纹> | base64
7.配置Gradle预编译脚本插件
先在你的项目中创建一个model,取名为 convention-plugins
然后创建目录如下所示,可以参考我的项目配置(ComposeViews):
ps:需要注意目录位置
model里的build.gradle.kts中写如下代码:
plugins {
`kotlin-dsl` // Is needed to turn our build logic written in Kotlin into the Gradle Plugin
}
repositories {
gradlePluginPortal() // To use 'maven-publish' and 'signing' plugins in our own plugin
}
文件convention.publication.gradle.kts中写如下代码:
import org.gradle.api.publish.maven.MavenPublication
import org.gradle.api.tasks.bundling.Jar
import org.gradle.kotlin.dsl.`maven-publish`
import org.gradle.kotlin.dsl.signing
import java.util.*
plugins {
`maven-publish`
signing
}
// Stub secrets to let the project sync and build without the publication values set up
ext["signing.keyId"] = null
ext["signing.password"] = null
ext["signing.secretKeyRingFile"] = null
ext["ossrhUsername"] = null
ext["ossrhPassword"] = null
// Grabbing secrets from local.properties file or from environment variables, which could be used on CI
val secretPropsFile = project.rootProject.file("local.properties")
if (secretPropsFile.exists()) {
secretPropsFile.reader().use {
Properties().apply {
load(it)
}
}.onEach { (name, value) ->
ext[name.toString()] = value
}
} else {
ext["signing.keyId"] = System.getenv("SIGNING_KEY_ID")
ext["signing.password"] = System.getenv("SIGNING_PASSWORD")
ext["signing.secretKeyRingFile"] = System.getenv("SIGNING_SECRET_KEY_RING_FILE")
ext["ossrhUsername"] = System.getenv("OSSRH_USERNAME")
ext["ossrhPassword"] = System.getenv("OSSRH_PASSWORD")
}
val javadocJar by tasks.registering(Jar::class) {
archiveClassifier.set("javadoc")
}
fun getExtraString(name: String) = ext[name]?.toString()
publishing {
// Configure maven central repository
repositories {
maven {
name = "sonatype"
setUrl("https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/")
credentials {
username = getExtraString("ossrhUsername")
password = getExtraString("ossrhPassword")
}
}
}
// Configure all publications
publications.withType<MavenPublication> {
// Stub javadoc.jar artifact
artifact(javadocJar.get())
// Provide artifacts information requited by Maven Central
pom {
name.set("<你的项目名>")
description.set("<你的项目描述>")
url.set("<你的项目地址>")
licenses {
license {
name.set("<开源协议,比如 Apache License 2.0>")
url.set("<开源协议地址,比如 http://www.apache.org/licenses/>")
}
}
developers {
developer {
id.set("<你的Github名字>")
name.set("<你的Github昵称>")
email.set("<你的Github邮箱>")
}
}
scm {
url.set("<你的项目地址>")
}
}
}
}
// Signing artifacts. Signing.* extra properties values will be used
signing {
sign(publishing.publications)
}
8.配置参数
将私钥文件secring.gpg复制到项目根目录
在项目根目录的local.properties文件中加入如下配置:
signing.keyId=<密钥指纹>
signing.password=<密钥密码>
signing.secretKeyRingFile=../secring.gpg
ossrhUsername=<Sonatype Jira的Username>
ossrhPassword=<Sonatype Jira的Password>
然后在.gitignore文件中将这两个文件配置为不上传
secring.gpg
local.properties
9.使用Gradle预编译脚本插件
在项目根目录的settings.gradle.kts文件中配置:
rootProject.name = "<你的项目名>"
includeBuild("convention-plugins")
在你需要发布的model中的build.gradle.kts中配置:
plugins {
//kotlin("multiplatform") version xxx
...
id("convention.publication")
}
然后同步一下gradle
ps:你要发布的model的model名字,后面就会变成你的远程依赖的项目名,比如:我的model:
本来红框选中的model名字叫croe,结果他给我生成的依赖地址为这个: io.github.ltttttttttttt:core:xxx
10.发布目标配置
在你需要发布的model中的build.gradle.kts中,除了需要配置下面这个插件除外,还需要配置更多:
id("convention.publication")
配置你的group id和版本号:
group = "io.github.<你的Github名字>"
version = "<版本号>"
配置你Kotlin多平台的target
kotlin {
//发布android target
android {
//发布安卓需要额外配置这两个变体
publishLibraryVariants("debug", "release")
...
}
//发布jvm的desktop的target
jvm("desktop") {
...
}
//发布js target
js(...){
...
}
}
截图如下:
11.上传项目产物至远程服务器
先调试不报错后,在Terminal tab中使用以下命令上传(第一次传最好是先clear一下)
ps:如果报错请修改你的错误后再重试
./gradlew publishAllPublicationsToSonatypeRepository
这样就成功了
12.去后台将远程服务器上的库确认发布
访问以下网址,使用Sonatype Jira账号进行登录:
ps:这个后台巨慢,巨卡,佛了
Nexus Repository Manager (sonatype.org)
点击Staging Repositories
点击Refresh
经过漫长的加载和重试中,出来了结果,我们选中,然后在点击close,直接确定就行
成功后(或者刷新几次看看)之后,我们在选中,然后在点击release,直接确定就行
成功后这个后台就完事了
然后在半个小时内可以发布到maven远程服务器上,4个小时左右可以在maven搜索中找到
maven服务器地址: Central Repository: (maven.org)
ps:链接后面可以拼上 io/github/<你的github名字>/<你的model名> 来直接访问对应项目地址
maven搜索地址: Maven Central (sonatype.com)
13.如果你这个库是第一次提交,则需要通知机器人,让他给你"开库"
打开之前注册的网站:
System Dashboard - Sonatype JIRA
在你创建的问题中,回复一下"I released the first component"
等机器人给你回复后,你的库就可以使用了,使用方式:
implementation("io.github.<你的github名字>:<开源库上传的model的名字>:<版本号>")
//比如: implementation("io.github.ltttttttttttt:ComposeViews:1.3.7.4")
结语
可以发现配置过程又臭又长,各种参考文档上也有错误,这个后台更是难用中的难用,佛了
可以参考我的项目的配置:
ltttttttttttt/ComposeViews
除了第一次配置之后,后续都只需要第11,12步即可完成配置
参考:
Create and publish a multiplatform library – tutorial | Kotlin Documentation (kotlinlang.org)