Maven artifact version number with custom variable - maven

I have in my pom this section:
<groupId>com.sample.app</groupId>
<artifactId>simpleapp</artifactId>
<version>1.0.9-${buildNumber}-SNAPSHOT</version>
<packaging>war</packaging>
Is there any nice and "maven way" to keep this variable name ${buildNumber} in that place in pom as this is now?
I mean - when I am performing
mvn deploy:prepare deploy:release -DbuildNumber=${BUILD_NUMBER}
this version section in pom.xml is updated to (when BUILD_NUMBER eq: 12):
<version>1.0.9-12-SNAPSHOT</version>
which almost is ok but this is also commited to repository. I like the fact that this tag: 1.0.9-12 in git repo is created, but I prefer to keep my original format of version in pom.xml file:
<version>1.0.9-${buildNumber}-SNAPSHOT</version>
This is because this stupid approach I have in my company to add to artefact version also build number from CI tool :(
Can someone give me some hint how to handle this?

The Maven Release Plugin has a parameter called developmentVersion that allows you to set the new version that is committed to your git branch after the release is done.
If you want to tell the Release Plugin to reuse the parts of version you used before, the Build Helper Maven Plugin helps you to parse the version. It creates properties like majorVersion and minorVersion from which you can construct the target version you like.

UPDATE:
I've added dependency for this helper plugin and final result is like this:
mvn --batch-mode \
build-helper:parse-version \
-DdevelopmentVersion=\${parsedVersion.majorVersion}.\${parsedVersion.minorVersion}.\${parsedVersion.nextIncrementalVersion}-\${parsedVersion.qualifier} \
-DreleaseVersion=\${parsedVersion.majorVersion}.\${parsedVersion.minorVersion}.\${parsedVersion.incrementalVersion}-31 \
release:clean \
release:prepare \
release:perform
I removed this ${buildNumber} as it is not required - Build Helper Plugin helped me a lot - I do not need any additional step in CI plan.
Now I have autoincrement and during release I am able to add build plan ID.
For me case solved :-)

Related

How to allow any version in Snapshot repo

We're building feature branches into a version 'feature_'. Each feature build will produce the same version. Since these are no releases, I want to deploy the artefacts into the Snapshots repo, but Nexus does not allow versions without 'SNAPSHOT' into the Snapshot repo.
How to configure Nexus to allow any version in a repo?
Solved it by appending '-SNAPSHOT' to the branch version.
It's quite tricky to get Maven in Jenkins to use the right version. The way I solved it now is like this. In the build job configure Git to build the branches origin/feature/*. Then:
In the 'build' section, first thing to do is execute a shell command to construct a file 'env.properties' containing the feature branch version to be used by the Maven build command.
echo BRANCH_VERSION="feature_${GIT_BRANCH##*/}-SNAPSHOT" > env.properties
This uses the GIT_BRANCH environment property of Jenkins. The '##*/' is a Bash Shell Parameter Expansion which strips everything from the parameter value except the part after the last '/' character.
Then use the Environment Injector Plugin to 'inject environment variables' to the build job using the 'env.properties' created in the previous step.
Put 'env.properties' in the 'Properties File Path' field.
Use Maven to build a versioned pom with the correct version using 'Invoke top-level Maven targets':
help:effective-pom -Dbuild.number=${BRANCH_VERSION} -Doutput=versioned-pom.xml. This step is necessary because otherwise the pom in the jar artefact does not contain the correct version causing other problems.
Use another 'Invoke top-level Maven targets' step to do the actual build and deploy using the pom version created in the previous step: -f versioned-pom.xml clean source:jar deploy
That's all folks. If anyone knows a simpler solution, let me know.
This is actually a Maven restriction. You can still use version like feature_x-1.2.3-SNAPSHOT though.
What are you actually trying to achieve though?

Updating the versions in a Maven multi-module project

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

Maven: change version properties in pom.xml

