sebastiandaschner blog


Continuous Delivery friendly Maven versions

saturday, december 09, 2017

A Continuous Delivery pipeline requires predictable software and dependency versions. Snapshot versions, which are common in Maven software projects, contradict the motivation behind Continuous Delivery.

In order to update snapshot versions to release versions developers usually edit the pom.xml file by hand or via a plugin such as the maven-release-plugin. However, Maven also offers the possibility to define version numbers as properties, which fits the Continuous Delivery world better.

It is possible to use placeholders such as ${revision} as artifact versions, as described here. We can therefore define a version that consists of a semantic version including the build number of the CI server as metadata:

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.sebastian-daschner</groupId>
    <artifactId>hello-world</artifactId>
    <version>${revision}</version>

    ...

    <properties>
        <!-- will be overridden in CD pipeline -->
        <buildNumber>local</buildNumber>
        <revision>1.0.0+${buildNumber}</revision>
        ...
    </properties>
</project>

In order to issue a local build which won’t be published on any environment, we invoke mvn clean package as usual. This results in the artifact version 1.0.0+local.

The Continuous Integration server will invoke the Maven build similar to: mvn clean package -DbuildNumber=b${buildNumber} — with the build number taken from the current pipeline build. This results in artifact versions 1.0.0+b123, 1.0.0+b124, and so on. The same property is set in order to mvn deploy the artifact to a repository.

This approach comes in handy to both specify predictable versions and fallback versions for local builds. It’s important to note that the semantic version 1.0.0 should only changed by developers, since it reflects the nature and compatibility of API-changes.

 

Found the post useful? Subscribe to my newsletter for more free content, tips and tricks on IT & Java: