Maven CI Friendly Versions
Starting with Maven 3.5.0-beta-1 you can use the ${revision}
, ${sha1}
and/or ${changelist}
as placeholders for the version in your pom file.
Single Project Setup
This can look like this:
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache</groupId>
<artifactId>apache</artifactId>
<version>18</version>
</parent>
<groupId>org.apache.maven.ci</groupId>
<artifactId>ci-parent</artifactId>
<name>First CI Friendly</name>
<version>${revision}</version>
...
</project>
This is of course a simple situation where we use only ${revision}
for brevity
to show the general course.
Based on the above pom you can build your project using:
mvn clean package
But wait there is a problem? Which version will the artifacts have? So you need to define the version for your artifacts. The first possibility is to use the command line like this:
mvn -Drevision=1.0.0-SNAPSHOT clean package
This will become cumbersome over the time. So the other solution for this is to simply use a property inside the pom file which looks like this:
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache</groupId>
<artifactId>apache</artifactId>
<version>18</version>
</parent>
<groupId>org.apache.maven.ci</groupId>
<artifactId>ci-parent</artifactId>
<name>First CI Friendly</name>
<version>${revision}</version>
...
<properties>
<revision>1.0.0-SNAPSHOT</revision>
</properties>
</project>
So now you can simply call Maven as usual like mvn clean package
.
You can of course change the version via the command line like this:
mvn -Drevision=2.0.0-SNAPSHOT clean package
Of course, you can use the .mvn/maven.config
file for this.
A note about the used properties. You can only use those named
${revision}
, ${sha1}
and/or ${changelist}
and not other
named properties like this:
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache</groupId>
<artifactId>apache</artifactId>
<version>18</version>
</parent>
<groupId>org.apache.maven.ci</groupId>
<artifactId>ci-parent</artifactId>
<name>First CI Friendly</name>
<version>${revision}</version>
...
<properties>
<revision>1.0.0-${buildNumber}-SNAPSHOT</revision>
</properties>
</project>
The above example will not work as expected. If you like to have more flexibility you can use a combination of the different properties like this:
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache</groupId>
<artifactId>apache</artifactId>
<version>18</version>
</parent>
<groupId>org.apache.maven.ci</groupId>
<artifactId>ci-parent</artifactId>
<name>First CI Friendly</name>
<version>${revision}${sha1}${changelist}</version>
...
<properties>
<revision>1.3.1</revision>
<changelist>-SNAPSHOT</changelist>
<sha1/>
</properties>
</project>
If you like to make a version 2.0.0-SNAPSHOT
this can
simply being achieved by using this:
mvn -Drevision=2.0.0 clean package
Another usage example can be to make a release which can be done via (version 1.3.1):
mvn -Dchangelist= clean package
Or if you like to make a release with another version:
mvn -Drevision=2.7.8 -Dchangelist= clean package
Please read until the end of this documentation!
Multi Module Setup
So now let us take a look into a situation where we have a multi module build. We have a parent pom and one or more children. The parent pom will look like this:
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache</groupId>
<artifactId>apache</artifactId>
<version>18</version>
</parent>
<groupId>org.apache.maven.ci</groupId>
<artifactId>ci-parent</artifactId>
<name>First CI Friendly</name>
<version>${revision}</version>
...
<properties>
<revision>1.0.0-SNAPSHOT</revision>
</properties>
<modules>
<module>child1</module>
..
</modules>
</project>
The child will look like this:
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.maven.ci</groupId>
<artifactId>ci-parent</artifactId>
<version>${revision}</version>
</parent>
<groupId>org.apache.maven.ci</groupId>
<artifactId>ci-child</artifactId>
...
</project>
A multi module build can of course build the same way as the single project setup. You should
define the version either via property in the parent or use the .mvn/maven.config
file.
Dependencies
In a multi module build you have often the case that you define dependencies
between module(s). The usual way of defining dependencies and their appropriate
versions has been to use ${project.version}
and this has not been changed.
So the correct way to do such things can be seen in the following example:
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache</groupId>
<artifactId>apache</artifactId>
<version>18</version>
</parent>
<groupId>org.apache.maven.ci</groupId>
<artifactId>ci-parent</artifactId>
<name>First CI Friendly</name>
<version>${revision}</version>
...
<properties>
<revision>1.0.0-SNAPSHOT</revision>
</properties>
<modules>
<module>child1</module>
..
</modules>
</project>
The child will look like this:
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.maven.ci</groupId>
<artifactId>ci-parent</artifactId>
<version>${revision}</version>
</parent>
<groupId>org.apache.maven.ci</groupId>
<artifactId>ci-child</artifactId>
...
<dependencies>
<dependency>
<groupId>org.apache.maven.ci</groupId>
<artifactId>child2</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>
If you try to use ${revision}
instead of ${project.version}
your build
will fail.
Install / Deploy
If you like to install or deploy artifacts by using the above setup you have to use the flatten-maven-plugin otherwise you will install/deploy artifacts in your repository which will not be consumable by Maven anymore. Such kind of setup will look like this:
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache</groupId>
<artifactId>apache</artifactId>
<version>18</version>
</parent>
<groupId>org.apache.maven.ci</groupId>
<artifactId>ci-parent</artifactId>
<name>First CI Friendly</name>
<version>${revision}</version>
...
<properties>
<revision>1.0.0-SNAPSHOT</revision>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>flatten-maven-plugin</artifactId>
<version>1.1.0</version>
<configuration>
<updatePomFile>true</updatePomFile>
<flattenMode>resolveCiFriendliesOnly</flattenMode>
</configuration>
<executions>
<execution>
<id>flatten</id>
<phase>process-resources</phase>
<goals>
<goal>flatten</goal>
</goals>
</execution>
<execution>
<id>flatten.clean</id>
<phase>clean</phase>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<modules>
<module>child1</module>
..
</modules>
</project>