How to increment versions in maven builds - alternative to maven release plugin

Posted March 3, 2021 by Adrian Wyssmann ‐ 3 min read

Maven release plugin does a great job incrasing the version in maven builds. Still sometimes you may need an alternative.

Up to now I am used to the Maven Release Plugin when it comes to incerease the version in a maven build. It does a pretty good job:

  • Check that there are no uncommitted changes in the sources
  • Check that there are no SNAPSHOT dependencies
  • Change the version in the POMs from x-SNAPSHOT to a new version
  • Transform the SCM information in the POM to include the final destination of the tag
  • Run the project tests against the modified POMs to confirm everything is in working order
  • Commit the modified POMs
  • Tag the code in the SCM with a version name
  • Bump the version in the POMs to a new value y-SNAPSHOT
  • Commit the modified POMs

We use this in our ci pipeline, so we can trigger the ci pipeline manually with a isRelease trigger. This trigger tells the pipeline to run mvn release:prepare release:perform. As a result we have release artifacts and properly tagged source code:

two builds are triggered, one release build and the next `SNAPSHOT` build
changed source code was commited and tagged accordingly

So the Maven Release Plugin is quite useful but it’s not necessarily always usable. For instance, since we started using JFrog Artifactory and JFrog Xray using the Maven Release Plugin our release does not work anymore as we would expect. So using the Maven Release Plugin is not an option and the steps performed by it have to be implemented otherwise. Most of the steps can probably performed with some shell scripting but you probably don’t want to implement the version parsing by yourself, so there must be something which can be reused - and yes there is.

The Build Helper Plugin offers build-helper:parse-version which parse a version string and set properties containing the component parts of the version. It set’s the following properties

[propertyPrefix].majorVersion
[propertyPrefix].minorVersion
[propertyPrefix].incrementalVersion
[propertyPrefix].qualifier
[propertyPrefix].buildNumber
[propertyPrefix].nextMajorVersion
[propertyPrefix].nextMinorVersion
[propertyPrefix].nextIncrementalVersion
[propertyPrefix].nextBuildNumber
[formattedPropertyPrefix].majorVersion
[formattedPropertyPrefix].minorVersion
[formattedPropertyPrefix].incrementalVersion
[formattedPropertyPrefix].buildNumber

So these parameters can be used to set the version etc. Let’s look at an example. I have the following pom.xml

...
    <groupId>com.wyssmann.ci.pipeline</groupId>
    <artifactId>pipeline-helper</artifactId>
    <packaging>jar</packaging>
    <version>2.2.2-SNAPSHOT</version>
....

Let’s see what we get for our current project:

mvn build-helper:parse-version help:effective-pom 

Results in the following properties:

...
<properties>
    <formattedVersion.buildNumber>00</formattedVersion.buildNumber>
    <formattedVersion.incrementalVersion>02</formattedVersion.incrementalVersion>
    <formattedVersion.majorVersion>02</formattedVersion.majorVersion>
    <formattedVersion.minorVersion>02</formattedVersion.minorVersion>
    <formattedVersion.nextBuildNumber>01</formattedVersion.nextBuildNumber>
    <formattedVersion.nextIncrementalVersion>03</formattedVersion.nextIncrementalVersion>
    <formattedVersion.nextMajorVersion>03</formattedVersion.nextMajorVersion>
    <formattedVersion.nextMinorVersion>03</formattedVersion.nextMinorVersion>
    <parsedVersion.buildNumber>0</parsedVersion.buildNumber>
    <parsedVersion.incrementalVersion>2</parsedVersion.incrementalVersion>
    <parsedVersion.majorVersion>2</parsedVersion.majorVersion>
    <parsedVersion.minorVersion>2</parsedVersion.minorVersion>
    <parsedVersion.nextBuildNumber>1</parsedVersion.nextBuildNumber>
    <parsedVersion.nextIncrementalVersion>3</parsedVersion.nextIncrementalVersion>
    <parsedVersion.nextMajorVersion>3</parsedVersion.nextMajorVersion>
    <parsedVersion.nextMinorVersion>3</parsedVersion.nextMinorVersion>
    <parsedVersion.osgiVersion>2.2.2.SNAPSHOT</parsedVersion.osgiVersion>
    <parsedVersion.qualifier>SNAPSHOT</parsedVersion.qualifier>
    ...
</properties>
...

As suggested in the documentation you can then do something like this to set the next release version 2.2.2

mvn build-helper:parse-version versions:set \
 -DnewVersion=\${parsedVersion.majorVersion}.\${parsedVersion.minorVersion}.\${parsedVersion.incrementalVersion}

or once a release is done, set the next snapshot version 2.2.3-SNAPSHOT

mvn build-helper:parse-version versions:set \
-DnewVersion=\${parsedVersion.majorVersion}.\${parsedVersion.minorVersion}.\${parsedVersion.nextIncrementalVersion}-SNAPSHOT

This is a really helpful alternative to Maven Release Plugin. This still does not solve the other steps required to “replace” the Maven Release Plugin but it’s already a good start to avoid implementing something by myself if there is already a solution in place.