In this tutorial I will show you how to set up your project to automatically be deployed to Maven Central using Gitlabs CI/CD pipeline.
Create access token
For security reasons you should not provide the Gitlab CI/CD configuration with your real login credentials. Instead you should use an access token for this.
First login at OSS Sonatype using the credentials you have set up for issues.sonatype.org.
Now click on your user name on the top right corner and then on „profile“:

Now click on the arrow next to „summary“. A menu is dropped down within which you click on „User Token“:

Click on the button „Access User Token“. You will requested to enter your login credentials. After that you will be displayed your created access token:

Copy the credentials to a temporary location and login into your Gitlab. Navigate to your project and in the menu on the left click on „Settings“ and „CI/CD“. Expand the variables section:

Click on „Add variable“ and create a masked variable MAVEN_REPO_USERNAME containing the username part of the access token:

Now also create a masked variable MAVEN_REPO_PASSWORD and set its value to the password part of the access token.
Add PGP secret key to the pipeline
As a requirement for this tutorial you have set up a basic Maven project that can be deployed to Maven Central manually. There you have created a PGP key. As the Maven docker image does not allow to use pinentry for asking inputting the passphrase you will need to remove the passphrase from the secret part of the PGP key. Open the key in GPG:
gpg --edit-key $YOUR_KEY_ID
$YOUR_KEY_ID is the ID of PGP key which you are going to remove the passphrase from. Now open the passphrase editor:
gpg> passwd
You need to enter the passphrase of your key. After that, you will asked to enter the new passphrase. Leave it empty to clear the passphrase and ackknowledge it. Now close the PGP key by pressing CTRL + C. Export the secret to a key file:
gpg --armor --export-secret-keys > secret-key.asc
Add a CI/CD variable (not protected and not masked) of type „file“ named GPG_SECRET_KEY having the content of that secret key file as its value.
Setup your project
Now create a directory „.m2“ within the root of your project folder and add a settings.xml file with following content:
<settings xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd" xmlns="http://maven.apache.org/SETTINGS/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <servers> <server> <id>central</id> <username>${env.MAVEN_REPO_USERNAME}</username> <password>${env.MAVEN_REPO_PASSWORD}</password> </server> <server> <id>ossrh</id> <username>${env.MAVEN_REPO_USERNAME}</username> <password>${env.MAVEN_REPO_PASSWORD}</password> </server> </servers> </settings>
Add profiles for the CI/CD stages to your pom.xml. This will help to prevent of repeatedly running maven goals that already have been run in a previouse phase of the CI/CD pipeline:
<profiles> <profile> <id>test</id> <!--This profile is used to run the tests.--> <properties> <maven.javadoc.skip>true</maven.javadoc.skip> <maven.source.skip>true</maven.source.skip> </properties> </profile> <profile> <id>deploy</id> <!--This profile is used to deploy the packages.--> <properties> <maven.test.skip>true</maven.test.skip> <maven.integration-test.skip>true</maven.integration-test.skip> </properties> </profile> </profiles>
Now create the gitlab-ci.yml with following content:
default: image: maven:3.8.6-openjdk-18 tags: - shared variables: MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode" MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository" cache: paths: - .m2/repository/ stages: - test - deploy test: stage: test script: - mvn $MAVEN_CLI_OPTS clean integration-test -Ptest deploy: stage: deploy before_script: - gpg --version - gpg --pinentry-mode loopback -v --import --batch --yes $GPG_SECRET_KEY - gpg --list-secret-keys script: - mvn $MAVEN_CLI_OPTS clean deploy -Pdeploy only: refs: - main artifacts: name: "$CI_PROJECT_NAME-signatures" paths: - target/*.asc - target/*.pom - target/*.jar
This will create two stages in the CI/CD pipeline. The test stage is run first and executes all tests. If it is successful, the deploy stage is run which packages the artifact, creates all needed signatures and upload it to Maven Central.