This document explains how to publish Compose-Settings library to Maven Central.
The publishing process is fully automated through GitHub Actions and uses:
- Convention Plugin: Maven publishing configuration integrated in
ComposeLibraryConventionPlugin - In-Memory GPG Signing: No local keyring files needed
- GitHub Actions: Automated building, signing, and publishing
- Maven Central Portal: Modern Sonatype publishing endpoint
All library modules (ui-core, ui-tiles, ui-tiles-extended, ui-tiles-expressive) use the
compose.library convention plugin which automatically configures:
Location: build-logic/convention/src/main/kotlin/ComposeLibraryConventionPlugin.kt
What it does:
- Applies
com.vanniktech.maven.publishplugin - Applies
signingplugin for GPG signatures - Configures Maven Central publishing endpoint
- Sets up POM metadata (name, description, licenses, developers, SCM)
- Reads
libGroupandlibVersionfromgradle.properties
Key Configuration:
extensions.configure<MavenPublishBaseExtension> {
publishToMavenCentral(validateDeployment = false)
signAllPublications()
pom { configurePom(this) }
}
group = findProperty("libGroup")?.toString() ?: "com.alorma.compose.settings"
version = findProperty("libVersion")?.toString() ?: "0.0.1"Each library module only needs to apply the plugin:
plugins {
id("compose.library")
}The convention plugin handles all publishing configuration automatically.
- Key ID:
54137F1B26EEAF35 - Email:
bernatbor15@gmail.com - Expires: 2027-12-23
gpg --edit-key 54137F1B26EEAF35
# In GPG prompt:
expire # Extend primary key
2y # Set to 2 years
key 1 # Select subkey
expire # Extend subkey
2y # Set to 2 years
save # Save and quit# Export in ASCII-armored format
gpg --export-secret-keys --armor 54137F1B26EEAF35Copy the entire output (including BEGIN and END lines) to the GPG_KEY secret in GitHub.
Navigate to: GitHub.com → Repository → Settings → Secrets and variables → Actions
| Secret Name | Description | How to Get It |
|---|---|---|
GPG_KEY |
Your GPG private key | gpg --export-secret-keys --armor 54137F1B26EEAF35 |
GPG_PASSWORD |
Passphrase for the GPG key | The password you use to unlock the key |
MAVEN_CENTRAL_USERNAME |
Sonatype username/token | From https://central.sonatype.com/ |
MAVEN_CENTRAL_PASSWORD |
Sonatype password/token | From https://central.sonatype.com/ |
Triggers: On pull requests to main
Steps:
- Builds all library modules
- Builds all sample apps
- Checks GPG signatures
- Publishes to Maven Local (test)
- Dry run publish to Maven Central
Purpose: Validates that builds and signing work before merging.
Triggers: On push to main branch
Steps:
- Builds all library modules
- Builds all sample apps
- Checks GPG signatures
- Publishes to Maven Local (test)
- Dry run publish to Maven Central
- Deploys documentation to GitHub Pages
Purpose: Continuous validation of main branch.
Triggers: Manual (workflow_dispatch)
Steps:
- Reads current version from
gradle.properties - Builds all library modules
- Builds all sample apps
- Checks GPG signatures
- In Parallel:
- Publishes to Maven Central
- Creates GitHub release with tag
- Calculates next version (increments minor, resets patch to 0)
- Updates
gradle.propertieswith next version - Commits and pushes version update to
main
Example Flow:
- Current version:
2.18.0 - Published version:
2.18.0 - GitHub tag created:
v2.18.0 - Next version set:
2.19.0
Versions are stored in gradle.properties:
libGroup=com.alorma.compose.settings
libVersion=2.18.0The convention plugin reads these properties and applies them to all library modules.
-
Ensure main branch is ready:
- All features merged
- Tests passing
- Version in
gradle.propertiesis what you want to release
-
Trigger the workflow:
- Go to GitHub Actions tab
- Select "Publish and Release" workflow
- Click "Run workflow"
- Select
mainbranch - Click "Run workflow"
-
Monitor the workflow:
- Watch the GitHub Actions run
- Check for any failures
- Verify Maven Central publication
- Verify GitHub release creation
-
Automatic version bump:
- The workflow automatically bumps to next minor version
- Commits the change back to
main - You don't need to manually update the version
Test signing (requires GPG password):
./gradlew :ui-tiles:signKotlinMultiplatformPublicationTest local publish:
./gradlew publishToMavenLocalNote: Local testing without environment variables will fail at signing step. This is expected and safe.
Test with credentials (for advanced testing):
export ORG_GRADLE_PROJECT_signingInMemoryKey="$(gpg --export-secret-keys --armor 54137F1B26EEAF35)"
export ORG_GRADLE_PROJECT_signingInMemoryKeyPassword="your-password"
export ORG_GRADLE_PROJECT_mavenCentralUsername="your-username"
export ORG_GRADLE_PROJECT_mavenCentralPassword="your-password"
./gradlew publishToMavenLocalThe com.vanniktech.maven.publish plugin automatically detects and uses in-memory GPG keys when
these environment variables are set:
env:
ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.GPG_KEY }}
ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.GPG_PASSWORD }}Benefits:
- No keyring files to manage
- Works seamlessly in CI/CD
- More secure (keys never touch disk)
- Cross-platform compatible
How it works:
- GitHub Actions sets environment variables from secrets
- Gradle picks them up as project properties
- vanniktech plugin passes them to Gradle's signing plugin
- Signing plugin uses in-memory key for all signatures
Each library module publishes multiple artifacts for each platform:
com.alorma.compose.settings:ui-core:$version- Platform variants:
-android,-desktop,-iosarm64,-iossimulatorarm64,-iosx64,-js,-wasmjs
com.alorma.compose.settings:ui-tiles:$version- Platform variants:
-android,-desktop,-iosarm64,-iossimulatorarm64,-iosx64,-js,-wasmjs
com.alorma.compose.settings:ui-tiles-extended:$version- Platform variants:
-android,-desktop,-iosarm64,-iossimulatorarm64,-iosx64,-js,-wasmjs
com.alorma.compose.settings:ui-tiles-expressive:$version- Platform variants:
-android,-desktop,-iosarm64,-iossimulatorarm64,-iosx64,-js,-wasmjs
Cause: Missing or incorrect GPG configuration.
Solution:
- Verify
GPG_KEYsecret contains the full ASCII-armored key - Verify
GPG_PASSWORDsecret is correct - Check GitHub Actions logs for environment variable presence
Cause: Invalid Maven Central credentials.
Solution:
- Verify
MAVEN_CENTRAL_USERNAMEsecret - Verify
MAVEN_CENTRAL_PASSWORDsecret - Check if token has expired at https://central.sonatype.com/
Cause: Trying to publish a version that's already published.
Solution:
- Update
libVersioningradle.properties - Commit and push the change
- Trigger the publish workflow again
Cause: GPG key passed its expiration date.
Solution:
- Renew the key (see "Renewing the GPG Key" section)
- Export the renewed key
- Update the
GPG_KEYsecret in GitHub - Retry the workflow
After publishing, artifacts appear at:
- Portal: https://central.sonatype.com/
- Repository: https://repo1.maven.org/maven2/com/alorma/compose/settings/
Timing:
- Artifacts appear in portal immediately after successful publish
- Full propagation to Maven Central can take 15-30 minutes
- CDNs and mirrors may take up to 2 hours