CMP/Android Library Publication to Maven Central
In this article, we’ll explore the process of publishing an Android/CMP/KMP library to Maven Central.
CMP/Android Library Publication to Maven Central
In this article, we’ll explore the process of publishing an Android/CMP/KMP library to Maven Central.

Phase 1: Machine & Keyservers Setup (One-Time)
1. Setup Your GPG Key
If you don’t have a clean, single-line GPG private key ready, run this on your terminal:
gpg --full-generate-key
# Choose RSA and RSA, keysize = 4096 bits, expiration = 0(for no expiration).
# Set a Passphrase [signing.password] you never forget.
2. Get your short Key ID — [signing.keyId]
gpg --list-secret-keys --keyid-format SHORT
#Look at the output line beginning with sec.
#It will resemble something like this: rsa4096/2B906A2C.
#Here, 2B906A2C is your Key ID.
3. Upload your key to the servers
Sonatype verifies the metadata signature of your uploaded artifacts against global keyservers. If your public key isn’t indexed, your deployment will be rejected instantly:
gpg --keyserver keyserver.ubuntu.com --send-keys YOUR_KEY_ID
4. Export your secret key — [signing.secretKey]
We need to export your private key into a single, continuous line where string breaks are explicitly formatted as literal \n character combinations.
# On macOS:
gpg --export-secret-keys --armor YOUR_KEY_ID | awk 'ORS="\\n"'
# On Linux:
gpg --export-secret-keys --armor YOUR_KEY_ID | awk '{printf "%s\\n", $0}'
Copy the full text output safely to your clipboard.
Phase 2: Configure Global Credentials File
To ensure your keys apply to all projects safely without risking credential leakage into GitHub repos, store your properites in local.properties and whenever you are publishing copy it to gradle.properties [Reference]
gradle.properties
# Sonatype User Token (Do NOT use your portal account password here.
# Generate an Token via https://central.sonatype.com/-> Account -> User Tokens -> Generate User Token)
mavenCentralUsername=token_keyid
mavenCentralPassword=token_password
[You can find keys mapping above in the steps]
signing.keyId=YOUR_KEY_ID
signing.password=YOUR_GPG_PASSPHRASE
signing.secretKey=-----BEGIN PGP PRIVATE KEY BLOCK-----\n...\n-----END PGP PRIVATE KEY BLOCK-----\n
Phase 3: The Project Configuration Script
With your machine prepared, let’s wire up your build system.
1. Root build.gradle.kts [[Reference]](https://github.com/ankitk77/coachmark/blob/master/build.gradle.kts#L8)
plugins {
id("com.vanniktech.maven.publish") version "0.28.0" apply false
...
}
2. Module-Level build.gradle.kts[Reference]
Open the subproject module containing your shared library architecture components and configure the publishing plugin:
import com.vanniktech.maven.publish.SonatypeHost
import com.vanniktech.maven.publish.KotlinMultiplatform
plugins {
..
id("com.vanniktech.maven.publish") // Apply the publishing engine here
signing // Enables conditional signing guards below
}
mavenPublishing {
coordinates(
groupId = "io.github.yourusername",
artifactId = "your-library-name",
version = "1.0.0" // Use "1.0.0-SNAPSHOT" if testing staging snapshots
)
pom {
name.set("Your Library Title")
description.set("A concise declaration outlining your framework's utility.")
inceptionYear.set("2026")
url.set("https://github.com/yourusername/repo")
licenses {
license {
name.set("The Apache License, Version 2.0")
url.set("http://www.apache.org/licenses/LICENSE-2.0.txt")
}
}
developers {
developer {
id.set("yourusername")
name.set("Your Name")
}
}
scm {
url.set("https://github.com/yourusername/repo")
connection.set("scm:git:git://github.com/yourusername/repo.git")
developerConnection.set("scm:git:ssh://github.com/yourusername/repo.git")
}
}
configure(KotlinMultiplatform(javadocJar = com.vanniktech.maven.publish.JavadocJar.Empty()))
publishToMavenCentral(SonatypeHost.CENTRAL_PORTAL, automaticRelease = true)
signAllPublications()
}
val properties = Properties().apply {
val file = rootProject.file("gradle.properties")
if (file.exists()) {
file.inputStream().use { load(it) }
}
}
signing {
val keyId = properties.getProperty("signing.keyId")
val password = properties.getProperty("signing.password")
val secretKey = properties.getProperty("signing.secretKey")
if (!keyId.isNullOrEmpty() && !secretKey.isNullOrEmpty()) {
useInMemoryPgpKeys(keyId, secretKey, password)
}
}
Phase 4: The Command Execution Runbook
Local Testing Environments
Bash
./gradlew publishAllPublicationsToMavenLocal
Production Distribution
When code is verified and ready for public ingestion, run the primary target repository task.
./gradlew publishAllPublicationsToMavenCentralRepository
Because automaticRelease = true is declared in our script configuration, as soon as Sonatype completes its automated structural and signature integrity scanning, your library variants will drop directly into production!
Happy coding! 🚀
메타데이터
- post_id
- 0a33595fa0ef
- slug
- cmp-android-library-publication-to-maven-central-0a33595fa0ef
- url
- https://medium.com/@ankitk77/cmp-android-library-publication-to-maven-central-0a33595fa0ef
- canonical_url
- https://medium.com/@ankitk77/cmp-android-library-publication-to-maven-central-0a33595fa0ef
- author_url
- https://medium.com/@ankitk77
- status
- ok
- fetched_at
- 2026-07-25 22:00:12