Publishing artifacts

Gradle · Advanced · 10 min

Sharing a library with other teams or the world means producing a correct Maven publication.

The maven-publish plugin publishes a project's artifacts to any Maven-compatible repository: Maven Central (via Sonatype), a company Nexus/Artifactory, GitHub Packages, or mavenLocal() (~/.m2) for local testing.

Configure a publication from the java component and one or more repositories:

publishing {
    publications { create<MavenPublication>("maven") { from(components["java"]) } }
    repositories { maven { url = uri("https://nexus.acme.com/repository/maven-releases") ; credentials { ... } } }
}

This generates tasks like publishMavenPublicationToMavenRepository and the aggregate publish, plus publishToMavenLocal.

The component maps Gradle's api dependencies to Maven compile scope and implementation to runtime, so consumers using Maven get a sensible POM. Gradle also publishes a .module file with richer metadata (variants, capabilities) that Gradle consumers use.

Add java { withSourcesJar(); withJavadocJar() } to publish source and Javadoc jars, which Maven Central requires, together with POM metadata (name, description, URL, license, developers, SCM) set through pom { }. The signing plugin signs artifacts with GPG; Central also requires it.

Use group and version for the coordinates; -SNAPSHOT versions go to snapshot repositories and can be republished. Never put credentials in the script: read them from gradle.properties in the home directory or environment variables (providers.environmentVariable("NEXUS_TOKEN")).

Example

plugins { `java-library`; `maven-publish`; signing }
group = "com.acme"
version = "1.2.0"
java { withSourcesJar(); withJavadocJar() }
publishing {
    publications {
        create<MavenPublication>("maven") {
            from(components["java"])
            pom {
                name = "acme-core"
                description = "Core utilities for ACME services"
                url = "https://github.com/acme/core"
                licenses { license { name = "Apache-2.0" } }
                developers { developer { id = "ada"; name = "Ada L." } }
                scm { url = "https://github.com/acme/core" }
            }
        }
    }
    repositories {
        maven {
            name = "nexus"
            url = uri("https://nexus.acme.com/repository/maven-releases")
            credentials(PasswordCredentials::class)   // nexusUsername / nexusPassword properties
        }
    }
}
signing { useGpgCmd(); sign(publishing.publications["maven"]) }
// $ ./gradlew publishToMavenLocal      $ ./gradlew publish

Remember

  • maven-publish creates publications from the java component
  • api maps to Maven compile scope, implementation to runtime
  • withSourcesJar/withJavadocJar, POM metadata and signing are needed for Central
  • Keep credentials in properties or environment variables

Check yourself

  1. A consumer builds with Maven. How does your Gradle implementation dependency appear in the published POM?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: docs.gradle.org/current/userguide/publishing_maven.html

Builds on

Unlocks

Nothing builds on this yet.