Automate Releases to Maven Central using GitHub Actions
In my previous guide, we stepped through how to register a domain with Nexus, sign artifacts with GPG, and publish release candidates manually to Maven Central. However incrementing semantic versions, repository tagging, GPG signing, and artifact publishing is manual and prone to human error. Using GitHub Actions, we can completely automate this process whenever code is merged to the main branch.
Configure GitHub Secrets
If you’re using a GitHub organization to host your OSS repository, consider configuring your GPG and OSSRH secrets in your organization’s settings. This will allow each repository to share the same secrets. Otherwise, each repository will need to configure secrets separately.
GPG_SIGNING_KEY
— The public key published to the key serversGPG_PASSPHRASE
— The passphrase used to generate the public keyOSSRH_USERNAME
— Your username for issues.sonatype.comOSSRH_PASSWORD
— Your password for issues.sonatype.com
Create Release Workflow
Start by creating a workflow at .github/workflows/release.yml
Name the workflow.
Decide how to trigger the workflow. In this case, we’re going to trigger whenever code is pushed to the main branch.
Each workflow is made up of jobs. Each job will run on a container. In this case, our container will run with Ubuntu.
At runtime, each job runs in parallel. Each job is made up of steps, which run in sequence.
First, checkout the code from the current branch.
Then, configure Java version. By default, setup-java action will use x64 JDK from OpenJDK.
The final step is to publish your artifact to Nexus using GPG and OSSRH secrets configured earlier.
The final release.yml
should look similar to this.
Now when code is pushed to the main branch (hopefully from a pull-request), the release action will fire and deploy to Nexus Repository.

Increment Maven Version
Before publishing to Nexus, the artifact version number can be automatically updated in the release workflow. This is an optional step, however once an artifact is released to Nexus, each subsequent release must have a unique and incremental version.
If you’re using semantic versioning, then decide whether to increment the major, minor, or patch number of the version.
Major
$ ./mvnw build-helper:parse-version versions:set -DnewVersion=\${parsedVersion.nextMajorVersion}.0.0 versions:commit
Minor
$ ./mvnw build-helper:parse-version versions:set -DnewVersion=\${parsedVersion.majorVersion}.\${parsedVersion.nextMinorVersion}.0 versions:commit
Patch
$ ./mvnw build-helper:parse-version versions:set -DnewVersion=\${parsedVersion.majorVersion}.\${parsedVersion.minorVersion}.\${parsedVersion.nextIncrementalVersion} versions:commit
Update Release Workflow
Add a new step to release.yml
to increment the version number and push to the checked out repository.
You can use your name and email to sign the version commit. However, consider using a bot account for OSS or organization repositories. This will allow for continuity if your account is no longer associated with the repository.
The updated release.yml
should look similar to this:
Tag Repository with Version
It is important to tag the repository to capture the exact point in git history for the release. We can automatically create a tag using the current maven version.
Using the maven-help plugin, we can find the current version.
$ ./mvnw help:evaluate -Dexpression=project.version -q -DforceStdout
Add a new step to release.yml
to create a tag with this version.
The updated release.yml
should look similar to this:
Using GitHub Actions we can now automatically increment our release version, create a git tag, sign our artifact with GPG, and publish to Nexus whenever code is pushed to our main branch. Additionally, we have removed human error and fully automated our release workflow.