Preparing to Publish Plugins
To share a Gradle plugin, package it into JAR files and generate the accompanying metadata so other builds can resolve and apply it.
Gradle’s publishing plugins add tasks and conventions to prepare artifacts and metadata for distribution to repositories such as a local Maven repository, Maven Central, JFrog Artifactory, or the Gradle Plugin Portal.
Applying a Publishing Plugin
Apply one or more publishing plugins in your plugin project:
-
For the Gradle Plugin Portal: Plugin Publish Plugin
-
For Maven repositories (e.g., Maven Central, Artifactory, GitHub Packages): Maven Publish Plugin
-
For Ivy repositories: Ivy Publish Plugin
plugins {
id("maven-publish") // Maven
id("ivy-publish") // Ivy
id("com.gradle.plugin-publish") version "<latest-version>" // Plugin Portal
}
Applying a publishing plugin registers tasks that assemble your plugin JAR(s) and generate metadata files (POM, Gradle Module Metadata, and the plugin marker module).
Minimum Configuration
A plugin project must at least declare:
-
A plugin ID and implementation class (so Gradle knows what to apply)
-
A group and version (so the plugin can be published and resolved)
group = "org.example"
version = "1.0"
gradlePlugin {
plugins.create("greeting") {
id = "org.example.greeting"
implementationClass = "org.example.GreetingPlugin"
}
}
group = 'org.example'
version = '1.0'
gradlePlugin {
plugins.create('greeting') {
id = 'org.example.greeting'
implementationClass = 'org.example.GreetingPlugin'
}
}
This lets Gradle generate the plugin marker module (org.example.greeting.gradle.plugin) and other metadata required by repositories and consumers.
Local Publishing and Testing
Before publishing remotely, publish to a local Maven directory:
publishing {
repositories {
maven { url = uri(layout.buildDirectory.dir("local-repo")) }
}
}
publishing {
repositories {
maven { url = layout.buildDirectory.dir('local-repo') }
}
}
Run:
./gradlew publish
Gradle writes plugin artifacts and metadata to build/local-repo:
build/local-repo/
└── org/
└── example/
├── greeting/
│ └── 1.0.0/
│ ├── greeting-1.0.0.jar // compiled plugin classes
│ ├── greeting-1.0.0.jar.sha1 // checksum (SHA-1)
│ ├── greeting-1.0.0.jar.sha256 // checksum (SHA-256)
│ ├── greeting-1.0.0.module // Gradle Module Metadata (variants, capabilities, deps)
│ ├── greeting-1.0.0.module.sha1
│ ├── greeting-1.0.0.module.sha256
│ ├── greeting-1.0.0.pom // Maven POM: GAV + dependencies
│ ├── greeting-1.0.0.pom.sha1
│ ├── greeting-1.0.0.pom.sha256
│ └── greeting-1.0.0-sources.jar // optional (java { withSourcesJar() })
│ ├── greeting-1.0.0-sources.jar.sha1
│ └── greeting-1.0.0-sources.jar.sha256
│
└── org.example.greeting.gradle.plugin/
└── 1.0.0/
├── org.example.greeting.gradle.plugin-1.0.0.module // plugin marker metadata
├── org.example.greeting.gradle.plugin-1.0.0.module.sha1
├── org.example.greeting.gradle.plugin-1.0.0.module.sha256
├── org.example.greeting.gradle.plugin-1.0.0.pom // plugin marker POM
├── org.example.greeting.gradle.plugin-1.0.0.pom.sha1
└── org.example.greeting.gradle.plugin-1.0.0.pom.sha256
You’ll see:
-
Plugin JAR(s) — compiled classes
-
.pom— Maven metadata (coordinates, dependencies) -
.module— Gradle Module Metadata (variants, capabilities) -
Plugin marker module — enables
plugins { id("…") }resolution by plugin ID -
Optional sources JAR — if enabled via
withSourcesJar() -
Checksums — integrity files (many repos prefer SHA-256/SHA-512)
To consume locally, point the consumer project’s pluginManagement to the local repo:
pluginManagement {
repositories {
maven {
url = uri("../plugin/build/local-repo")
}
gradlePluginPortal()
}
}
pluginManagement {
repositories {
maven {
url = uri('../plugin/build/local-repo')
}
gradlePluginPortal()
}
}
Consumers can then apply your plugin by ID without publishing to a public repository.
Validating
To validate a Plugin Portal publication (no upload):
$ ./gradlew publishPlugins --validate-only