I have a Maven pom.xml, I build project and release project deploy with Jenkins.
But before and after build "release version" we need set my version in
For example:
I have in pom.xml
<properties>
<version-own>0.0.21-SNAPSHOT</version-own>
</properties>
before release I need set like this
<properties>
<version-own>0.0.25</version-own>
</properties>
after release I need set like this
<properties>
<version-own>0.0.27-SNAPSHOT</version-own>
</properties>
How can this be done?
If you don't have to use your own version property, consider the following that will operate on your <project><version>0.0.21-SNAPSHOT</version></project> element:
mvn versions:set versions:commit -DnewVersion="0.0.25"
That will modify your pom and adjust the version to your liking. You'll likely want to commit this change to your source code control repository, for this the scm plugin's scm:checkin goal works just fine (assuming you want this to be automated):
mvn scm:checkin -Dincludes=pom.xml -Dmessage="Setting version, preping for release."
Then you can perform your release (I recommend the maven-release-plugin), after which you can set your new version and commit it as above.
The versions plugin is your friend. Scripting the above would likely involve some parameterized build, or preferably the groovy plugin for jenkins which allows you to get the maven-specific build variables.
For starters, you can do it by hand. If your build follows maven conventions well, you could probably leverage one of a couple of maven plugins that exist for helping with the management of version numbers.
The maven-versions-plugin helps automate manual changes to version numbers. It has nice CLI commands to help tune up your poms before doing releases.
Then there's the maven-release-plugin that automates the whole process of cutting a release. It will change your snapshot to a release version, then roll it to the next snapshot after the release build. During all this process it commits discrete versions of the poms to source control.
Again, the secret to seeing success in the more automated bits of the maven community is whether your build is doing things the maven way or not. Hacked, highly tweaked, non-conventional builds usually have a lot of barriers to successful use of the release plugin.
There is one way to to that easily. With one command you can change whichever part you want:
For cut and paste:
mvn build-helper:parse-version versions:set -DbuildNumber=555 '-DnewVersion=${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}-${buildNumber}'
For clarity:
mvn build-helper:parse-version versions:set -DbuildNumber=555
'-DnewVersion=
${parsedVersion.majorVersion}
.${parsedVersion.minorVersion}
.${parsedVersion.incrementalVersion}
-${buildNumber}'
This is a concise example how to update versions in one go with build values
Build-helper plugin supports regex replacements, and can even parse version numbers if need be.
http://www.mojohaus.org/build-helper-maven-plugin/
There is something like parsedVersion.nextIncrementalVersion
mvn build-helper:parse-version versions:set -DnewVersion=\${parsedVersion.majorVersion}.\${parsedVersion.minorVersion}.\${parsedVersion.nextIncrementalVersion} versions:commit
Looking at this comment you are describing that you are using this version to provide a dependency. maven-release-plugin should help you manage the versions for you. So provide that plugin in your pom.xml.
And for the step of manually providing the release and development version, create a job in jenkins which will have 2 string parameters:
developmentVersion
releaseVersion
Add "Invoke top-level Maven targets" build step to execute the releasing (for example):
clean release:clean release:prepare release:perform -DdevelopmentVersion=${developmentVersion} -DreleaseVersion=${releaseVersion}
When building the job, it will prompt you to insert both the developmentVersion and releaseVersion.
Cheers,
Despot

parameterise POM file (Maven)

Whenever I want to create a new version of my projects, I have to go in and edit the <version> tag in the POM files.
The projects are related, so they have the same version, most of the time.
Is it possible to just put the new version in some file, and have the POM regenerated when needed?
Thanks
The best thing in such situations is to use the release plugin which supports automatically changing the version in the pom and creating a tag/label in the appropriate VCS. There are two steps release:prepare and release:perform which can simply be combined.
A command like this:
mvn release:prepare release:prepare
will do all needed steps like making a tag in VCS, change pom's version and deploy the artifacts to your repository. But the prerequesite is having correct entries in the SCM area of your pom, correctly configured the distributionManagement etc.
If the project comprises of several modules which have the same version this sounds like using a multi-module build instead of separated projects which would solve the problem of changing the version manually.

org.apache.maven.BuildFailureException: No SCM URL was provided to perform the release from

I'm using Maven 2.2.1 and I sucessfully ran:
mvn -B release:clean release:prepare
But get the error message:
No SCM URL was provided to perform the release from
when I run:
mvn release:perform
My pom.xml have the scm tags defined correctly:
<scm>
<url>file:///C:/tmp/svnrepo/myproj/trunk</url>
<connection>scm:svn:file:///C:/tmp/svnrepo/myproj/trunk</connection>
<developerConnection>scm:svn:file:///C:/tmp/svnrepo/myproj/trunk</developerConnection>
</scm>
It is possible to rerun a maven release:perform by creating a manually edited release.properties file in the root folder. This file should define these two properties: scm.url and scm.tag. Here a possible example:
scm.url=scm:git:https://github.com/owner/repo.git
scm.tag=v1.0.4
With this file it is possible to redo a release:perform task.
Inspired by this answer.
Looks like I did a mvn -DdryRun=true release:perform and this had deleted the release.properties file from the prepare stage.
So I add the -DconnectionUrl to the command to provide url of the tag
It should work. I had similar problem, but in my case perform failed due to network error and I had to restart it with something like:
mvn release:perform -rf :{ARTIFACT ON WHICH IT FAILED} -DconnectionUrl=scm:svn:{URL TO TAG}
The message
No SCM URL was provided to perform the release from
does not mean the SCM URL in the pom.xml!
There are two kinds of SCM-URLS:
Trunk Folder (for development)
Tag Folder (for tagging the release)
In the pom.xml you specify the trunk-folder-url. What the release:perform require is the tag-folder-url. You can specify the parameter -DconnectionUrl.
Usually you are using prepare and perform in one maven call. Prepare do all preparation stuff and will commit some resources to the version-control-system using the comment [maven-release-plugin] prepare release XXX- BUT NOT ALL FILES ARE COMMITTED! One important file is not committed to the version-control-system, the release.properties. This file is used if you omit the -DconnectionUrl.
The problem occourse while perform because the checkout/commit require the release.properties or the -DconnectionUrl respectivly.
You can either:
Specify the tag-url by using -DconnectionUrl or
Call release:prepare release:perform in one shot to rely on the not-committed release.properties
More informations are here
I got this same exception in our CI automation and it turned out to be due to the fact that target/checkout directory already has a release build. For one of the projects, we had to introduce an improvised maven release perform build between the real maven release:prepare and release:perform steps. As part of improvisation the release tag is checked out to target/checkout and what I noticed is that if this directory is left undeleted, it would cause the release:perform to fail with the No SCM URL was provided to perform the release from error. I don't know if it matters, but we also use -DlocalCheckout=true option.
Simply running mvn release:clean release:prepare first, and then mvn release:perform worked for me.

Resources