Change version of Maven project without manipulating the POM file - maven

Is it somehow possible to change the version of a Maven project without manipulating the POM file?
Let's say I have a Maven project with version 1.5.0-SNAPSHOT but I want to build it as 1.5.46.
The Versions Maven Plugin unfortunately modifies the POM files.

Since Maven 3.5.0 this is possible using a special predefined property: ${revision}. Define the property with a default value (e.g. 1.5.0-SNAPSHOT) and when needed, set it during execution to a specific version (e.g. 1.5.46).
For example, define the following in your pom.xml:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>foo</artifactId>
<name>Foo Module</name>
<version>${revision}</version>
...
<properties>
<revision>1.5.0-SNAPSHOT</revision>
</properties>
</project>
Build it using the default value:
mvn clean install
This will produce an artifact identified as org.example:foo:1.5.0-SNAPSHOT.
In order to build a specific version, set the revision property, for example:
mvn clean install -Drevision=1.5.46
This will produce an artifact identified as org.example:foo:1.5.46.
For further details, see the Maven CI Friendly Versions page.

Try to override project version with
mvn versions:set -DnewVersion=<version>
in your particular case:
mvn versions:set -DnewVersion=1.5.46

You can
Make a copy of your pom as temppom.xml
Replace the version in temppom.xml
Build with mvn -f temppom.xml.
Delete temppom.xml.

Maven supports delivery friendly versions, see https://issues.apache.org/jira/browse/MNG-5576 .
For more details I would suggest to talk with #khmarbaise

The plugin provides a goal to revert the changes made by it:
mvn versions:revert

Related

Maven release plugin

Hi Meier I have used the following goal
mvn org.codehaus.mojo:versions-maven-plugin:2.7:update-property -
Dproperty=emom.web.dependency.shr.version -DallowSnapshots=true
My Job B pom.xml is
<dependency>
<groupId>com.safeway.app</groupId>
<artifactId>emom-shr</artifactId>
<version>${emom.web.dependency.shr.version}</version>
</dependency>
Under the properties it has version harcoded
<emom.web.dependency.shr.version>19.6.5-
SNAPSHOT</emom.web.dependency.shr.version>
My Job A pom.xml
<groupId>com.safeway.app</groupId>
<artifactId>emom-shr</artifactId>
<version>20.1.0-SNAPSHOT</version>
<packaging>jar</packaging>
When I run the above goal maven is picking the latest version i,e(20.1.0)
from artifactory but when I check the pom.xml of Job B under properties it still says 19.6.5 I need a way to change the 19.6.5 or current version to latest version available. Am I doing something wrong not able to figure it out.
You need versions:update-property to update the content of properties in your POM.
See https://www.mojohaus.org/versions-maven-plugin/update-property-mojo.html

Can I refer to POM properties from the command line?

