发布插件是使其可供他人使用的主要方式。虽然您可以发布到私有仓库以限制访问,但发布到 Gradle 插件门户 会使您的插件可供全世界任何人使用。

plugin portal page

本指南将向您展示如何使用 com.gradle.plugin-publish 插件,通过便捷的 DSL 将插件发布到 Gradle 插件门户。这种方法简化了配置步骤并提供验证检查,以确保您的插件符合 Gradle 插件门户的标准。

先决条件

本教程需要一个现有的 Gradle 插件项目。如果您没有,请使用 Greeting 插件示例

尝试发布此插件将因权限错误而安全失败,因此不必担心使用一个琐碎的示例插件来搞乱 Gradle 插件门户。

账户设置

在发布插件之前,您必须在 Gradle 插件门户上创建一个账户。按照注册页面上的说明创建一个账户,并从您的个人资料页面的“API 密钥”选项卡获取 API 密钥。

plugin portal registration page

将您的 API 密钥存储在 Gradle 配置中(gradle.publish.key 和 gradle.publish.secret),或者使用像 Seauc Credentials 插件这样的插件进行安全管理。

plugin portal api keys

通常的做法是将其复制并粘贴到您的 $HOME/.gradle/gradle.properties 文件中,但您也可以将其放置在任何其他有效位置。该插件仅要求在执行适当的插件门户任务时,gradle.publish.keygradle.publish.secret 可作为项目属性使用。

如果您担心将凭据放在 gradle.properties 中,请查看 Seauc Credentials 插件

或者,您可以通过 GRADLE_PUBLISH_KEYGRADLE_PUBLISH_SECRET 环境变量提供 API 密钥。这种方法可能适用于 CI/CD 管道。

添加插件发布插件

要发布您的插件,请将 com.gradle.plugin-publish 插件添加到您的项目的 build.gradlebuild.gradle.kts 文件中

build.gradle.kts
plugins {
    id("com.gradle.plugin-publish") version "1.2.1"
}
build.gradle
plugins {
    id 'com.gradle.plugin-publish' version '1.2.1'
}

插件发布插件的最新版本可在 Gradle 插件门户上找到。

自 1.0.0 版本起,插件发布插件会自动应用 Java Gradle 插件开发插件(协助开发 Gradle 插件)和 Maven 发布插件(生成插件发布元数据)。如果使用旧版本的插件发布插件,则必须显式应用这些辅助插件。

配置插件发布插件

在您的 build.gradlebuild.gradle.kts 文件中配置 com.gradle.plugin-publish 插件。

build.gradle.kts
group = "io.github.johndoe" (1)
version = "1.0" (2)

gradlePlugin { (3)
    website = "<substitute your project website>" (4)
    vcsUrl = "<uri to project source repository>" (5)

    // ... (6)
}
build.gradle
group = 'io.github.johndoe' (1)
version = '1.0'     (2)

gradlePlugin { (3)
    website = '<substitute your project website>' (4)
    vcsUrl = '<uri to project source repository>' (5)

    // ... (6)
}
1 确保您的项目设置了 group,该组用于标识您在 Gradle 插件门户仓库中发布的插件的 artifact(jar 和元数据),并且能够描述插件作者或插件所属的组织。
2 设置您的项目版本,该版本也将用作您的插件版本。
3 使用 Java Gradle 插件开发插件 提供的 gradlePlugin 块来配置插件发布的更多选项。
4 设置插件项目的网站。
5 提供源代码仓库 URI,以便其他人如果想贡献可以找到它。
6 为您要发布的每个插件设置特定属性;请参阅下一节。

使用 gradlePlugin{} 块定义所有插件的通用属性,例如组、版本、网站和源代码仓库

build.gradle.kts
gradlePlugin { (1)
    // ... (2)

    plugins { (3)
        create("greetingsPlugin") { (4)
            id = "<your plugin identifier>" (5)
            displayName = "<short displayable name for plugin>" (6)
            description = "<human-readable description of what your plugin is about>" (7)
            tags = listOf("tags", "for", "your", "plugins") (8)
            implementationClass = "<your plugin class>"
        }
    }
}
build.gradle
gradlePlugin { (1)
    // ... (2)

    plugins { (3)
        greetingsPlugin { (4)
            id = '<your plugin identifier>' (5)
            displayName = '<short displayable name for plugin>' (6)
            description = '<human-readable description of what your plugin is about>' (7)
            tags.set(['tags', 'for', 'your', 'plugins']) (8)
            implementationClass = '<your plugin class>'
        }
    }
}
1 插件特定的配置也进入 gradlePlugin 块。
2 这是我们之前添加全局属性的地方。
3 您发布的每个插件都将在 plugins 内部有自己的块。
4 插件块的名称必须对您发布的每个插件都是唯一的;这是您的构建仅在本地使用的属性,不会成为发布的一部分。
5 设置插件的唯一 id,因为它将在发布中被标识。
6 以人类可读的形式设置插件名称。
7 设置将在门户上显示的描述。它为想要使用您的插件的人提供了有用的信息。
8 指定您的插件涵盖的类别。这使得需要其功能的人更有可能发现该插件。

例如,考虑已发布到 Gradle 插件门户的 GradleTest 插件 的配置。

build.gradle.kts
gradlePlugin {
    website = "https://github.com/ysb33r/gradleTest"
    vcsUrl = "https://github.com/ysb33r/gradleTest.git"
    plugins {
        create("gradletestPlugin") {
            id = "org.ysb33r.gradletest"
            displayName = "Plugin for compatibility testing of Gradle plugins"
            description = "A plugin that helps you test your plugin against a variety of Gradle versions"
            tags = listOf("testing", "integrationTesting", "compatibility")
            implementationClass = "org.ysb33r.gradle.gradletest.GradleTestPlugin"
        }
    }
}
build.gradle
gradlePlugin {
    website = 'https://github.com/ysb33r/gradleTest'
    vcsUrl = 'https://github.com/ysb33r/gradleTest.git'
    plugins {
        gradletestPlugin {
            id = 'org.ysb33r.gradletest'
            displayName = 'Plugin for compatibility testing of Gradle plugins'
            description = 'A plugin that helps you test your plugin against a variety of Gradle versions'
            tags.addAll('testing', 'integrationTesting', 'compatibility')
            implementationClass = 'org.ysb33r.gradle.gradletest.GradleTestPlugin'
        }
    }
}

如果您浏览 GradleTest 插件在 Gradle 插件门户上的相关页面,您将看到指定的元数据显示方式。

plugin portal plugin page

源码和 Javadoc

插件发布插件会自动生成并发布您的插件发布的 Javadoc 和源码 JAR 包

签名 Artifact

从插件发布插件的 1.0.0 版本开始,已发布的插件 artifact 的签名已自动化。要启用它,只需在构建中应用 signing 插件即可。

Shadow 依赖项

从插件发布插件的 1.0.0 版本开始,Shadow 您的插件依赖项(即将其发布为 fat jar)已自动化。要启用它,只需在构建中应用 com.gradleup.shadow 插件即可。

发布插件

如果您在组织内部发布插件供内部使用,则可以像发布任何其他代码 artifact 一样发布它。请参阅 IvyMaven 关于发布 artifact 的章节。

如果您有兴趣发布您的插件以供更广泛的 Gradle 社区使用,您可以将其发布到 Gradle 插件门户。该网站提供了搜索和收集 Gradle 社区贡献的插件信息的能力。请参阅关于在此网站上提供插件的相应部分

本地发布

要检查已发布插件的 artifact 外观或仅在公司内部本地使用它,您可以将其发布到任何 Maven 仓库,包括本地文件夹。您只需要配置发布仓库。然后,您可以运行 publish 任务将您的插件发布到所有已定义的仓库(但不包括 Gradle 插件门户)。

build.gradle.kts
publishing {
    repositories {
        maven {
            name = "localPluginRepository"
            url = uri("../local-plugin-repository")
        }
    }
}
build.gradle
publishing {
    repositories {
        maven {
            name = 'localPluginRepository'
            url = file('../local-plugin-repository')
        }
    }
}

要在另一个构建中使用该仓库,请将其添加到 settings.gradle(.kts) 文件中 pluginManagement {} 块的仓库中。

发布到插件门户

使用 publishPlugin 任务发布插件

$ ./gradlew publishPlugins

您可以使用 --validate-only 标志在发布之前验证您的插件

$ ./gradlew publishPlugins --validate-only

如果您尚未为 Gradle 插件门户配置 gradle.properties,则可以在命令行上指定它们

$ ./gradlew publishPlugins -Pgradle.publish.key=<key> -Pgradle.publish.secret=<secret>
如果您尝试使用本节中使用的 ID 发布示例 Greeting 插件,您将遇到权限失败。这是预期行为,可确保门户不会被多个实验性和重复的问候类型插件淹没。

批准后,您的插件将在 Gradle 插件门户上可用,供其他人发现和使用。

使用已发布的插件

一旦您成功发布了一个插件,它不会立即出现在门户上。它还需要通过一个审批流程,该流程对于您的插件的初始版本是手动的,并且相对较慢,但对于后续版本是完全自动化的。有关更多详细信息,请参阅此处

一旦您的插件获得批准,您可以在 URL 形式为 https://plugins.gradle.org/plugin/<your-plugin-id> 的网址找到其使用说明。例如,Greeting 插件示例已在门户上,网址为 https://plugins.gradle.org/plugin/org.example.greeting

未通过 Gradle 插件门户发布的插件

如果您的插件未通过 Java Gradle 插件开发插件 发布,则发布将缺少 插件标记 Artifact,这是 plugins DSL 定位插件所需的。在这种情况下,在另一个项目中解析插件的推荐方法是在项目的 settings 文件的 pluginManagement {} 块中添加一个 resolutionStrategy 部分,如下所示。

settings.gradle.kts
resolutionStrategy {
    eachPlugin {
        if (requested.id.namespace == "org.example") {
            useModule("org.example:custom-plugin:${requested.version}")
        }
    }
}
settings.gradle
resolutionStrategy {
    eachPlugin {
        if (requested.id.namespace == 'org.example') {
            useModule("org.example:custom-plugin:${requested.version}")
        }
    }
}