Updating the versions in a Maven multi-module project - maven

I have Maven multi-module project and I would like to update the development versions to a given value using a script. The aggregator POM is only an aggregator and the children do not inherit from it. This is important because the artifacts all inherit from other POM files. Here is my structure
aggregator/
--projectA
--projectB
Also, projectB has a Maven dependency on projectA.
First I tried:
mvn -DnewVersion=0.28-SNAPSHOT -DupdateMatchingVersions=true versions:set
It only updated the aggregator project's version.
If I run the Maven release process, it correctly updates projectB's dependency on projectA to use the new development version after the release build. Because the release process handles this well, I thought that using the release plugin might solve my issue.
So I tried the following:
mvn -DdevelopmentVersion=0.28-SNAPSHOT -DautoVersionSubmodules=true --batch-mode release:update-versions
This updated all of my sub-projects correctly. However it did not update projectB's dependency version for projectA.
What is a simple way to update all the development versions in my project, including projectB's dependency on projectA?

You may have more luck with the release plugin but it may require some tweaking
versions:set is designed to update the version of the pom that it executes against... ie the root of the reactor.
If you follow it's conventions, then it will work... But you need to know its conventions.
When you have /project/parent/version and /project/version both specified but "accidentally" at the same value, the versions plugin assumes that the two versions are just accidentally the same, and so does not update the child project's version when the parent version is being updated. updateMatchingVersions tells the plugin to assume that it us not an accident and that the child should be in lock step.
If you only specify /project/parent/version and leave the project version unspecified, therefore relying on inheritance, the plugin will add the child project to the list of version changes (and hence loop through all the projects again to ensure it catches any additional required changes)
The versions plugin does not currently provide an option to force everything to the one version... Though that might be a good idea.
You can get what you want with three commands, eg
mvn versions:set -DnewVersion=...
cd projectA
mvn versions:set -DnewVersion=...
cd ../projectB
mvn versions:set -DnewVersion=...
This is because versions:set will attempt to "grow" the reactor if the parent directory contains an aggregator pom that references the invoked project...
In other words when you have a reactor with no common parent, versions assumes that the common version number is by accident, but it will pick up the intent from the wider reactor

# for each module into aggregator pom
for module in $(grep "\<module\>" pom.xml | sed 's/<\/module>//g' | sed 's/.*<module>//g' | sed 's/.*\///g')
do
# set the version of the module
# and update reference to this module into others modules
mvn versions:set -DgenerateBackupPoms=false -DartifactId=$module \
-DnewVersion=$newVersion -DupdateMatchingVersions=true
done
# set the version of the aggregator pom
mvn versions:set versions:commit -DnewVersion=$newVersion

i found your same problem ,then i clone versions plugin code , then I found if you set gropuId,artifcatId,oldVersion value tobe * will solve the problem;
like this :
mvn versions:set -DnewVersion=xxx -DgroupId=* -DartifactId=* -DoldVersion=*

Related

How to update/fix a single child module's parent version

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

mvn versions:set doesn't update all pom.xml files

We run mvn versions:set -DnewVersion=x.x.x to update the version of our project. For some projects it updates the version in all pom.xml files except one or two. What are some reasons that this command wouldn't update all files?
There are some reasons. The parent is not correctly set in the childs. The childs have different versions as the parent or the other childs. The child is only part of the aggregator based on some profiles.
So you can try with:
mvn version:set -DnewVersion=3.6.0 -DoldVersion=* -DgroupId=* -DartifactId=*
This is explained at https://www.mojohaus.org/versions-maven-plugin/examples/setaggregator.html.
For more advice we would need the pom files.

How to set the parent pom version on a project

