'How do I Extract Version ID from POM inside Jenkins Declarative and Scripted pipelines?
I've created a pipeline and using the embedded groovy pipeline script definition and can't seem to get the version ID of the project from the POM. I tried this which works in a groovy console but on in the Jenkins build pipeline script:
def project = new XmlSlurper().parse(new File("pom.xml"))
def pomv = project.version.toString()
According to the documentation Jenkins has a $POM_VERSION but the value doesn't have anything in it when I assign it to a variable and echo it out.
def pomv = "$POM_VERSION"
OR
def pomv = '$POM_VERSION"
Solution 1:[1]
Use readMavenPom like this:
pom = readMavenPom file: 'pom.xml'
pom.version
See Model reference for properties (like the above version).
For this to work, one has to install Pipeline Utility Steps plugin
Solution 2:[2]
In Jenkins 2.138.3 there are two different types of pipelines.
Declarative and Scripted pipelines.
"Declarative pipelines is a new extension of the pipeline DSL (it is basically a pipeline script with only one step, a pipeline step with arguments (called directives), these directives should follow a specific syntax. The point of this new format is that it is more strict and therefore should be easier for those new to pipelines, allow for graphical editing and much more. scripted pipelines is the fallback for advanced requirements."
jenkins pipeline: agent vs node?
Here is an example of a Declarative Pipeline:
pipeline {
agent any
environment {
//Use Pipeline Utility Steps plugin to read information from pom.xml into env variables
IMAGE = readMavenPom().getArtifactId()
VERSION = readMavenPom().getVersion()
}
stages {
stage('Test') {
steps {
echo "${VERSION}"
}
}
}
}
Example of Scripted Pipeline
node('master') {
stage('Test') {
IMAGE = readMavenPom().getArtifactId()
VERSION = readMavenPom().getVersion()
echo "IMAGE: ${IMAGE}"
echo "VERSION: ${VERSION}"
}
}
Here are some good links:
Scripted https://bulldogjob.com/articles/726-exploring-jenkins-pipelines-a-simple-delivery-flow
Solution 3:[3]
You could always shell out and use maven to query the version, e.g. like so:
echo sh(returnStdout: true,
script: 'mvn org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate ' +
'-Dexpression=project.version -q -DforceStdout ' +
'--batch-mode -U -e -Dsurefire.useFile=false'
).trim()
# Note: Use "./mvnw" with Maven wrapper
Where
-Dexpression=project.version -q -DforceStdoutare mandatory (see here for details), and--batch-mode -U -e -Dsurefire.useFile=falseare recommended for CI usage (see here for details).
This is also implemented in the shared library ces-build-lib. Here it is as convenient as
echo mvn.version
The Getting Started with Pipeline page showed yet another option. It has some disadvantages, though (see bellow and comments):
def version() {
def matcher = readFile('pom.xml') =~ '<version>(.+?)</version>'
matcher ? matcher[0][1] : null
}
This always matches the first <version> tag to be found in the pom.xml. This should be the version of the maven module or its parent in most cases. It could be the version of the parent, though.
Solution 4:[4]
You can try readMavenPom function that is available.
More info is here: https://jenkins.io/doc/pipeline/steps/pipeline-utility-steps/#readmavenpom-read-a-maven-project-file
Solution 5:[5]
I usually use the map to do this.
def pomFile = readFile(pomName)
def pom = new XmlParser().parseText(pomFile)
def gavMap = [:]
gavMap['groupId'] = pom['groupId'].text().trim()
gavMap['artifactId'] = pom['artifactId'].text().trim()
gavMap['version'] = pom['version'].text().trim()
Solution 6:[6]
I've just enhanced @haridsv solution without using grep:
#!/usr/bin/env
def call(String mvnBin = 'mvn',String pom_file = 'pom.xml') {
return sh(
script: mvnBin+''' -N -f '''+pom_file+''' org.apache.maven.plugins:maven-help-plugin:evaluate -Dexpression=project.version -q -DforceStdout''',
returnStdout: true).trim()
}
You'd better not use readMavenPom since it's going to be deprecated ( see PR https://github.com/jenkinsci/pipeline-utility-steps-plugin/pull/47/commits/eeebaa891a006c083ce10f883b7c1264533bb692 ). You can copy and paste this in a file such as evaluateMavenPomVersion.groovy :-)
Solution 7:[7]
Seems like readMavenPom is the most straight-forward answer, but since it required installation of an additional pipeline plugin, here is another that uses the native maven approach instead of loading xml (based on this answer)
def mvn_project_version(pom_file) {
return sh(
script: """mvn -N -f $pom_file org.apache.maven.plugins:maven-help-plugin:evaluate -Dexpression=project.version |
grep -Ev '(^\\s*\\[|Download\\w+:)'""",
returnStdout: true).trim()
}
Because of the use of grep command this may not work on some platforms that are not posix compatible, but you can always process the output in Groovy instead of piping through grep.
Solution 8:[8]
jenkins pipeline add this stage. more see
stage('info')
{
steps
{
script
{
def version = sh script: 'mvn help:evaluate -Dexpression=project.version -q -DforceStdout', returnStdout: true
def artifactId = sh script: 'mvn help:evaluate -Dexpression=project.artifactId -q -DforceStdout', returnStdout: true
}
}
}
Solution 9:[9]
I'm just starting with Jenkisfile and I had the same problem as you. Since XmlSlurper and XmlParser are forbidden by default configuration i have crated below function to extract maven version:
String readProjectVersion(String pom) {
//Take value of the <project> tag
def matcher = pom.trim() =~ /(?s)<project[^>]*>(.*)<\/project>/
def pomWithoutProject = matcher[0][1].trim()
//remove every tag except <version>, since only project version is not encapsulated in the other tag e.g. dependency, parent, plugin
def nonVersionMatcher = pomWithoutProject =~ /(?s)\s*(?!<version>)<([a-zA-Z][a-zA-Z0-9]*)\b[^>]*>(.*?)<\/\1>\s*/
def versionTag = nonVersionMatcher.replaceAll("").trim()
//Take value of the <version> tag
def versionTagMatcher = versionTag =~ /<version>(.*)<\/version>/
if (versionTagMatcher.matches()) {
return versionTagMatcher[0][1]
}
//no version tag, version should be inherited from parent version
def parentVersionMatcher = pomWithoutProject =~ /(?s)\s*<parent>.*<version>(.*)<\/version>.*<\/parent>\s*/
return parentVersionMatcher[0][1]
}
I have tested this solution against files where parent was declared, version was first statement, version was last statement and with presence of version in nested tags like dependency, plugin etc.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | pitchblack408 |
| Solution 3 | |
| Solution 4 | Raitis Dembovskis |
| Solution 5 | Mohamed Thoufeeque |
| Solution 6 | Vincenzo Cerbone |
| Solution 7 | |
| Solution 8 | |
| Solution 9 |
