从 0 到发布:Gradle 插件双平台(MavenCentral + Plugin Portal)发布记录与避坑

之前学习了一下如何自定义 Gradle 插件,后续发布在 Jitpack 上在其他项目使用,最近发现 Jitpack 的不稳定,并且新增插件功能时,Jitpack 发布一直不成功,考虑转移到其他平台,如 MavenCentral 或 Plugin Portal,在整个过程中遇到不少容易踩坑的点,本文将完整记录整个过程。

插件地址:
github.com/waxw/String...

🔧 插件发布目标

  1. 发布到 MavenCentral
  2. 发布到 Gradle Plugin Portal
  3. 插件能通过以下两种方式引入:

✅ Gradle Plugin DSL 引入:

kotlin 复制代码
plugins {
    id("io.github.waxw.strings.plugin") version "1.0.0"
}

✅ 传统依赖方式引入:

groovy 复制代码
classpath("io.github.waxw:strings-plugin:1.0.0")

🧩 未发布插件模块 build.gradle.kts

kotlin 复制代码
plugins {
    `maven-publish`
    `java-gradle-plugin`
    // 这里需要指定 version,否则会提示找不到插件实现类
    kotlin("jvm") version libs.plugins.kotlin.jvm.get().version.displayName
}

java {
    sourceCompatibility = JavaVersion.VERSION_17
    targetCompatibility = JavaVersion.VERSION_17
}

gradlePlugin {
    plugins {
        register("stringsPlugin") {
            id = "com.miyako.strings.plugin"
            implementationClass = "com.miyako.strings.plugin.StringsPlugin"
            displayName = "Handle strings.xml plugin for Android"
            description = "A plugin help you to handle android strings.xml"
            tags.addAll("android", "strings")
        }
    }
}

group = "com.miyako.strings"
version = libs.plugins.strings.plugin.get().version

MavenCentral 发布

创建 MavenCentral 账号

  • central.sonatype.com

  • 选择 Github 登录,会自动生成一个账户同名的 namespace。

    • 可以注册一个新 namespace,生成一个 Verification Key ,需要在验证网站所有权,或者选择 Github 账号,在 Github 账号下创建同名 Verification Key 的项目仓库。
  • 创建 NameSpace

  • 创建 Token

