Epilogue - The Maven Release Plugin

We've been spending a little more time recently at work moving our code repo away from subversion and over to git. Whilst we were doing this, I came across this cool tip to optimize the Maven Release Process, which allows you to skip using the heavy Release Plugin. So, if there's anyone left fighting in the eternal war against maven, this article is the roundup.

The inspiration for our solution is derived heavily from Axel Fontaine's insightful series on the Maven release process, which you can read the conclusion of here.

In summary, it suggests swapping out the release plugin for the scm and versions plugins, and then getting Jenkins to do some smart work during the release build to orchestrate tagging and versioning. It works pretty well, and the core advantage of not having to wait for the same build to complete over and over is incredibly satisfying.

There were, however, some snagging issues that initially stopped us adopting this approach. These essentially boil down to the following :-

Versioning

No matter how many times I see

<project ...>  
    ...
    <version>0-SNAPSHOT</version>
    ...
</project>  

I can't get used to it, I try to avoid unusual workarounds as much as possible when dealing with Maven, so if it was possible to keep the snapshot version intact, I was in favour of doing so. I also find it beneficial to keep the last stable release visible for developers working on the current development iteration.

SCM Tagging

The SCM tag doesn't actually commit the version change via jenkins to GIT, so your tags will all have the weird snapshot version 0-SNAPSHOT. There's also no commit to start the next development iteration, so you may end up tracking release versions via some other system, which is just another maintenance headache in my way.

Better Housekeeping with Jenkins

Turns out it's actually pretty cheap to keep the snapshot version if you still have some use for it. Here's a breakdown of what's involved :-

  1. Set up a Jenkins job to perform the release.
  2. Add some parameters using the Parameterized Build Plugin. You'll need a parameter for the release version and one for the next snapshot iteration. I creatively called mine Release_Version and Next_Snapshot_Version. We'll need these environment variables orchestrate the scm plugin.
  3. You need 4 steps in the build itself. The first of these is to set the release version
    versions:set -DnewVersion=$Release_Version
  4. Next lets deploy the project artifacts in our repository, clean deploy -T2C.
  5. Now we need to check in the release version so, when we tag, the tag has the right version in git scm:checkin scm:tag -Dmessage="[Jenkins] Tag commit $Release_Version". If you've had your Jenkins user set up using a deploy key until now, you'll need to migrate this to a real user with access to push to your repo.
  6. Finally we set up for the next development iteration : versions:set -DnewVersion=$Next_Snapshot_Version scm:checkin -Dmessage="[Jenkins] Next development iteration $Next_Snapshot_Version"

And thats it ! Another nice touch, if you have the Groovy Postbuild Plugin, is to execute the following script after the build :

if(!manager.build.result.isWorseOrEqualTo(hudson.model.Result.UNSTABLE)) {  
      manager.addBadge("completed.gif", manager.envVars['Release_Version'], 'http://[YOUR REPO BROWSER PLACEHOLDER]'+manager.envVars['Release_Version'])
}

This will add a nice tooltip badge on your build which will tell you the released version and link back to the released tag for convenience.

comments powered by Disqus