# Part 8: Publish your Plugin Locally

version 9.5.0-20260319005705+0000

Learn how to verify your plugin can be published by pushing it to a local Maven repository, then consuming it like any external plugin.

In this section, you’ll:

- Update your plugin with publishable metadata

- Publish your plugin to a local throwable Maven repository

- Use the published version of the plugin in the `consumer` project

## Step 0: Before you Begin

1. You initialized your plugin in part 1.

2. You added an extension to your plugin in part 2.

3. You created a custom task in part3.

4. You wrote a unit test in part 4.

5. You added a dataflow action to your plugin in part 5.

6. You wrote a functional test in part 6.

7. You created a dummy consumer project in part 7.

## Step 1: Add Plugin Metadata

In your `plugin/build.gradle(.kts)` file, apply the `maven-publish` plugin and make sure you have the `group` and `version` defined:

plugin/build.gradle.kts

    plugins {
        // Apply the Java Gradle plugin development plugin to add support for developing Gradle plugins
        `java-gradle-plugin`
        // Apply the Maven Publishing plugin
        id("maven-publish")
        // Apply the Kotlin JVM plugin to add support for Kotlin.
        id("org.jetbrains.kotlin.jvm") version "2.0.0"
    }

    group = "org.example"
    version = "1.0.0"

    repositories {
        // Use Maven Central for resolving dependencies.
        mavenCentral()
    }

    dependencies {
        // Use the Kotlin JUnit 5 integration.
        testImplementation("org.jetbrains.kotlin:kotlin-test-junit5")
        testRuntimeOnly("org.junit.platform:junit-platform-launcher")
        // Use the Java Slack Client APIs
        implementation("com.slack.api:slack-api-client:1.45.3")
    }

    gradlePlugin {
        // Define the plugin
        plugins {
            create("slack") {
                id = "org.example.slack"
                implementationClass = "org.example.SlackPlugin"
            }
        }
    }

plugin/build.gradle

    plugins {
        // Apply the Java Gradle plugin development plugin to add support for developing Gradle plugins
        id 'java-gradle-plugin'
        // Apply the Maven Publishing plugin
        id('maven-publish')
        // Apply the Groovy plugin to add support for Groovy
        id 'groovy'
    }

    group = 'org.example'
    version = '1.0.0'

    repositories {
        // Use Maven Central for resolving dependencies.
        mavenCentral()
    }

    dependencies {
        // Use the awesome Spock testing and specification framework
        testImplementation 'org.spockframework:spock-core:2.3-groovy-4.0'
        testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
        // Use the Java Slack Client APIs
        implementation("com.slack.api:slack-api-client:1.45.3")
    }

    gradlePlugin {
        // Define the plugin
        plugins {
            slack {
                id = 'org.example.slack'
                implementationClass = 'org.example.SlackPlugin'
            }
        }
    }

| The `group` and `version` must be set or the `publish` task will fail.

## Step 2: Publish to a Local Folder

Use the `publishing {}` block from the `maven-publish` plugin to add a Maven repository that points to `build/local-repo` in your plugin’s build file:

plugin/build.gradle.kts

    publishing {
        repositories {
            maven {
                name = "localRepo"
                url = layout.buildDirectory.dir("local-repo").get().asFile.toURI()
            }
        }
    }

plugin/build.gradle

    publishing {
        repositories {
            maven {
                name = 'localRepo'
                url = layout.buildDirectory.dir('local-repo').get().asFile.toURI()
            }
        }
    }

Publish the plugin:

    ./gradlew :plugin:publishAllPublicationsToLocalRepoRepository

    > Task :plugin:checkKotlinGradlePluginConfigurationErrors SKIPPED
    > Task :plugin:pluginDescriptors UP-TO-DATE
    > Task :plugin:processResources UP-TO-DATE
    > Task :plugin:generatePomFileForPluginMavenPublication
    > Task :plugin:generatePomFileForSlackPluginMarkerMavenPublication
    > Task :plugin:publishSlackPluginMarkerMavenPublicationToLocalRepoRepository
    > Task :plugin:compileKotlin
    > Task :plugin:compileJava NO-SOURCE
    > Task :plugin:classes UP-TO-DATE
    > Task :plugin:jar
    > Task :plugin:generateMetadataFileForPluginMavenPublication
    > Task :plugin:publishPluginMavenPublicationToLocalRepoRepository
    > Task :plugin:publishAllPublicationsToLocalRepoRepository

    BUILD SUCCESSFUL in 1s
    9 actionable tasks: 7 executed, 2 up-to-date

You should now see artifacts under `plugin/build/local-repo/`. Take a moment to look at these files.

## Step 3: Configure the Local Repository in `consumer`

Point your consumer build to that repo and apply the plugin with a version:

consumer/settings.gradle.kts

    pluginManagement {
        repositories {
            maven {
                url = file("../plugin/build/local-repo").toURI()
            }
            gradlePluginPortal()
        }
    }

consumer/settings.gradle

    pluginManagement {
        repositories {
            maven {
                url = file('../plugin/build/local-repo').toURI()
            }
            gradlePluginPortal()
        }
    }

## Step 4: Apply the Plugin in the `consumer` Project

consumer/build.gradle.kts

    plugins {
        id("java")
        id("org.example.slack") version "1.0.0"
    }

consumer/build.gradle

    plugins {
        id("java")
        id 'org.example.slack' version '1.0.0'
    }

Now run something in the consumer (e.g., your `test` task or `build`):

    ./gradlew :consumer:build

You’ve now proven the plugin is publishable and consumable like a real, external plugin, no portals or private repos required.

You can easily clean up the artifacts by running `rm -rf plugin/build/local-repo` if you want to republish from scratch.

Congratulations, you have completed the tutorial!