使用 GPG 工具签名

  • [www.gnupg.org/download](https://link.juejin.cn?target=https%3A%2F%2Fwww.gnupg.org%2Fdownload "https://www.gnupg.org/download")

  • gpg --gen-key,生成 /secring.gpg。

引入 Maven 发布插件

  • [github.com/vanniktech/...](https://link.juejin.cn?target=https%3A%2F%2Fgithub.com%2Fvanniktech%2Fgradle-maven-publish-plugin "https://github.com/vanniktech/gradle-maven-publish-plugin")

kotlin 复制代码
plugins {
    `java-gradle-plugin`
    // 这里需要指定 version,否则会提示找不到插件实现类
    kotlin("jvm") version libs.plugins.kotlin.jvm.get().version.displayName
    // maven publishing 第三方插件,已包含 `maven-publish`
    alias(libs.plugins.maven.publish.plugin)
}
  • 配置 maven 仓库
kotlin 复制代码
mavenPublishing {
    coordinates("io.github.waxw", "strings-plugin", "1.0.1")
    publishToMavenCentral()
    signAllPublications()

    pom {
        name.set("Strings Plugin")
        description.set("A plugin that simplifies Android string management.")
        inceptionYear.set("2025")
        url.set("https://github.com/waxw/StringsPlugin")

        licenses {
            license {
                name.set("Apache-2.0")
                url.set("https://www.apache.org/licenses/LICENSE-2.0.txt")
            }
        }

        developers {
            developer {
                id.set("miyako")
                name.set("miyako")
                email.set("weilanxiaogz@outlook.com")
            }
        }

        scm {
            url.set("https://github.com/waxw/StringsPlugin")
            connection.set("scm:git:https://github.com/waxw/StringsPlugin.git")
            developerConnection.set("scm:git:ssh://git@github.com:waxw/StringsPlugin.git")
        }
    }
}
  • signAllPublications 是自动从 gradle.properties 中仓库账户信息。
properties 复制代码
mavenCentralUsername=MavenCentral 生成的 Token Name
mavenCentralPassword=MavenCentral 生成的 Token
signing.keyId=GPG keyId
signing.password=GPG 密码
signing.secretKeyRingFile=GPG 文件

发布插件

在以上内容配置完成后,可以通过以下命令发布插件。

bin 复制代码
./gradlew publish

运行成功后到 MavenCentral 查看结果。

发现提示,com.miyako.strings.plugin namespace 不被允许,这个产物是因为 gradle plugin 会自动为我们的插件添加 gradle.plugin 后缀并生成对应的 artificial,执行相应的 PluginMarker Task 标记映射关系并将自动上传。

可以添加以下代码禁用生成多余 artificial

kotlin 复制代码
// 禁用 plugin marker 的生成
tasks.withType<PublishToMavenRepository>().configureEach {
    if (name.contains("PluginMarker")) {
        enabled = false
    }
}

本地调试

maven-publish 插件中,默认有 publishPubName**PublicationToRepoNameRepository task 发布到指定存储库,以如下配置为例,对应的 task 为 publishStringsPluginPublicationToProjectRepository

kotlin 复制代码
// maven-publish 提供的配置项
publishing {
    // 配置发布项,默认为 publish项目名PublicationTo仓库Repository
    publications {
        create<MavenPublication>("StringsPlugin") {
            groupId = "io.github.waxw"
            artifactId = "strings-plugin"
            version = "1.0.1"
        }
    }

    repositories {
        maven {
            name = "project"
            setUrl("../local-repo/") // 发布到根项目的 local-repo 路径下
        }
    }
}

在同项目其他模块中验证:

  • 不通过 includeBuild 引入 plugin module,选择本地 maven 库依赖方式
kotlin 复制代码
settings.gradle.kts
pluginManagment {
    repositories {
        maven { setUrl("./local-repo") }
    }
}
kotlin 复制代码
build.gradle.kts
plugins {
    alias(libs.plugin.strings.plugin) apply false
}
kotlin 复制代码
app.build.kts
plugins {
    id(libs.plugin.strings.plugin.get().pluginId)
}

发现无法找到对应插件,这是因为 plugins dsl 方式引入的插件需要有 plugin marker artifacts,而之前为了上传到 MavenCentral 禁用了生成 plugin marker artifacts,因此无法通过这种方式引入依赖。需要通过 classpath 方式引入插件。

kotlin 复制代码
build.gradle.kts
classpath("io.github.waxw:strings-plugin:1.0.1")
kotlin 复制代码
app.build.kts
apply plugin: "com.miyako.strings.plugin"

如果要支持 PluginId DSL 这种方式通过 pluginId 引入插件,就需要发布到 Gradle Plugin Portal。

Gradle Plugin Portal

kotiln 复制代码
plugins {
    id("com.gradle.plugin-publish") version "1.3.1"
}

gradlePlugin {
    website.set("https://github.com/waxw/StringsPlugin")
    vcsUrl.set("https://github.com/waxw/StringsPlugin.git")
    plugins {
        register("stringsPlugin") {
            id = "com.miyako.strings.plugin"
            implementationClass = "com.miyako.strings.plugin.StringsPlugin"
            tags.addAll("android", "strings")
        }
    }
}
  • 生成并配置 gradle plugin portal 秘钥。
properties 复制代码
gradle.publish.key=xxx
gradle.publish.secret=xxx
  • 执行 publishPlugins 命令,会提示一下报错信息。 Plugin ID 'com.miyako.strings.plugin' and group ID 'io.github.waxw' must use the same top level namespace, like 'io.github.waxw' or 'com.miyako' 。这是因为 plugin-publish 强制要求 pluginId 和 groupId 相同。

因此我们需要修改我们的 pluginId,由于修改 pluginId 前缀和 MavenCentral namesspace 相同,因此也不再需要禁用 PluginMarker 产物的生成。

kotlin 复制代码
gradlePlugin { 
    website.set("https://github.com/waxw/StringsPlugin")
    vcsUrl.set("https://github.com/waxw/StringsPlugin.git") 
    plugins { 
    register("stringsPlugin") { 
        id = "io.github.waxw.strings.plugin" 
        implementationClass = "com.miyako.strings.plugin.StringsPlugin"
        tags.addAll("android", "strings") 
        }
    }
}

再次执行 publishPlugins,看到以下日志就表明我们的 plugin 已经上传成功了,我们到 Gradle Plugin Portal 的 Plugins Tab 中可以看到对应的 plugin 即可。

arduino 复制代码
> Task :plugin:publishPlugins
Thank you. Your new plugin io.github.waxw.strings.plugin has been submitted for approval by Gradle engineers. The request should be processed within the next few days, at which point you will be contacted via email.

现在插件已经发布到了 MavenCentral 和 Gradle Plugin Portal 双平台了。

bin 复制代码
./gradlew publish  -- MavenCentral
./gradlew publishPlugins --Gradle Plugin Protal

🔚 结语

这次插件发布从注册账号、生成 GPG 密钥、发布 Maven + Plugin Portal 一路走下来,最大的感受就是:文档能看懂,但实际过程太容易掉坑了。

通常来说 Gradle Plugin 项目还是建议发布到 Gradle Plugin Portal。

希望这篇文章能帮你少走些弯路。如果你觉得有帮助,欢迎点赞、收藏、评论交流!


👋 有问题欢迎 Github Issue 或加我一起交流~

如果你也在做插件开发,欢迎分享你的经验!

相关推荐
檀越剑指大厂2 小时前
容器化 Android 开发效率:cpolar 内网穿透服务优化远程协作流程
android
NRatel3 小时前
Unity 游戏提升 Android TargetVersion 相关记录
android·游戏·unity·提升版本
叽哥6 小时前
Kotlin学习第 1 课:Kotlin 入门准备:搭建学习环境与认知基础
android·java·kotlin
风往哪边走6 小时前
创建自定义语音录制View
android·前端
用户2018792831676 小时前
事件分发之“官僚主义”?或“绕圈”的艺术
android
用户2018792831676 小时前
Android事件分发为何喜欢“兜圈子”?不做个“敞亮人”!
android
Kapaseker8 小时前
你一定会喜欢的 Compose 形变动画
android
QuZhengRong8 小时前
【数据库】Navicat 导入 Excel 数据乱码问题的解决方法
android·数据库·excel
zhangphil9 小时前
Android Coil3视频封面抽取封面帧存Disk缓存,Kotlin(2)
android·kotlin