The Maven Release plugin allows you to easily craft releases of your own libraries, to share code between projects. When combined with Semantic Versioning you can communicate clearly to your library users which changes are minor, or potentially breaking. The plugin will trim off the -SNAPSHOT suffix of your artifact version, run through all the stages to create your build artifacts, and push those artifacts to a remote registry such as Artifactory. It will also push a Git tag to your code repository, as well as increment your artifact version to prepare for further development.

This blogpost will run you through the steps to authenticate with both GitLab and Artifactory when running a Maven Release from GitLab CI.

Allow to push commits and tags to GitLab

We will set up a SSH key pair, which the Maven Release plugin will use to push the commits and tag to GitLab.

Listing 1. Create a RSA keypair
ssh-keygen -m PEM -t rsa -P "" -f deploy_key

This creates a key pair named deploy_key.pub for the public key, and deploy_key for the private key, which does not require a password to use.

Next we will create a deploy key for the GitLab project that you want to release. This will allow read-write access to your repository using the SSH public key created above. Navigate to Settings > Repository > Deploy Keys, and paste the contents of deploy_key.pub in the corresponding Key field. Be sure to grant write permission to this key.

In addition to public and private key files, we will also need a known hosts file. To create one execute the following command.

Listing 2. Create a known hosts file
ssh-keyscan -H your.gitlab.host > known_hosts

We want to make both the private key file and the known hosts file available to our release job in GitLab CI. For that we create two CI / CD variables by navigating to Settings > CI / CD > Variables.

  1. Name the first one DEPLOY_PRIVATE_KEY and provide the contents of deploy_key.

  2. Name the second one KNOWN_HOSTS and provide the contents of known_hosts.

Be sure to select the File type, and mark both variables as Protected.

Add release step to GitLab CI

With the SSH credentials set up correcty, we move on to defining a release step in our GitLab CI pipeline. We will likely want to keep this a manual step at first, and only run this from the main or master branch.

We have to do some wrangling to convert the CI / CD file variables from the previous step into files the SSH client will know and look for. We install and configure Git, if not already present in the build image, and ensure we are not in a Git detached head state. Finally, we define a single script line that does both a release:prepare as well as release:perform.

Listing 3. gitlab-ci.yml
release:
  image: openjdk:15
  stage: release
  only:
    - master
  when: manual
  before_script:
    - mkdir -p ~/.ssh/
    - cp $DEPLOY_PRIVATE_KEY ~/.ssh/id_rsa && chmod 600 ~/.ssh/id_rsa
    - cp $KNOWN_HOSTS ~/.ssh/known_hosts
    - apt-get update && apt-get install -y git
    - git config --global user.email "noreply@your.gitlab.host"
    - git config --global user.name "GitLab CI"
    - git checkout -B "$CI_COMMIT_REF_NAME"
  script:
    - ./mvnw release:prepare release:perform

Reference your project repository in pom.xml

With SSH credentials and build step in place, next up we want to ensure our Maven Release connects to the correct repository. For that we need to define a SCM element in our pom.xml, with your specific details replaced in the sample below.

Listing 4. pom.xml > SCM
 <scm>
  <developerConnection>scm:git:git@gyour.gitlab.host:your-organization/your-library.git</developerConnection>
  <tag>HEAD</tag>
 </scm>

Allow to push artifacts to Artifactory

You can skip this step if you do not use Artifactory, for instance when you use GitLab Package Repository for Maven.

To upload artifacts to Artifactory, we need the dedicated artifactory-maven-plugin. Configure it similar to the snippet provided below. Note how we use environment variables for the ARTIFACTORY_CONTEXT_URL, ARTIFACTORY_USERNAME and ARTIFACTORY_PASSWORD. These will once again have to be provided in GitLab CI for your project by navigating to Settings > CI / CD > Variables, now using the Variable type.

Listing 5. pom.xml > Build > Plugins
<plugin>
  <groupId>org.jfrog.buildinfo</groupId>
  <artifactId>artifactory-maven-plugin</artifactId>
  <version>3.2.0</version>
  <executions>
    <execution>
      <id>push-library</id>
      <goals>
        <goal>publish</goal>
      </goals>
      <configuration>
        <publisher>
        <contextUrl>${env.ARTIFACTORY_CONTEXT_URL}</contextUrl>
        <username>${env.ARTIFACTORY_USERNAME}</username>
        <password>${env.ARTIFACTORY_PASSWORD}</password>
        <repoKey>libs-release-local</repoKey>
        <snapshotRepoKey>libs-snapshot-local</snapshotRepoKey>
        </publisher>
      </configuration>
    </execution>
  </executions>
</plugin>

Conclusion

That’s it! With the above in place you’re now all set to create Maven Releases for your libraries on GitLab CI.

shadow-left