In this blog post, we will guide you through the process of automatically publishing your Kotlin package to the Maven Central Repository. Follow the steps below to ensure a seamless setup.
1. Obtain a Sonatype OSSRH Account
To start, you need a Sonatype OSSRH (OSS Repository Hosting) account. Sign up for one by following this publish guide.
2. Meet Maven Central Publishing Requirements
Before you can publish a package to Maven Central, you must satisfy certain requirements. Find the complete list here. In summary, you need to:
- Adhere to semantic versioning
- Provide source code
- Provide Java documentation
- Sign publications with GPG
3. Configure Signing in Gradle
To sign your publications with GPG, configure the signing process in Gradle. You can reference this example of a build.gradle.kts file.
I used in-memory ascii-armored OpenPGP subkeys which let me store a signing only key to Github signingPassword of screte key.
Comparing to store configurations in a property file, this method is greate for CI.
signingKeyId: last 8 digits of subkey ID signingKey: ascii-armored with ECC algorithm signingPassword: same to secrete key’s
You can create a subkey by following 5.1.2
signing {
val signingKeyId: String? by project
val signingKey: String? by project
val signingPassword: String? by project
useInMemoryPgpKeys(signingKeyId, signingKey, signingPassword)
sign(publishing.publications["mavenKotlin"])
}
4. Set Up Publishing
To set up publishing, use the Gradle Nexus Publish Plugin.
This is a new plugin which make publishing easier than before with two different plugins.
nexusPublishing {
repositories {
create("myNexus") {
nexusUrl.set(uri("https://s01.oss.sonatype.org/service/local/"))
snapshotRepositoryUrl.set(uri("https://s01.oss.sonatype.org/content/repositories/snapshots/"))
username.set(System.getenv("OSSRH_USERNAME")) // defaults to project.properties["myNexusUsername"]
password.set(System.getenv("OSSRH_PASSWORD")) // defaults to project.properties["myNexusPassword"]
}
}
}
5. Configure GitHub Workflow
5.1. Add Secrets
Securely store sensitive information, such as your Nexus credentials and GPG keys, in your GitHub repository using GitHub Secrets.
5.1.1. Nexus Token
Create a Nexus token to authenticate with the Sonatype OSSRH. Follow these steps:
- Log in to the Sonatype Nexus Repository Manager.
- Click on your username in the top-right corner and select “Profile.”
- Navigate to the “User Token” tab and click “Access User Token.”
- Enter your account password and click “Authenticate.”
- Click “Show User Token” to reveal your token. Make sure to copy both the “Username” and “Password” for the token.
Now, store the Nexus token in your GitHub repository as secrets:
- Go to your repository’s main page on GitHub.
- Click on the “Settings” tab.
- Navigate to the “Secrets” section in the left sidebar.
- Click the “New repository secret” button.
- Create two new secrets:
OSSRH_USERNAME
andOSSRH_PASSWORD
. Use the “Username” and “Password” from the Nexus token, respectively.
5.1.2. GPG Subkey
Generate a GPG subkey for signing your Kotlin package. Follow these steps:
- Install GnuPG, if you haven’t already, by following the instructions on the official website.
- Open the command line (terminal on macOS/Linux or Command Prompt on Windows) and run
gpg --list-secret-keys
to list your existing secret keys. - If you don’t have any secret keys, create one by running
gpg --gen-key
. Follow the prompts to generate a new key pair. - Run
gpg --edit-key [KEY_ID]
to start the key-editing mode, replacing[KEY_ID]
with the ID of the key you want to create a subkey for. - Enter the command
addkey
to create a new subkey. Follow the prompts and choose the “ECC (sign only)” key type. - Set the expiration date and key length, then confirm the subkey creation. Finally, enter the passphrase to unlock the master key.
- Run the
save
command to save the changes and exit the key-editing mode. - Export the subkey by running
gpg --armor --export-secret-subkeys [SUBKEY_ID] > subkey.gpg
, replacing[SUBKEY_ID]
with the ID of the subkey you just created.
Now, store the GPG subkey and related information in your GitHub repository as secrets:
- Open the
subkey.gpg
file and copy its contents. - Retrieve the passphrase you used when creating your GPG key pair.
- Run
gpg --list-secret-keys
to list your secret keys and find the ID of the key you want to use for signing. Copy the key ID. - Go to your repository’s main page on GitHub.
- Click on the “Settings” tab.
- Navigate to the “Secrets” section in the left sidebar.
- Click the “New repository secret” button.
- Create the following secrets:
GPG_SIGNING_KEY
: Paste the contents of thesubkey.gpg
file.GPG_PASSPHRASE
: Enter the passphrase you used when creating your GPG key pair.GPG_SIGNING_KEY_ID
: Enter the key ID you found usinggpg --list-secret-keys
.
5.2 Configure Workflow
Create a yml file under .github/workflows
with content below, then test it by manually trigger.
name: Publish package to the Maven Central Repository
on:
release:
types: [created]
workflow_dispatch:
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Java
uses: actions/setup-java@v3
with:
java-version: '11'
distribution: 'corretto'
- name: Publish package
uses: gradle/gradle-build-action@v2
with:
arguments: publishToMyNexus closeAndReleaseMyNexusStagingRepository
env:
OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }}
OSSRH_PASSWORD: ${{ secrets.OSSRH_TOKEN }}
ORG_GRADLE_PROJECT_signingKey: ${{ secrets.GPG_SIGNING_KEY }}
ORG_GRADLE_PROJECT_signingKeyId: ${{ secrets.GPG_SINGING_KEY_ID }}
ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.GPG_PASSPHASE }}