I am just setting up a Maven multi-module project with ${revision}
as version as described in https://maven.apache.org/maven-ci-friendly.html
The property ${revision}
is set in the parent POM and used as version number throughout all modules.
This works fine for SNAPSHOT builds, but when I run the Maven release plugin, the version gets replaced by something like 1.0.0
and then 1.0.1-SNAPSHOT
. So the cifriendly versions are gone after one release.
Is there a way to configure the Maven release plugin in a way that cifriendly versions are not destroyed?
The CI Friendly version scheme is intended to replace the Maven Release Plugin, not complement it. In today's development world most teams are relying on CI servers for integration testing, performing automated tests and either releasing with continuous delivery or continuous deployment. The concept of a SNAPSHOT
is truly limited when everything is potentially a SNAPSHOT
.
Notably, the Release Plugin executes 4 to 5 times more processes than a properly implemented CI Friendly configuration. Imagine a 50-minute build using the release plugin becoming a 15-minute build using the CI strategy. Now that's modernization!
The basic idea is that values used in versions will be collected from the DVCS (Git
, SVN
, etc.) and the CIS (Jenkins
, Travis CI
, GitLab
, etc.) at build time and used to modify or set the POM/release version. These values are things like the build number, the shortened Git hash or anything else.
Procedure to implement CI Friendly Maven builds:
<version>
tag. These are ${revision}
, ${changelist}
and ${sha1}
.${revision}
. NOTE: I now recommend ${revision}
.<properties>
, set values to acceptable defaults -- fake values that become clear they are from non-build machines, like 0
for the build number.<properties>
, assemble the value for <revision>
, e.g. the version, from other properties and hardcoded values. For instance, <revision>1.0.0b${changelist}-${sha1}</revision>
.-D
flags to set the actual values. For instance, the ${BUILD_NUMBER}
value is injected to every Jenkins build -- -Dchangelist=${BUILD_NUMBER}
.In the CI pipelines you can now detect the commit branch and perform releases from master
by clearing all or some of these values. For instance, feature branches can calculate and add the Git hash. The semantic version is set above -- Developers now own and control it. They must know their code to make changes, and they have the freedom to increment the semantic version. It's a lot of valuable flexibility.
The sound reasoning here, though, is to speed up things and get rid of a heavyweight process that really adds little to no relevant information that ties code to its precise origin. By using CI Friendly versions you will let deployers, testers and sysadmins see the compile number and code commit hash that allows the problem to be precisely correlated to an actual code release.
It should be noted that this requires a bit of philosophical flexibility to accept a paradigm shift. Change is good, and ditching the release plugin will make your release pipelines better.