skip to content

How do you publish a Gradle plugin to the public Gradle Plugin Portal? Walk through the plugin and task involved.

level: middleimportance: must knowfreq 55%

answer

  1. com.gradle.plugin-publish
  2. publishPlugins task
  3. gradlePlugin { website / vcsUrl / tags }
  4. gradle.publish.key / .secret
  5. --validate-only dry run

basics

~10 s

Apply the com.gradle.plugin-publish plugin, configure plugin metadata under the gradlePlugin block, set your Portal API key/secret, then run the publishPlugins task.

solid answer

~40 s

Publishing to the Gradle Plugin Portal is driven by the official **`com.gradle.plugin-publish`** plugin (current major: 1.x). It pulls in `java-gradle-plugin` and `maven-publish` for you. You describe your plugin(s) in the `gradlePlugin { plugins { … } }` block — each entry needs an `id`, `implementationClass`, plus portal metadata like `displayName`, `description`, `tags` and a project-level `website`/`vcsUrl`. You authenticate with a Portal API **key and secret** (obtained from your gradle.org account), supplied via `gradle.publish.key`/`gradle.publish.secret` (usually in `~/.gradle/gradle.properties` or env vars). Running **`./gradlew publishPlugins`** validates the metadata, builds the artifacts, and uploads them — it also publishes a *plugin marker* artifact so `plugins { id … }` resolution works. Use `--validate-only` to dry-run the checks.

code

kotlin · 22 lines
kotlin
plugins {
    `java-gradle-plugin`
    id("com.gradle.plugin-publish") version "1.3.0"
}

group = "com.example"
version = "1.0.0"

gradlePlugin {
    website = "https://github.com/me/greeting"
    vcsUrl = "https://github.com/me/greeting.git"
    plugins {
        create("greeting") {
            id = "com.example.greeting"
            implementationClass = "com.example.GreetingPlugin"
            displayName = "Greeting Plugin"
            description = "Prints a greeting"
            tags = listOf("hello", "sample")
        }
    }
}
// ./gradlew publishPlugins

go deeper

for a junior

Know the one-liner: apply com.gradle.plugin-publish and run publishPlugins.

for a middle

Explain the gradlePlugin metadata block, where credentials live, and the --validate-only dry run.

for a senior

Discuss the marker artifact, the auto-applied java-gradle-plugin/maven-publish, and required sources/javadoc JARs.

for a principal

Frame Portal publishing within an org release process — secret management, CI gating with --validate-only, and versioning policy.

## Why a dedicated plugin The **Gradle Plugin Portal** (plugins.gradle.org) is the default repository the `plugins {}` block resolves IDs against. Publishing there is not a raw `maven-publish` upload — it requires extra metadata and a marker artifact. The **`com.gradle.plugin-publish`** plugin packages all of this. ## What it brings in Applying it automatically applies: - **`java-gradle-plugin`** — the base plugin-development plugin that exposes the `gradlePlugin` extension and generates plugin descriptors. - **`maven-publish`** — the publishing engine used under the hood. ## Metadata you must declare The `gradlePlugin` extension is configured like: ```kotlin gradlePlugin { website = "https://github.com/me/greeting" vcsUrl = "https://github.com/me/greeting.git" plugins { create("greeting") { id = "com.example.greeting" implementationClass = "com.example.GreetingPlugin" displayName = "Greeting Plugin" description = "Says hello at build time" tags = listOf("hello", "sample") } } } ``` `website` and `vcsUrl` are set on the extension itself (they are required by the Portal). `displayName`, `description`, and `tags` are per-plugin and used for the Portal listing/search. ## Authentication The Portal authenticates with an **API key + secret** generated from your gradle.org profile. Provide them as `gradle.publish.key` and `gradle.publish.secret` — typically in `~/.gradle/gradle.properties` (never commit) or as the env vars `GRADLE_PUBLISH_KEY` / `GRADLE_PUBLISH_SECRET`. ## The publish task **`publishPlugins`** is the entry point. It runs validation (metadata present, plugin IDs valid, `java-gradle-plugin` plugin marker generation), assembles the JARs (and, by default, sources + javadoc JARs which the Portal requires), and uploads. `./gradlew publishPlugins --validate-only` performs all checks **without** uploading — ideal for CI pre-flight. ## Marker artifacts For every plugin `id`, the build also publishes a tiny **plugin marker** artifact at coordinates `<id>:<id>.gradle.plugin:<version>` whose only job is to depend on your real implementation artifact. This is what lets consumers write `plugins { id("com.example.greeting") version "1.0" }`.

  • Where should the API key and secret live so they aren't committed?
    In `~/.gradle/gradle.properties` (outside the project) as `gradle.publish.key`/`gradle.publish.secret`, or in env vars `GRADLE_PUBLISH_KEY`/`GRADLE_PUBLISH_SECRET` for CI — never in the project's `gradle.properties` checked into VCS.
  • How can you check your metadata passes Portal validation without actually uploading?
    Run `./gradlew publishPlugins --validate-only`, which executes all validation/build steps but skips the upload.

saying these in an interview costs you the question

  • Claiming you publish with plain `maven-publish` to the Portal — you need `com.gradle.plugin-publish` and the `publishPlugins` task.
  • Saying the key/secret go in the project's committed `gradle.properties`.
  • Forgetting that `website`/`vcsUrl` are required Portal metadata.

context