In 2024 the mechanism of publishing Maven artifacts has changed, in this short article we'll discuss how we can release and publish a new Maven package from GitHub.
https://central.sonatype.com will be our starting point, let's open it in the browser:
Let's click on "Sign in" button!
If you are new here, press on Signup, otherwise enter your username and credential:
Important note: If you already have a user from the old Maven central (oss.sonatype.org), then you might not able to log in, then read the following websites:
Once you've logged in, you'll see a similar page that I've pasted as first attachment, with only one difference on the top right corner:
Create a namespace
Open "View namespaces" to add a new namespace, then press "Add namespace".
If you have a GitHub user called "johndoe123", then you have to define
io.github.johndoe123
Once you pressed Submit, you have to verify that you own the given domain.
You can see a Verification key on the bottom left side of the panel. In order to proove that you are the owner of that GitHub account, create a repository with that name:
After the repository created, press "Verify namespace" and "Confirm":
Verification takes a few minutes to complete:
After the verification completed, you will see
HINT: After the verification don't forget to remove the repository! GPG configuration
Create the key
In order to sign your Maven package you'll need a keypair generated by GPG. Run
gpg --gen-key
Once you generated the key, run
and you will see something like this:
$ gpg --list-keys
/home/mylocaluser/.gnupg/pubring.kbx
---------------------------------
pub rsa3072 2021-06-23 [SC] [expires: 2023-06-23]
CA925CD6C9E8D064FF05B4728190C4130ABA0F98
uid [ultimate] Central Repo Test <central@example.com>
sub rsa3072 2021-06-23 [E] [expires: 2023-06-23]
You need to copy the highlighted value, we will use it later.
Save the public key
Next we have to export the public key. It will be used by Sonatype portal, so we'll publish it on Ubuntu keyserver:
gpg --armor --export <Copied_highlighted_ID>
Save the private key
We need the exported private key in order to use it in our GitHub Action step to sign the Maven artifacts:
gpg --armor --export-secret-keys <Copied_highlighted_ID>
Upload the public key
With that all required steps completed that is necessary on Sonatype side, let's move on to our side!
Maven configuration
Resources:
Configuration options
Before you add the necessary plugins to your pom.xml, please check this website:
If you want to release a public (open source) Maven package, you have to set all mandatory parameters!
Plugin setup
I recommend to define a new Maven profile in order to separate release functionality from other Maven features.
4 Maven plugins required:
- maven-source-plugin
- maven-javadoc-plugin
- maven-gpg-plugin
- central-publishing-maven-plugin
<profile>
<id>release</id>
<distributionManagement>
<repository>
<id>central</id>
<url>https://central.sonatype.com</url>
</repository>
</distributionManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<doclint>all,-missing</doclint>
</configuration>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
<configuration>
<gpgArguments>
<arg>--pinentry-mode</arg>
<arg>loopback</arg>
</gpgArguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.sonatype.central</groupId>
<artifactId>central-publishing-maven-plugin</artifactId>
<version>0.5.0</version>
<extensions>true</extensions>
<configuration>
<publishingServerId>central</publishingServerId>
</configuration>
</plugin>
</plugins>
</build>
</profile>
Now let's discuss the most important parts of this setup!
Distribution setup
<distributionManagement>
<repository>
<id>central</id>
<url>https://central.sonatype.com</url>
</repository>
</distributionManagement>
In this configuration setup you defined that your artifact will be distributed to the Central Sonatype website, and the ID will be "central". You will see why this ID is important to remember.
Central Sonatype plugin
This plugin is essential to upload and release your Maven package. There are several ways to customize this plugin, you can find further info here:
<plugin>
<groupId>org.sonatype.central</groupId>
<artifactId>central-publishing-maven-plugin</artifactId>
<version>0.5.0</version>
<extensions>true</extensions>
<configuration>
<publishingServerId>central</publishingServerId>
</configuration>
</plugin>
For instance, if you prefer automatic publishing, you need to set "autoPublish" configuration property to true.
GitHub repository setup
GitHub Action
We have to create a new GitHub workflow by pressing "New workflow", then press "setup a workflow yourself".
Let's add the following code:
name: Release Java client library
on:
workflow_dispatch:
inputs:
releaseVersion:
description: "Default version to use when preparing a release."
required: true
default: "X.Y.Z"
developmentVersion:
description: "Default version to use for new local working copy."
required: true
default: "X.Y.Z-SNAPSHOT"
permissions:
contents: write
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
token: ${{ secrets.PAT }}
ref: main
env:
branch: main
- id: install-secret-key
name: Install gpg secret key
run: |
# Install gpg secret key
cat <(echo -e "${{ secrets.GPG_SIGNING_KEY }}") | gpg --batch --import
# Verify gpg secret key
gpg --list-secret-keys --keyid-format LONG
- name: Set up Maven Central Repository
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
server-id: central
server-username: MAVEN_USERNAME
server-password: MAVEN_PASSWORD
- name: Update pom.xml to releaseVersion
run: mvn -B versions:set -DnewVersion=${{ github.event.inputs.releaseVersion }} -DgenerateBackupPoms=false -f ./pom.xml
- name: Commit version change
run: |
git config --global user.name ${{ secrets.GH_USERNAME }}
git config --global user.email ${{ secrets.GH_EMAIL }}
git commit -am "[ci-skip] Version updated to ${{ github.event.inputs.releaseVersion }}"
- name: Publish package
run: mvn -Prelease --batch-mode -Dgpg.keyname=${{ secrets.GPG_KEY }} -Dgpg.passphrase=${{ secrets.GPG_PASSPHRASE }} deploy -f ./pom.xml
env:
MAVEN_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
MAVEN_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}
MAVEN_GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
- name: Update pom.xml to developmentVersion
run: mvn -B versions:set -DnewVersion=${{ github.event.inputs.developmentVersion }} -DgenerateBackupPoms=false -f ./pom.xml
- name: Commit version change to next SNAPSHOT version
run: |
git config --global user.name ${{ secrets.GH_USERNAME }}
git config --global user.email ${{ secrets.GH_EMAIL }}
git commit -am "[ci-skip] Version updated to ${{ github.event.inputs.developmentVersion }}"
git push
Secrets
We will need a bunch of secrets for our Maven artifact release.
- PAT*: GitHub Personal Access Token,
- GPG_SIGNING_KEY: Set your exported private GPG key into this secret,
- GH_USERNAME: This should be your GitHub username (email),
- GH_EMAIL: Your email address,
- GPG_KEY: GPG key ID ("<Copied_highlighted_ID>"),
- GPG_PASSPHRASE: The password that you've defined for the GPG key,
- SONATYPE_USERNAME*: Sonatype token username,
- SONATYPE_PASSWORD*: Sonatype token password
Some of these secrets requires some clarification, let's go one by one!
PAT
and select "Fine-grained tokens(beta)", then press "Generate new token" button. Add all mandatory parameters like:
- token name,
- resource owner,
- expiration date,
- repository access: If you want to create a PAT for only a specific repository, choose "Only select repositories" menu, otherwise you can choose "All repositories".
- Permissions: I'd say the following permissions are enough:
Sonatype settings
The username and password names can be misleading, because these are generated user tokens. To generate a new user token name and password, go to
https://central.sonatype.com/account and press "Generate new user token", then copy the provided username and password into
- SONATYPE_USERNAME and
- SONATYPE_PASSWORD
GitHub Actions secrets.
Check the deployed artifact
Run your GitHub Action manually, and if everything goes fine, you'll see something like that on Maven Central:
After a few minutes the status will change to deployed:
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.