Configure publication to Maven Central repository for Gradle projects with minimal effort.
- Simple: The core part of this plugin is very simple. You can even embed the core content of this project directly into your project configuration.
- Low conflict: This plugin only uses Gradle's public API and does not involve any internal Gradle API. You can use this plugin in many Gradle versions.
- Integrability:
- The core work of this plugin is to add a temporary local goal to maven-publish. This means that you can add your own target repository directly in maven-publish, and this plugin will not interfere with any of your custom target repositories.
- Because this plugin directly uses maven-publish to handle publishing, this plugin can be easily used with other
projects that can use gradle to publish.
For example:Java,Kotlin/JVM,Kotlin/Multiplatform,Android Library
- CI Friendly: Only 2 secrets required for processing publishing.
- Local Friendly: Provide a global option to use your local gpg agent for publishing.
- Low Configuration: Even if you don't define any information, this plugin can infer all the required information from the repository and write it to the pom.
- Customizable: Everything is configurable, see MavenPublishingExtension
- Configuration Cache support: This plugin supports gradle's configuration cache feature.
plugins {
// Full version of maven-center-publish
id "moe.karla.maven-publishing"
// Or else if you just want to sign up your publications
id "moe.karla.signing-setup"
}Goto Gradle Plugin Portal to view the latest version.
Tip
You don't need to configure the plugin in build.gradle
if you used moe.karla.signing-setup only.
Just goto the GPG Setup section and setup GPG configurations.
plugins {
id 'java'
id 'moe.karla.maven-publishing'
id 'maven-publish'
}
group = 'moe.karla.mptest'
version = '1.0.0'
description = 'The Example Project. Project description is included in maven pom.'
repositories {
mavenCentral()
}
mavenPublishing {
// Add This line if you want to verify your component before publishing.
publishingType = moe.karla.maven.publishing.MavenPublishingExtension.PublishingType.USER_MANAGED
url = 'https://github.com/YourUserName/YourProject'
developer('YourUserName', '[email protected]')
}
publishing {
publications {
main(MavenPublication) {
from(project.components.java)
}
}
}plugins {
java
id("moe.karla.maven-publishing")
`maven-publish`
}
group = "moe.karla.mptest"
version = "1.0.0"
description = "The Example Project. Project description is included in maven pom."
mavenPublishing {
// Add This line if you want to verify your component before publishing.
publishingType = moe.karla.maven.publishing.MavenPublishingExtension.PublishingType.USER_MANAGED
url = "https://github.com/YourUserName/YourProject"
developer("YourUserName", "[email protected]")
}
publishing {
publications {
register<MavenPublication>("maven") {
from(project.components["java"])
}
}
}
plugins {
id 'java'
id 'moe.karla.maven-publishing'
id 'maven-publish'
}
group = 'moe.karla.mptest'
version = '1.0.0'
repositories {
mavenCentral()
}
publishing {
publications {
main(MavenPublication) {
from(project.components.java)
}
}
}This section is for people who want to set up maven pom manually
plugins {
id 'java'
id 'moe.karla.maven-publishing'
id 'maven-publish'
}
mavenPublishing {
// Add This line if you want to verify your component before publishing.
publishingType = moe.karla.maven.publishing.MavenPublishingExtension.PublishingType.USER_MANAGED
manuallyPomSetup = true
}
publishing {
publications {
main(MavenPublication) {
from(project.components.java)
pom {
// .....
}
}
}
}
Important
Based on Sonatype's requirements, you must set up GPG to push your software to Maven Central.
For GPG Installation and key generation, see https://central.sonatype.org/publish/requirements/gpg/
-
Type
gpg --list-secret-keysto confirm the sign key you want to use.C:\Users\karlatemp>gpg --list-secret-keys /c/Users/karlatemp/.gnupg/pubring.kbx ------------------------------------- sec ed25519 2024-10-18 [SC] C369D088F3CDAD2C7759D03A281BC3003E644D8C ## This is key id uid [ultimate] Tester <[email protected]> ssb cv25519 2024-10-18 [E] -
Type
gpg --armor --export-secret-key [email protected]orgpg --armor --export-secret-key KEYIDC:\Users\karlatemp>gpg --armor --export-secret-key [email protected] -----BEGIN PGP PRIVATE KEY BLOCK----- ........................ -----END PGP PRIVATE KEY BLOCK----- -
Create a file named
data.json(or any name you want). Fill with following content.{ // NOTE: Don't write comments into your file. // Don't drop line breaks. An empty line is required for gradle to read the key "key": "-----BEGIN PGP PRIVATE KEY BLOCK-----\n\n.....\n-----END PGP PRIVATE KEY BLOCK-----", // Optional. When the key has no password, remove this field "keyPassword": "The Password Of Your Key", // Optional. This field is optional. Used when you want to use a sub key to sign publications "keyId": "Sub Key Id" }
You can also use the provided script
bash key-export.shto generate this content. -
(This step is only for validating signing setup) Open your user
gradle.properties. Addsigning.setup.file=/path/to/your/data.json. And then executegradle testSigningin your project.https://docs.gradle.org/current/userguide/build_environment.html
-
Create an account and generate User Token on https://central.sonatype.com/account
-
Goto your actions secrets settings.
-
Create a secret named
MAVEN_CENTRAL_PUBLISH_GPGwith the content ofdata.json -
Create a secret named
MAVEN_CENTRAL_PUBLISH_ACCOUNTwith valueUserName:UserToken -
Change your workflow with
jobs: publish: runs-on: ubuntu-latest env: SIGNING_SETUP: ${{ secrets.MAVEN_CENTRAL_PUBLISH_GPG }} MAVEN_PUBLISH_PASSWORD: ${{ secrets.MAVEN_CENTRAL_PUBLISH_ACCOUNT }} steps: - uses: actions/checkout@v4 - name: Set up JDK 21 uses: actions/setup-java@v4 with: java-version: '21' distribution: 'zulu' # Configure Gradle for optimal use in GitHub Actions, including caching of downloaded dependencies. # See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md - name: Setup Gradle uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0 with: gradle-version: wrapper - run: gradle cleanMavenPublishingStage build publishAllPublicationsToMavenStageRepository # - run: gradle packMavenPublishingStage - run: gradle publishToMavenCentral
In addition, you can specify the username and password separately for other scenarios where you need to separate the username and password.
jobs: publish: runs-on: ubuntu-latest env: SIGNING_SETUP: ${{ secrets.MAVEN_CENTRAL_PUBLISH_GPG }} MAVEN_PUBLISH_USER: ${{ secrets.MAVEN_CENTRAL_PUBLISH_USER }} MAVEN_PUBLISH_PASSWORD: ${{ secrets.MAVEN_CENTRAL_PUBLISH_TOKEN }} steps: - ...
Add following values to your gradle.properties
Important
Never add your secrets into the gradle.proerties in your project!
You should add it in GRADLE_USER_HOME/gradle.properties
https://docs.gradle.org/current/userguide/build_environment.html
# Maven Central Setup
maven.publish.password=UserName:UserToken
# Local GPG Setup
# Way 1: Setting up using CI configuration
signing.setup.file=/path/to/your/data.json
# Way 2: Setting up using local GPG command
#
# When you choose to use local GPG command to sign, you must set up the gradle signing settings manually.
# See https://docs.gradle.org/current/userguide/signing_plugin.html#sec:using_gpg_agent
#
# NOTE: This option has the highest priority.
# When you're testing your CI configuration. Run with following command:
# ./gradlew testSigning -Psigning.manually=false
signing.manually=trueThe signing.manually property control how maven-publishing setup GPG signing.
You can define this behavior in the project level options via
creating gradle.properties in your root project.
Options can be separated by , to reference multiple options at once.
| Flag Name | Description |
|---|---|
notest |
Disable registering testSigning task |
nouse |
Don't setup the signing extension Useful when you already setup the signing by yourself. |
nopub |
Disable automatic registering publications to the signing extension |
gpgcmd |
Use gpg agent. No effect if nouse applied. |
| --- | |
true |
Alias of gpgcmd |
all |
Alias of notest,nouse,nopub |
Cleanup the local temporary staging repository.
You need to execute this task when you locally publish your software.
This task well be executed when
gradle cleanexecuted.
Publish all publications to the local staging repository.
Publish everything in stage repository to maven central.
Test the signing configuration.
- Apply
moe.karla.maven-publishingto the rootbuild.gradleand only the root script. - Setup
mavenPublishingin the root project. - Apply
maven-publishand configure publication on the modules you want to publish.
publishing {
publications {
release(MavenPublication) {
groupId = 'com.my-company'
artifactId = 'my-library'
version = '1.0'
- from(project.components.java)
+ afterEvaluate {
+ from(components.release)
+ }
}
}
}https://developer.android.com/build/publish-library/upload-library#create-pub
## rootProject/gradle/libs.versions.toml
[libraries]
androidLibrary = { id = "com.android.library", version.ref = "agp" }
kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
mavenPublishing = { id = "moe.karla.maven-publishing", version = "1.3.1" }// rootProject/build.gradle.kts
plugins {
alias(libs.plugins.androidLibrary) apply false
alias(libs.plugins.kotlinMultiplatform) apply false
// id("moe.karla.maven-publishing")
alias(libs.plugins.mavenPublishing)
}
mavenPublishing {
// Add This line if you want to verify your component before publishing.
publishingType = moe.karla.maven.publishing.MavenPublishingExtension.PublishingType.USER_MANAGED
}// rootProject/library/build.gradle.kts
plugins {
alias(libs.plugins.kotlinMultiplatform)
alias(libs.plugins.androidLibrary)
`maven-publish`
}
group = "moe.karla.mptest"
version = "1.0.0"
kotlin {
// ...
}
// NOTE:
// You don't need to configure the `publishing` extension.
// Everything you need was already completed by kotlin-multiplatform and the maven-publishing plugin
//
// Technology:
// publications:
// Publications are registered automatically when you applied
// kotlinMultiplatform and `maven-publish`
// the `-sources.jar`:
// The sources jars are automatically registered by kotlinMultiplatform
// the `-javadoc.jar`:
// An empty stub javadoc jar will be attached to all available publications by
// maven-publishing plugin to pass central publishing rule
// the .asc sign files:
// maven-publishing plugin will register all publications to the signing extension
// the .pom:
// maven-publishing will fill all necessary fields to all publication pom files
//publishing {
//}