Given a property defined inside the pom, can I refer to that property from the command line?
This is what I would like to achieve:
# instead of:
mvn versions:set -DnewVersion=x.y.z
# something like this:
mvn versions:set -DnewVersion=properties:library.version
This way I can manage my multi-modular project version in one place and update all modules at the same time.
Is something like this possible? Perhaps by preconfiguring the version plugin inside the pom itself and completely omit the newVersion property from the command line?
You actually have a better way to reach you goal:
https://maven.apache.org/maven-ci-friendly.html
Idea is to use property ${revision} instead of version value.
So in all you POMs you do something like that:
Parent POM:
<groupId>my.group</groupId>
<artifactId>my.artifact</artifactId>
<version>${revision}</version>
Sub-modules:
<parent>
<groupId>my.group</groupId>
<artifactId>my.artifact</artifactId>
<version>${revision}</version>
</parent>
Now at the root of the project (where you project parent POM) you provide /.mvn/maven.config file (FYI: https://maven.apache.org/docs/3.3.1/release-notes.html (JVM and Command Line Options)):
/.mvn
maven.config
/submodule-one
/submodule-two
pom.xml
maven.config contains setting of the version to the property:
-Drevision=1.1.10-SNAPSHOT
And do not forget to provide in the parent POM flatten-maven-plugin configuration with flattenMode=resolveCiFriendliesOnly, exactly like described in the documentation by link above.
As result, maven.config is the only place where you need set version for all you modules.
And you not need to change anything in POMs when you want to change version.
But to make it works you need at least maven 3.5.0-beta-1.
P.S. you can see all of that in my maven testing project:
https://github.com/Gmugra/net.cactusthorn.maven
It's actually very easy, just provide the newVersion property in the pom:
<properties>
<library.version>1.0.0</library.version>
<newVersion>${library.version}</newVersion>
</properties>
Then simply execute versions:set without providing the property and it will pick up on the property from the POM instead:
mvn versions:set
Alternative solution:
You can also skip the property and have maven dynamically update the current version:
The following increases patch version:
mvn build-helper:parse-version versions:set -DnewVersion=${parsedVersion.nextMajorVersion}.${parsedVersion.minorVersion}.${parsedVersion.IncrementalVersion} versions:commit
This is built into Maven and works out-of-the-box.

version property dynamic in pom.xml

I have a Maven pom.xml, I build project and executable jar deploy in Nexus with Jenkins.
But I want changes of version name according to branch name.
For example: I have in pom.xml
<groupId>net.test</groupId>
<artifactId>test-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>iin-parent</name>
<packaging>pom</packaging>
I need set like this : (Branch- Master/Test1/Test2/..)
<groupId>net.test</groupId>
<artifactId>test-parent</artifactId>
<version>BranchName_0.0.1-SNAPSHOT</version>
<name>iin-parent</name>
<packaging>pom</packaging>
How can this be done?
I was using MVN build like -Drevision=BranchName-SNAPSHOT clean compile package deploy. But I want dynamically fetch the branch name.
enter code here
If you use clean compile package deploy you are duplicating several parts..only clean deploy is needed. Please read the documentation about Maven Life cycle.
Furthermore if you like to change the version dynamically you can do that by using the correct properties (Starting with Maven 3.5.0+) which are ${revision}, ${sha1} and ${changelist} so for example:
<groupId>net.test</groupId>
<artifactId>test-parent</artifactId>
<version>${revision}</version>
<properties>
<revision>1.0-SNAPSHOT</revision>
</properties>
This can be done in Maven like this:
mvn -Drevision=2.0-SNAPSHOT clean package
or if you like to do this for a branch:
mvn -Drevision=2.0-BranchName-SNAPSHOT clean package
You have to be aware if you like to do mvn clean deploy please read carefully the docs and follow them.

Maven Snapshot in pom.xml

There are a easy way to make Maven put "-SNAPSHOT" on my versions? We have a project with many POMs.
We usualy create branchs from TAGs that haven't SNAPSHOTs.
Use the release plugin:
mvn --batch-mode release:update-versions -DdevelopmentVersion=1.2.0-SNAPSHOT
You can use the versions-plugin to do that:
mvn versions:set -DnewVersion=1.2.0-SNAPSHOT
Alternatively, you could use release:branch to even create the branch as well (provided the scm settings in your pom are correct):
(check out tag)
mvn release:branch -DbranchName=my-branch -DupdateBranchVersions=true -DupdateWorkingCopyVersions=false -DreleaseVersion=1.0.1-SNAPSHOT
Yes, the property is named releaseVersion, although it is really the version for the branch. (see: http://maven.apache.org/maven-release/maven-release-plugin/examples/branch.html for details)
Define new property in parent pom.xml:
<properties>
<myprojectversion>0.0.1-SNAPSHOT</myprojectversion>
</properties>
and use it whenever needed: ${myprojectversion}.
If this solution is too rough. Consider to define more properties for minor, major, postfix etc. parts of intended version code.

Maven: Selecting Parent Project Based On Profile

I have a maven project - it is a plugin for jenkins. It's parent should be a:
<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>1.414</version>
</parent>
But at the same time this plugin can be also used for hudson, without changing any line of code. But the parent project for it should be:
<parent>
<groupId>org.jvnet.hudson.plugins</groupId>
<artifactId>hudson-plugin-parent</artifactId>
<version>2.0.1</version>
</parent>
Can I specify 2 different profiles for that and use them to build plugin for jenkins or hudson accordingly? So that I call something like that:
mvn package -P jenkins
or
mvn package -P hudson
I have tried to specify properties in profiles, but those are not replaced by their values inside the <parent> tag. So is there any other possibility to build plugin for both, but with as much as possible common code and files?
Added: So, if I cannot do that, what should I do then? How to refactor? What the new structure should be?
As already mentioned, this is not possible.
Also, it is not possible to set a property for the parent's version as the interpolation for that happens a lot earlier than the handling of the profiles.
I would suggest that you create a masterbuild project as follows:
master
|-plugin-jenkins
|-plugin-hudson
|-plugin-assembly
The master should build all three as usual. However, in the assembly, you could add each of the two plugins as dependencies in separate profiles. And... each of these plugins can have the parent you like.
This is obviously somewhat a deviation from the Maven convention, but I believe it is a solution to your problem.
It's not possible because the tag "parent" is not available in the profiles section of the pom.
Currently we decided to stick with 1 repository and 2 separate pom.xml files, giving maven key which pom.xml use to build the project.
mvn package -f pom-jenkins.xml
mvn package -f pom-hudson.xml
No you cannot do that. you will have to refactor somehow to avoid the necessity.
As mentioned already not possible. I would suggest to make separate projects for jenkins plugin and hudson plugin. I assume that in not that far future that will not work anymore cause Hudons and Jenkins will diverge.
In general, you should be able to set the {group,artifact}Id and version of the parent POM via Java System Properties or Environment Variables, but it seems there is a Bug in Maven which will only be fixed in 4.x:
https://issues.apache.org/jira/browse/MNG-624
Another solution is to delegate the inclusion of the parent POM to your own parent POMs which you reference in the relativePath element, and change the content of the target e.g. via a symlink or cp command.
So in the main POM you would write:
<parent>
<groupId>org.mycompany.project</groupId>
<artifactId>foo-artifact</artifactId>
<version>1.0.0</version>
<relativePath>./my-parent.pom</relativePath>
</parent>
And in my-parent-jenkins you would just put:
<groupId>org.mycompany.project</groupId>
<artifactId>foo-artifact</artifactId>
<version>1.0.0</version>
<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>1.414</version>
</parent>
The same project information with the block for hudson you put in my-parent-hudson.pom.
No you can either use
ln -s my-parent-jenkins.pom my-parent.pom
or
ln -s my-parent-hudson.pom my-parent.pom
to include the respective parent POM without the need to maintain two different main POM files for your project.
In case POM does not exist at the place referenced in relativePath, Maven will look up the POM in the remote repository[1], which is also an easy way to overwrite a parent POM locally.
[1] http://maven.apache.org/components/ref/3.3.9/maven-model/maven.html#class_parent

Resources