I'm using the versions plugin to... set versions.
mvn versions:set -DnewVersion=XXXX
That work's great on aggregate project with declared modules
Now my question is how, in other maven project can I change the parent pom version ? I've placed high hopes in the versions:update-parent but I would like just to set the parent with the version i'm specifying regardless whether that version is deployed or not. Besides I can't get it to work. It never modifies the actual pom. Is there a way to do just that using a mvn plug-in ? Right now it's a manual pom.xml edit.
Thanks
Aa.
I usually use release plugin for that. It changes version of the parent and all the submodules:
mvn release:update-versions -DautoVersionSubmodules=true
Details are here:
http://maven.apache.org/maven-release/maven-release-plugin/examples/update-versions.html

Maven force update only for specific dependency (mvn -U for selected dependencies)

The command mvn -U forcing all project dependencies to get updated from remote repository.
Is it possible to force such update for specific selection of dependencies, by explicit selection / by some logic?
The reasoning:
I don't want to force checking all the dependencies we have because how time consuming it is. All I need, is to verify a few of them or even specify only one dependency. So, such solution is highly desired.
There are two maven plugins that may help you here.
The first, dependency, will simply download the given version of a dependency:
mvn dependency:get -Dartifact=groupId:artifactId:version
The second, versions, offers some behaviors which you may also find helpful.
By running mvn versions:use-latest-releases -Dincludes=groupId:artifactId your project's pom will be updated with the latest release version of the dependency specified by the '-Dincludes' flag. You could then run the first command to download the version now referenced by your pom.
Both of these behaviors can be heavily customized and automated to do some quite awesome things. To get more help on a plugin goal, run: mvn plugin:help -Ddetail=true -Dgoal=goal
Example: mvn versions:help -Ddetail=true -Dgoal=use-latest-releases
For further information:
versions, dependency, and plugins

Maven version:set does not update child modules

After finally getting tired of maven release plugin I deceided to move on to something more simpler.
I have a project, with a couple of modules.
When I do
mvn versions:set -DnewVersion=1.0.2-SNAPSHOT
it just changes the parent and skips all child modules?
what am I doing wrong? do I need to set another parameter as well?
I had the same problem of submodules referencing external parents.
If the child's parent version matches the parent's local version, then it updates the versions of the parent and child (it might say SKIPPED but still work, bizarrely). If they don't match then it seems to only update the parent's version and update the children to point to the new parent, it doesn't change the children's versions at all.
Finally i found that wildcards could resolve this problem (requires a new'ish version of the versions plugin):
mvn org.codehaus.mojo:versions-maven-plugin:2.2:set -DnewVersion=1.5.0a -DartifactId=* -DgroupId=*
Alternatively you can also use the processAllModules parameter.
$ mvn versions:set -DnewVersion=2.0.0 -DprocessAllModules
If you're like me with a project whose child modules don't match the parent's version, another option is to adjust them to match first:
$ mvn versions:update-child-modules
then versions:set (and versions:replace-snapshot etc.) will now work as expected, without needing a newer version of the plugin :)
$ mvn versions:set -DnewVersion=1.0.2-SNAPSHOT
I'm assuming that your project structure is like this:
parent/pom.xml
child/pom.xml
Then you have to run mvn versions:set -DnewVersion=1.0.2-SNAPSHOT from parent/ directory.
If anyone searching for an answer, below command worked like a charm for me
mvn release:update-versions -DdevelopmentVersion=4.4.0-SNAPSHOT
Maybe is because you don't declare the plugin in parent pom in Plugin Management. If you want to propagate the plugin to the childs you have to declare in Plugin Management Section.
See: http://maven.apache.org/pom.html#Plugin_Management
I eventually ran mvn -X to discover one of my child poms was saved in UTF-8 BOM encoding:
[DEBUG] Could not parse child-project\pom.xml
java.io.IOException: only whitespace content allowed before start tag and not \uef (position: START_DOCUMENT seen \uef... #1:1)
at org.codehaus.mojo.versions.api.PomHelper.getRawModel (PomHelper.java:116)
The Exception was 'hidden' in DEBUG logging.
I re-saved it using UTF-8 encoding, and it worked.
(Encountered with Maven 3.5.4 / Versions-Maven-Plugin 2.7)

Resources