Anyone who has published an open source library knows the pain: getting a library published to Maven Central through Sonatype is far from simple. You need to meet a long list of requirements, and for Gradle projects, even though everything uses the maven-publish plugin, the configuration differs across project types – Gradle Plugin, Android Library, and Java Library all have their quirks. In a multi-module Gradle project, writing nearly identical but subtly different DSL blocks for each module is tedious, and Gradle‘s DSL can be bewildering for newcomers.
Sonatype
Sonatype provides automatic syncing to Maven Central, but publishing to it requires several steps:
Unlike Java/Kotlin Library projects, Android Library projects need to generate sources and javadoc JARs for each variant. When necessary, you also need to publish an AAR for each variant. This is typically done by iterating over all variants via android.libraryVariants:
1 2 3 4 5
val android = extensions.getByName("android") as LibraryExtension
android.libraryVariants.forEach { variant -> // Register a MavenPublication for each variant }
Since libraryVariants is configured lazily, this must be executed inside a project.afterEvaluate callback. The complete code looks like this:
Gradle officially provides java-gradle-plugin for generating Gradle Plugin-related POM files, but its output only includes Maven coordinates and basic project info – nowhere near enough for Sonatype‘s requirements. Developers need to configure the rest manually, but Gradle’s official documentation doesn’t explain how to modify the POM generated by java-gradle-plugin. It’s actually not hard – just different from Java/Kotlin Library and Android Library projects. Since java-gradle-plugin already creates MavenPublication instances automatically, you don’t need to create or register new ones. Just iterate over the existing ones and append the required POM information. The complete code:
After looking at the publishing configurations for different project types above, you’ll notice that most of the code is nearly identical. In a multi-module project, this becomes a real hassle – some modules need to be published and others don’t, and using allprojects or subprojects doesn’t simplify things much. Since the code is so similar, can we make the whole thing simpler? The answer is yes – and that’s exactly what sonatype-publish-plugin was built for. It truly takes just one line:
1 2 3 4 5 6
plugins { id("io.johnsonlee.sonatype-publish-plugin") version "1.3.0" }
group = "io.johnsonlee" version = "1.0.0"
Just configure the appropriate environment variables and you can upload directly via command line:
The plugin also supports publishing to private Nexus repositories, such as a company’s internal Nexus server. Just configure these properties or environment variables:
NEXUS_URL
NEXUS_USERNAME
NEXUS_PASSWORD
Then publish to your private Nexus repository with: