Maven — Git— Nexus — Jenkins: Automate Maven releases with Jenkins

Kasun Gajasinghe
6 min readAug 6, 2017

--

As part of my work at WSO2, I worked on automating maven-based release process to make it a two-click process via Jenkins reducing the complexities involved with Maven, Git, and Nexus.

We are a Apache Maven power-house who has heavily invested in Jenkins for Continuous Integration. We host all our 600+ repos on GitHub, each has a corresponding Jenkins job, and the released artifacts are hosted on Sonatype Nexus. We are using Nexus staging repositories to verify the artifacts before hosting. Releases happen with maven-release-plugin.

Yes, you heard it right. We are using maven-release-plugin to do our releases! It can get bit cumbersome. Developer energy was wasted when they had to release all these repos by-hand. Something had to be done.

We already have Jenkins for Continuous Integration. We thought why not improve it to support Continuous Delivery? We needed Jenkins to take care of the work of release plugin AND take care of Nexus Staging repository closing and releasing. More importantly, we needed to automatically rollback the Git tags, and delete partially created staging repositories.

Fig.1

We came across the m2release-plugin Jenkins plugin that gives you the ability to do “maven release:prepare release:perform” from the same Jenkins build that we use for daily snapshot builds. That was convenient because we then don’t have to create duplicate jobs just to do releases.

Fig.2 M2-release-plugin configuration section in a job

This was good. But it lacked the support for Sonatype Nexus and a good integration with Git. Further more, we follow a defined git flow release process — https://docs.wso2.com/display/Carbon4411/Releasing+a+Git+Repository.

Here’s the actual flow in a sequence diagram.

Fig.3 A simple Jenkins-based release model for Maven + Git + Nexus based builds

The stake-holders are: The Git committers, GitHub Repo, Jenkins, and Maven Nexus repo. Maven-release-plugin plays a major part here.

To make it work, we forked the m2release-plugin. The fork can be found here — WSO2 Jenkins M2 Release Plugin. You can download the latest plugin binary here — https://github.com/wso2/wso2-jenkins-m2release-plugin/releases/tag/v0.15.2

Configuring the WSO2 Jenkins M2 Release Plugin

  1. First, make sure your repo is releasable via the maven-release-plugin. If not, you need to set-up your Git repo first. See this guide for some useful instructions — https://docs.wso2.com/display/Carbon4411/Setting+up+a+Git+Repository
  2. Install GitHub Plugin and Mask Passwords Plugin via the Jenkins Plugin Center at $JENKINS_URL/pluginManager/available. GitHub plugin is used to work with GitHub APIs. Mask Passwords Plugin masks the configured plugins from the build log. Maven-release-plugin is nasty that way!
  3. Download the new M2 Release Plugin from the v0.15.2 tag and copy it to $JENKINS_HOME/plugins/ folder, and restart Jenkins. Or you can build it from the source via — you guessed it right — mvn clean install.

Global Configuration

This describes the steps that need to be performed in $JENKINS_URL/configure .

Configure Maven release plugin — This is quite simple. Tick the “Enable Nexus Pro support”, and provide your nexus URL along with credentials.

Configure the Mask passwords plugin

  • Go to Global -> Mask Passwords — Parameters to automatically mask
  • Tick “Non-stored password”, “ Text ”, “ String ”, “ Password ”.
  • Fill the password to mask. Choose any name. See the picture below.
  • The github user-password and Nexus user-password needs to be masked. Otherwise, these appear in the build logs!!
Fig.4 Mask passwords plugin global configuration

Add a settings.xml that has GitHub and nexus credentials under the managed scripts.

  • It can be added via$JENKINS_URL/configFiles. A sample settings.xml is given below.
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">


<servers>
<!-- The passwords should be picked from jenkins server credentials. -KasunG -->
<!-- First we have the Sonatype Nexus credentials. Make sure the server id here matches with the id under the <repositories> section of your pom. -->
<server>
<id>nexus-releases</id>
<username>kasunbg</username>
<password></password>
</server>
<!-- Next up is the Git SCM credentials. Make sure the server id here matches with the project.scm.id property in your pom. -->
<server>
<id>my-scm-server</id>
<username>wso2</username>
<password></password>
</server>
</servers>
</settings>

You do not need to set the credentials in plain-text. You can use Jenkins’ credentials vault for that.

  • Let Jenkins manage the GitHub Webhooks. To do that, add a new GitHub Server under the GitHub section —

a. API URL: https://api.github.com
b. Set credentials — You can use a GitHub application token if you need to.
c. Tick Manage hooks.

Fig.5 GitHub WebHook configuration.
  • If you need to manage it manually, then you can of course configure GitHub WebHook for each repo. (optional)
    a. Login to GitHub, and head over to Settings -> Webhooks & services
    b. Click on Add Webhook
    c. Set the Payload URL: https://wso2.org/jenkins/github-webhook/
    d. Click on Add Webhook

Per Job Configuration

Now, let’s get to the interesting part — configuring your jobs to use the new plugin.

Good screenshots make the config easier. So, here we go. The per job Git configuration:

Fig.6 Per Job Git Configuration
Tick the GitHub Webhook build-trigger to do releases for each git push. Untick this if you are triggering releases via the Jenkins UI.
Fig.8 Enable the mask passwords
Fig.9 Maven Release Build configuration
Fig.10 If the build is a release build, we should not run the snapshot deployment post-build action.

Also make sure to set the newly added settings.xml under the Build -> Settings file.

Triggering a Manual Release via Jenkins

Let’s suppose CD is not enabled for a repo. But still, if you like to use Jenkins to do the releases for you, then it indeed is possible. :-) What happens then is that you make your Jenkins job CD-ready, but the release per each push option is set to disable.

Now, when you need to do a release, click on the “Perform Maven Release” option in the left menu. (If you do not need see this, then you may need to request the permission)

Now, in the “Perform Maven Release” page, provide the following (usual) stuff.

  • Release Version
  • Next Development Version
  • SCM Tag name
Fig.12 The Perform a Release Wizard UI

That’s about it. If you have come all the way here, congratulations! You made it! :-D

I did not cover some Jenkins stuff in this article assuming users are familiar with them. BUT, if any step if unclear, do holler! Thanks.

--

--