ani2fun / sonatype-maven-central-publisher

9 stars 1 forks source link

Gradle Plugin for publishing to central sonatype maven repository

The Maven Central Publisher Plugin is a Gradle plugin designed to streamline the process of publishing artifacts to Maven Central repository. Currently, it supports publishing Java Libraries, Gradle Version Catalog files and Spring Boot Application.

Sample projects illustrating the publishing of Java libraries, version catalogs, and Spring Boot applications using this plugin can be accessed at: https://github.com/ani2fun/plugin-demo

[!NOTE] This project serves as a temporary solution. As a Gradle user, I found a gap in the existing plugins suited to my requirements at the time. It encourage me to develop a custom solution to publish various artifacts to sonatype central repository, which includes Java libraries and Spring Boot applications and Gradle Version-Catalog. Looking ahead, more efficient solutions will be arriving, either through direct enhancements from platform developers or Gradle engineers. This project presents a valuable opportunity to learn Gradle plugin development

Follow these steps to integrate and configure the plugin for your project:

1. Apply the Plugin

Apply the plugin in your build.gradle.kts file:

plugins {
    id("eu.kakde.gradle.sonatype-maven-central-publisher") version "1.0.6"
}

2. Configure GPG Signing

Ensure that GPG signing is correctly configured for your project using the Gradle signing extension. You can find more information on signing publication for Gradle here.

Below is sample configuration for gradle.properties file:

##############################
# GPG Credentials
# Last 8 characters in your GPG public key
signing.keyId=<ABCD1234>
# Your signing passphrase
signing.password=<gpg_passphrase>
# private key secring.gpg file path: /Users/jondoe/.gnupg/secring.gpg
signing.secretKeyRingFile=<file_path>

# sonatype credentials
sonatypeUsername=<username>
sonatypePassword=<password>
##############################

Please note that the GPG configuration format mentioned above is utilized for testing the publication to the new Maven Central repository, covering the following artifacts:

3. Configure Publication

Add the sonatypeCentralPublishExtension to configure the publication:

[!NOTE] Specify the component type as "java" for publishing Java artifacts (which includes Java libraries or Spring Boot applications), or "versionCatalog" for publishing a version catalog.

The sample configuration block in build.gradle.kts appears as follows:

// ------------------------------------
// PUBLISHING TO SONATYPE CONFIGURATION
// ------------------------------------
object Meta { 
  val COMPONENT_TYPE = "java" // "java" or "versionCatalog"
  val GROUP = "eu.kakde.plugindemo"
  val ARTIFACT_ID = "samplelib"
  val VERSION = "1.0.0"
  val PUBLISHING_TYPE = "AUTOMATIC" // USER_MANAGED or AUTOMATIC
  val SHA_ALGORITHMS = listOf("SHA-256", "SHA-512") // sha256 and sha512 are supported but not mandatory. Only sha1 is mandatory but it is supported by default.
  val DESC = "GitHub Version Catalog Repository for Personal Projects based on Gradle"
  val LICENSE = "Apache-2.0"
  val LICENSE_URL = "https://opensource.org/licenses/Apache-2.0"
  val GITHUB_REPO = "ani2fun/plugin-demo.git"
  val DEVELOPER_ID = "ani2fun"
  val DEVELOPER_NAME = "Aniket Kakde"
  val DEVELOPER_ORGANIZATION = "kakde.eu"
  val DEVELOPER_ORGANIZATION_URL = "https://www.kakde.eu"
}

val sonatypeUsername: String? by project // this is defined in ~/.gradle/gradle.properties
val sonatypePassword: String? by project // this is defined in ~/.gradle/gradle.properties

sonatypeCentralPublishExtension {
    // Set group ID, artifact ID, version, and other publication details
    groupId.set(Meta.GROUP)
    artifactId.set(Meta.ARTIFACT_ID)
    version.set(Meta.VERSION)
    componentType.set(Meta.COMPONENT_TYPE) // "java" or "versionCatalog"
    publishingType.set(Meta.PUBLISHING_TYPE) // USER_MANAGED or AUTOMATIC

    // Set username and password for Sonatype repository
    username.set(System.getenv("SONATYPE_USERNAME") ?: sonatypeUsername)
    password.set(System.getenv("SONATYPE_PASSWORD") ?: sonatypePassword)

    // Configure POM metadata
    pom {
        name.set(Meta.ARTIFACT_ID)
        description.set(Meta.DESC)
        url.set("https://github.com/${Meta.GITHUB_REPO}")
        licenses {
            license {
                name.set(Meta.LICENSE)
                url.set(Meta.LICENSE_URL)
            }
        }
        developers {
            developer {
                id.set(Meta.DEVELOPER_ID)
                name.set(Meta.DEVELOPER_NAME)
                organization.set(Meta.DEVELOPER_ORGANIZATION)
                organizationUrl.set(Meta.DEVELOPER_ORGANIZATION_URL)
            }
        }
        scm {
            url.set("https://github.com/${Meta.GITHUB_REPO}")
            connection.set("scm:git:https://github.com/${Meta.GITHUB_REPO}")
            developerConnection.set("scm:git:https://github.com/${Meta.GITHUB_REPO}")
        }
        issueManagement {
            system.set("GitHub")
            url.set("https://github.com/${Meta.GITHUB_REPO}/issues")
        }
    }
}

5. Finally, to Publish your Projects to Sonatype Central

Follow these steps:

You'll see the deployment response in the console:

    > Task :plugin-demo:getDeploymentStatus

    Executing 'getDeploymentStatus' task... With parameter deploymentId=8dad65c2-8f66-4585-bb1e-20a8f19e22fd
    Deployment Status:
    {
      "deploymentId": "8dad65c2-8f66-4585-bb1e-20a8f19e22fd",
      "deploymentName": "eu.kakde.plugindemo:samplelib:1.0.3",
      "deploymentState": "PENDING",
      "purls": [],
      "errors": {
        "common": [
          "Deployment components info not found"
        ]
      }
    }

Side note:

You can test the plugin locally by publishing it and then importing it into the corresponding project. Run the following command to publish the plugin to your local Maven repository:

./gradlew :plugin:publishToMavenLocal

This command will publish the plugin to your local Maven repository, making it available for use in other projects on your local environment using the same way as in 1.Apply the Plugin section.