0

Structure

I know this project structure is not "the Maven way" and this is why I struggle in the first place. Unfortunately I cannot change the project structure.

I try to simplify it as much as possible:

/module-a
/module-b
/module-c
/parent              <- <parent>master</parent>, <modules>module-a, module-b, module-c</modules>
/parent/aggregator-d <- <parent>parent</parent>, <modules>module-a, module-b</modules>
/parent/aggregator-t <- <parent>parent</parent>, <modules>module-a</modules>

Use Case

The version of all modules should be changed to a given version. Apart from the parent module, no module explicitly defines its version, so only the parent version has to be changed. But since the parent version is referenced in all other modules, they have to be updated accordingly.

This works fine (using release:update-versions -DautoVersionSubmodules on the parent) for all modules that are listed in a <modules> section in the parent POM (or activated profile). However, the remaining modules aggregator-d and aggregator-t are not updated.

Failed attempts

So I thought I'd update the remaining modules separately, using mvn --non-recursive, but with no luck so far.

With the release plugin, I only managed to update their own version, using release:update-versions, however this does not update the referenced parent version, so it results in a module version different than the parent version (the explicit module version declaration has been added by the release plugin):

<parent>
  [...]
  <version>1.0.0-SNAPSHOT</version>
</parent>
<version>1.0.0-changed-SNAPSHOT</version> <- added by release plugin

Using the versions plugin, versions:set fails because the module version is defined by its parent, versions:update-parent does not work because I cannot specify the new parent version (instead the newest version found in the remote repository will be set) and versions:update-child-modules tells me that all child modules are up to date (because the idea is to run it on an aggregator which references the module I want to have updated).

Other ideas

The Maven commands are executed within a Jenkins declarative pipeline, so maybe I could try the (deprecated) writeMavenPom.

Apart from that and using something like sed or maven-antrun-plugin for regex replacement, I've run out of ideas.

halfer
  • 19,824
  • 17
  • 99
  • 186
msa
  • 702
  • 7
  • 14
  • 1
    Are you really sure you cannot change the project structure? Have you talked to your manager and explained that the current structure is unfortunate? – J Fabian Meier Mar 04 '20 at 12:40
  • Yes, at least not short term. I'll try to get a task into the backlog for this. I guess we can e.g. use profiles instead of separate aggregators (so the parent by default won't define any modules but provides profiles "parent", "aggregator-d" and "aggregator-t" defining the desired modules). – msa Mar 04 '20 at 13:20
  • This also does not sound like a good idea. If you only want to build one or two modules, why don't you just specify them on the command line? – J Fabian Meier Mar 04 '20 at 13:28
  • At least it would solve the problems I do have right now, I guess. The two aggregator modules do also specify additional properties, plugins and dependencies, so command line would not be very practical, if possible at all (and would not be tracked in the Git repository). – msa Mar 04 '20 at 13:35

1 Answers1

0

Reading more documentation on the versions Maven plugin I noticed that for the parameter newVersion of versions:update-property it says:

If you like to define the version to be used exactly you have to use it like this: -DnewVersion=[19.0] otherwise a newer existing version will be used.

So I applied this information to the parameter parentVersion of versions:update-parent, together with -DallowSnapshots. I then got this warning (while the build still succeeded):

[WARNING] Not updating version: could not resolve any versions

Luckily I found out that the desired version is not required to exist in the remote repository, it's OK if it exists in the local repository. So what I did to finally make everything work is just mvn --non-recursive install the parent POM before using versions:update-parent.

All in all I do this now (-N is --non-recursive, ${v} resolves to e.g. 1.0.0-changed-SNAPSHOT):

mvn -f parent release:update-versions -DautoVersionSubmodules -DdevelopmentVersion=${v}
mvn -f parent -N install
mvn -f parent/aggregator-d -N versions:update-parent -DallowSnapshots -DparentVersion=[${v}]
mvn -f parent/aggregator-t -N versions:update-parent -DallowSnapshots -DparentVersion=[${v}]

This solution is not very pretty but i favor it over using regex or deprecated Jenkins API.

msa
  • 702
  • 7
  • 14