Release a maven project¶
GPG¶
Commands¶
Install gpg with homebrew
Generate key
To list the generated keys
Tip: Finding your GPG Key ID
To find your GPG Key ID, run:
Example output:
/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]
The long hexadecimal value: CA925CD6C9E8D064FF05B4728190C4130ABA0F98 is your GPG Key ID (fingerprint) used in signing configuration.
Push your public key to the server
or
Generate key ring that will be used to signin our artifacts
Export private key in the form of a string
Your GPG public key (exported as an ASCII-armored string)
Your GPG private key (exported as an ASCII-armored string)
Maven Central Deployment¶
Setup¶
Configure pom.xml¶
Add the following configuration to your pom.xml file:
<profiles>
<profile>
<id>makeRelease</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>${maven-source-plugin.version}</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>${maven-javadoc-plugin.version}</version>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
<executions>
<execution>
<id>attach-javadoc</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>${maven-gpg-plugin.version}</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
<configuration>
<passphrase>${env.GPG_PASSPHRASE}</passphrase>
<gpgArguments>
<arg>--pinentry-mode</arg>
<arg>loopback</arg>
</gpgArguments>
</configuration>
</plugin>
<!-- ✨ NEW Sonatype Central Publishing Plugin -->
<plugin>
<groupId>org.sonatype.central</groupId>
<artifactId>central-publishing-maven-plugin</artifactId>
<version>${central-publishing-maven-plugin.version}</version>
<extensions>true</extensions>
<configuration>
<publishingServerId>central</publishingServerId>
<autoPublish>true</autoPublish>
<waitUntil>published</waitUntil>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
Github workflow for release¶
Pre-requisites:
- The following secrets are configured in your GitHub repository:
CENTRAL_USERNAME- Your Sonatype OSSRH username.CENTRAL_PASSWORD- Your Sonatype OSSRH password.GPG_PRIVATE_KEY- Your GPG private key (exported as an ASCII-armored string).GPG_PASSPHRASE- The passphrase for your GPG key.
The pipeline will be triggered on every new release published in the GitHub repository. The version
will be extracted from the tag name (assuming the tag follows the pattern vX.Y.Z). The idea is to
build the project using Maven, sign the artifacts with GPG, and deploy them to the Maven Central
Repository.
name: Publish package to Maven Central Repository
on:
release:
types: [ published ]
jobs:
publish:
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Extract version from tag
id: version
run: |
raw_tag_name="${GITHUB_REF_NAME}"
# Extract last x.y.z pattern
version=$(echo "$raw_tag_name" | grep -oE '[0-9]+\.[0-9]+\.[0-9]+$')
echo "VERSION=$version" >> $GITHUB_ENV
- name: Set up JDK 25 with GPG
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: 25
gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }}
gpg-passphrase: MAVEN_GPG_PASSPHRASE
server-id: central
server-username: CENTRAL_USERNAME
server-password: CENTRAL_PASSWORD
- name: Build & Deploy to Staging
env:
CENTRAL_USERNAME: ${{ secrets.CENTRAL_USERNAME }}
CENTRAL_PASSWORD: ${{ secrets.CENTRAL_PASSWORD }}
MAVEN_GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
run: |
# Build and deploy artifacts (signed)
echo "🚀 Building release version: $VERSION"
mvn -B clean deploy -P makeRelease -DskipTests -Drevision="$VERSION" -ntp