📜 ⬆️ ⬇️

Experience using flatten-maven-plugin to simplify versioning in maven projects

About Us


In 1C, we are developing not only the 1C: Enterprise C ++ platform and JavaScript , but also Java applications — in particular, the Eclipse-based Enterprise Development Tools development environment and the server that is deeply integrated with the messenger platform, the Interoperability System .

Introduction


As a system for building Java applications, we most often use maven, and in this small article we would like to talk about one of the problems we had to face in the development organization process and the approach that allowed us to overcome this problem.

Background and Workflow


Due to the specifics of development in our maven-projects we use quite a lot of modules, dependencies and subsidiary projects. The number of pom-files in one tree can be in the tens and even hundreds.

image
')
It would seem: nothing terrible, once created and forgotten. If you need to change or add something in all files at once, there are a lot of handy tools in editors and IDE. And what is the most common regular change to pom.xml? We believe that changing project versions and dependencies. Maybe someone wants to argue with that, but this is the case with us. The reason lies in the fact that, in addition to the kernel, we are simultaneously developing many of our own libraries, and for the constant reproducibility of the results of assembly and testing, the use of snapshots does not seem to us a convenient approach. For this reason, and you have to raise the version number in projects with each build.

Also, the developer from time to time there is a need to build a branch of a library and test its performance across all dependencies, for which they all have to manually change the version.

Initial decision


With such frequent and multiple version changes, I want to simplify and automate the process within CI. Here comes the handy well-known plugin versions-maven-plugin - connect it and run

mvn -N versions: set -DnewVersion = 2.0.1

and the maven will do everything as it should: run through the hierarchy from top to bottom, all versions will replace - beauty! Now it remains to raise the pull-request, colleagues will see the changes, and you can quickly join the trunk. Quickly? As if not so. A couple of hundred pom.xml on the review, and that's not counting the code. In addition, no one is insured against merge conflicts with such a large number of modified files. It should be noted here that in the CI process, version changes occur automatically along with a change in functionality, and not somehow separately.

New opportunities


For some time we calmed down and, having resignedly, and lived, until the guys from the Maven Apache Project included in maven, starting with version 3.5.0-beta-1, support for so-called "placeholders" versions (placeholders). The essence of these substitutes is that in pom.xml, instead of a specific indication of the project version, the variables $ {revision} , $ {sha1} and $ {changelist} are used . The values ​​of these properties themselves are set either in the < properties > element, or they can be defined through the system property

mvn -Drevision = 2.0.0 clean package

The values ​​of the system properties take precedence over the values ​​defined in < properties >.

Parent
<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>

Descendant
<project>
<modelVersion> 4.0.0 </ modelVersion>
<parent>
<groupId> org.apache.maven.ci </ groupId>
<artifactId> ci-parent </ artifactId>
<version> $ {revision} $ {sha1} $ {changelist} </ version>
</ parent>
<groupId> org.apache.maven.ci </ groupId>
<artifactId> ci-child </ artifactId>
...
</ project>


If you want to build version 2.0.0-SNAPSHOT, then just use

mvn -Drevision = 2.0.0 clean package

If you want to make a release, then just reset SNAPSHOT

mvn -Dchangelist = clean package

* The examples above are taken from an article on the Maven Apache Project website.

Harsh reality


Everything is good and healthy, it's time to feel a sense of satisfaction, but no. It turns out that for install and deploy this method will not work, because in descriptions of artifacts published in the repository the $ {revision} will not be replaced by its value and maven will not understand what it is about anymore.

<parent>
<groupId> org.apache </ groupId>
<artifactId> apache </ artifactId>
<version> $ {revision} </ version>
</ parent>


A light in the end of a tunnel


We must seek a solution to the problem. The situation could save the flatten-maven-plugin . This plugin resolves all variables in pom, but at the same time cuts out a lot of other information that is needed only during assembly and is not needed when importing published artifacts into other projects. Also, the plugin “straightens” all parent-child dependencies, and as a result we get flat pom, including everything you need. The inconvenience was that he cut out the “excess” too much, which did not suit us at all. After studying the information on the development of this plugin, it turned out that we are not alone in the universe, and as early as August 2018 a pull-request was created on the githaba in the plugin's repository with the desire to make it possible to determine how to spoil pom.xml. The developers listened to the voices of the afflicted, and in December, with the release of the new version 1.1.0, the new resolveCiFriendliesOnly mode appeared in the flatten-maven-plugin, which more than ever fit - it leaves pom.xml as it is, except the <version> element and resolves $ {revision} , $ {sha1} and $ {changelist} .

Add a plugin to the project

<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>


Done!

Happy end


From now on, to change the version of the entire project and let all the dependencies know about it, we just need to edit the < revision > element in the root pom.xml only. Not one hundred or two of these files with the same change arrive on the review, but one. Well, there is no need to use versions-maven-plugin .

Source: https://habr.com/ru/post/449172/


All Articles