Is there any way a Jenkins build can be aware of the Maven version number of a project after processing the POM?
I\'ve got some projects where versioning is controll
Based on @Akom`s answer the pre steps to have POM_VERSION are:
Script
mvn org.apache.maven.plugins:maven-help-plugin:evaluate -Dexpression=project.version -l project_version
# grep for the version pattern rather than not mentioning '\['
echo "POM_VERSION=$(grep -E '^[0-9.]+(-SNAPSHOT)?$' project_version)" > your_property_file
After a lot of digging around (I never realised how poorly-documented Jenkins is!) I found a quite trivial solution.
Post Step
to your Maven build of type Execute **system** Groovy script
Script:
import hudson.model.*;
import hudson.util.*;
def thr = Thread.currentThread();
def currentBuild = thr?.executable;
def mavenVer = currentBuild.getParent().getModules().toArray()[0].getVersion();
def newParamAction = new hudson.model.ParametersAction(new hudson.model.StringParameterValue("MAVEN_VERSION", mavenVer));
currentBuild.addAction(newParamAction);
The build environment variable called MAVEN_VERSION
will now be available for substitution into other post-build steps in the usual manner (${MAVEN_VERSION}
). I'm using it for Git tagging amongst other things.
Using 'Execute System Groovy Script' as follows:
import jenkins.util.*;
import jenkins.model.*;
def thr = Thread.currentThread();
def currentBuild = thr?.executable;
def projectManager = build.getProject()
def file = projectManager.getWorkspace().child("pom.xml");
def project = new XmlSlurper().parseText(file.readToString())
def param = new hudson.model.StringParameterValue("currentVersion", project.version.toString())
currentBuild.addAction(new hudson.model.ParametersAction(param));
By using Execute System Groovy script you have direct access to the build, from which you can get the project and thus the "child" file in this case pom.xml.
You won't have to create a new file and as you can see it offers very powerful access to every file within the workspace.
You could also do :
MAVEN_VERSION=`grep A -2 -B 2 "<your_project_name>" pom.xml | grep version | cut -d\> -f 2 | cut -d\< -f 1`-commit-"`echo $GIT_COMMIT`"
Explanation: assuming that you have your project name within a line or two above/below version like a normal pom:
<groupId>org.apache.bigtop</groupId>
<artifactId>bigpetstore</artifactId>
<version>1.0-SNAPSHOT</version>
Then you can easily grep for the artifactId, use the "before/after" grep actions to suck in the version with it, and then grep the version out and use the simple unix "cut" command to splice out the content between "version" tags.
I like the Jenkins-groovy integration, but this is alot easier and will work even on a build server which you dont have control over (i.e. because bash is universal).
Solution:
POM_VERSION=$( \
xmlstarlet sel \
-N x='http://maven.apache.org/POM/4.0.0' \
-t \
-v '//x:project/x:version/text()' \
pom.xml \
)
Explanation:
You can do this in a one-liner using a command-line XPath tool, such as those mentioned at "How to execute XPath one-liners from shell?". I chose XMLStarlet, but they all have similar syntax.
When parsing a POM, you have to account for namespaces. The docs here helped me figure this out.
In order to get the text for an element in XPath, you use the text() function as explained at XPath: select text node.
My POM looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.foo.bar</groupId>
<artifactId>foobar</artifactId>
<version>1.0.6-SNAPSHOT</version>
<packaging>jar</packaging>
The downside here is that if the namespace changes, you have to change the command.