Maven 仓库发布
将 Android 库或 Kotlin 模块发布到 Maven 仓库,供其他项目使用。
Maven 发布概念
为什么发布到 Maven
共享代码:
- 团队内部共享库
- 开源项目分发
- 模块化架构
版本管理:
- 统一版本号
- 依赖管理
- 回滚支持
CI/CD 集成:
- 自动发布
- 快照版本
- 正式版本
Maven Publish 插件
启用插件
build.gradle.kts:
kotlin
plugins {
id("maven-publish")
}基本发布配置
kotlin
publishing {
publications {
create<MavenPublication>("release") {
groupId = "com.example"
artifactId = "my-library"
version = "1.0.0"
from(components["release"])
}
}
}Android 库发布
完整配置
kotlin
// library/build.gradle.kts
plugins {
id("com.android.library")
id("maven-publish")
}
android {
namespace = "com.example.mylibrary"
compileSdk = 34
defaultConfig {
minSdk = 24
}
publishing {
singleVariant("release") {
withSourcesJar()
withJavadocJar()
}
}
}
publishing {
publications {
create<MavenPublication>("release") {
groupId = "com.example"
artifactId = "mylibrary"
version = "1.0.0"
// 发布 release 变体
afterEvaluate {
from(components["release"])
}
// POM 配置
pom {
name.set("My Library")
description.set("An awesome Android library")
url.set("https://github.com/example/mylibrary")
licenses {
license {
name.set("The Apache License, Version 2.0")
url.set("http://www.apache.org/licenses/LICENSE-2.0.txt")
}
}
developers {
developer {
id.set("developer")
name.set("Developer Name")
email.set("developer@example.com")
}
}
scm {
connection.set("scm:git:git://github.com/example/mylibrary.git")
developerConnection.set("scm:git:ssh://github.com/example/mylibrary.git")
url.set("https://github.com/example/mylibrary")
}
}
}
}
}发布目标
本地 Maven 仓库
发布到本地:
kotlin
publishing {
repositories {
mavenLocal()
}
}发布命令:
bash
./gradlew publishToMavenLocal位置:
~/.m2/repository/com/example/mylibrary/1.0.0/文件系统仓库
kotlin
publishing {
repositories {
maven {
name = "FileRepo"
url = uri("file://${rootProject.projectDir}/repo")
}
}
}发布:
bash
./gradlew publishReleasePublicationToFileRepoRepository远程 Maven 仓库
HTTP 仓库:
kotlin
publishing {
repositories {
maven {
name = "CompanyRepo"
url = uri("https://maven.company.com/releases")
credentials {
username = providers.environmentVariable("MAVEN_USERNAME").orNull
password = providers.environmentVariable("MAVEN_PASSWORD").orNull
}
}
}
}发布:
bash
export MAVEN_USERNAME=user
export MAVEN_PASSWORD=pass
./gradlew publishReleasePublicationToCompanyRepoRepositoryMaven Central 发布
准备工作
1. 注册 Sonatype 账号:
2. 申请 GroupID:
- 创建 JIRA Issue
- 验证域名所有权
3. 生成 GPG 密钥:
bash
gpg --gen-key
gpg --list-keys
gpg --keyserver keyserver.ubuntu.com --send-keys <KEY_ID>配置签名
gradle.properties:
properties
signing.keyId=<LAST_8_CHARS_OF_KEY>
signing.password=<GPG_PASSWORD>
signing.secretKeyRingFile=/home/user/.gnupg/secring.gpg
ossrhUsername=<SONATYPE_USERNAME>
ossrhPassword=<SONATYPE_PASSWORD>build.gradle.kts:
kotlin
plugins {
id("maven-publish")
id("signing")
}
publishing {
publications {
create<MavenPublication>("release") {
groupId = "com.example"
artifactId = "mylibrary"
version = "1.0.0"
afterEvaluate {
from(components["release"])
}
pom {
// 必填项
name.set("My Library")
description.set("Description")
url.set("https://github.com/example/mylibrary")
licenses {
license {
name.set("The Apache License, Version 2.0")
url.set("http://www.apache.org/licenses/LICENSE-2.0.txt")
}
}
developers {
developer {
id.set("developer")
name.set("Developer Name")
email.set("developer@example.com")
}
}
scm {
connection.set("scm:git:git://github.com/example/mylibrary.git")
developerConnection.set("scm:git:ssh://github.com/example/mylibrary.git")
url.set("https://github.com/example/mylibrary")
}
}
}
}
repositories {
maven {
name = "OSSRH"
val releasesRepoUrl = uri("https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/")
val snapshotsRepoUrl = uri("https://s01.oss.sonatype.org/content/repositories/snapshots/")
url = if (version.toString().endsWith("SNAPSHOT")) snapshotsRepoUrl else releasesRepoUrl
credentials {
username = findProperty("ossrhUsername") as String?
password = findProperty("ossrhPassword") as String?
}
}
}
}
signing {
sign(publishing.publications["release"])
}发布到 Maven Central
bash
./gradlew publishReleasePublicationToOSSRHRepository发布流程:
- 上传到 Staging 仓库
- 登录 https://s01.oss.sonatype.org/
- Close Staging Repository
- Release to Maven Central
- 等待同步(2-4小时)
GitHub Packages
配置
kotlin
publishing {
repositories {
maven {
name = "GitHubPackages"
url = uri("https://maven.pkg.github.com/username/repository")
credentials {
username = providers.environmentVariable("GITHUB_ACTOR").orNull
password = providers.environmentVariable("GITHUB_TOKEN").orNull
}
}
}
}GitHub Actions 发布
yaml
name: Publish
on:
release:
types: [created]
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup JDK
uses: actions/setup-java@v3
with:
java-version: '17'
- name: Publish
run: ./gradlew publishReleasePublicationToGitHubPackagesRepository
env:
GITHUB_ACTOR: ${{ github.actor }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}版本管理
语义化版本
<major>.<minor>.<patch>[-<label>]
1.0.0 - 正式版本
1.0.0-alpha01 - Alpha 版本
1.0.0-beta01 - Beta 版本
1.0.0-rc01 - Release Candidate
1.1.0-SNAPSHOT- 快照版本动态版本号
使用 Git Tag:
kotlin
fun getVersionName(): String {
val tag = providers.exec {
commandLine("git", "describe", "--tags", "--always")
}.standardOutput.asText.get().trim()
return if (tag.startsWith("v")) tag.substring(1) else tag
}
publishing {
publications {
create<MavenPublication>("release") {
version = getVersionName()
}
}
}使用 gradle.properties:
properties
VERSION_NAME=1.0.0
VERSION_CODE=1kotlin
val versionName: String by project
publishing {
publications {
create<MavenPublication>("release") {
version = versionName
}
}
}实战案例
案例1:内部库发布
场景:团队内部共享工具库
配置:
kotlin
// buildSrc/src/main/kotlin/publish-conventions.gradle.kts
plugins {
id("maven-publish")
}
group = "com.company.internal"
publishing {
publications {
create<MavenPublication>("release") {
from(components["java"])
}
}
repositories {
maven {
name = "CompanyNexus"
url = uri("https://nexus.company.com/repository/maven-releases/")
credentials {
username = providers.environmentVariable("NEXUS_USER").orNull
password = providers.environmentVariable("NEXUS_PASS").orNull
}
}
}
}使用:
kotlin
// library/build.gradle.kts
plugins {
id("publish-conventions")
}
version = "1.2.3"案例2:多模块发布
根项目:
kotlin
// build.gradle.kts
subprojects {
group = "com.example"
version = "1.0.0"
plugins.withId("com.android.library") {
apply(plugin = "maven-publish")
publishing {
publications {
create<MavenPublication>("release") {
afterEvaluate {
from(components["release"])
}
}
}
}
}
}发布所有模块:
bash
./gradlew publishToMavenLocal最佳实践
版本号规范:
- 使用语义化版本
- SNAPSHOT 用于开发
- 正式版本不可变
POM 完整性:
- 填写所有必填字段
- 添加开源许可
- 提供项目 URL
凭证安全:
- 使用环境变量
- 不提交到版本控制
- CI 使用 Secrets
自动化发布:
yaml
# GitHub Actions
on:
push:
tags:
- 'v*'发布检查清单:
- ✅ 版本号正确
- ✅ POM 信息完整
- ✅ 源码和文档打包
- ✅ 签名配置(Maven Central)
- ✅ 测试通过
- ✅ CHANGELOG 更新