在Jenkins中获取Maven版本

在处理POM之后,Jenkins构build是否可以知道项目的Maven版本号?

我有一些项目,其中版本控制是由Maven控制的,在后期构build工作中,我们希望创build一个Debian包并调用一些shell脚本。 我需要的是Maven用作Jenkins环境variables的版本号,所以我可以将它传递给构build后的操作。

要清楚的是,我不需要知道如何让Jenkins把一个版本号传给Maven; 相反,我希望Maven将一个版本号传给Jenkins!

您可以使用https://issues.jenkins-ci.org/browse/JENKINS-18272引入的$ {POM_VERSION}variables

经过大量的挖掘(我从来没有意识到jenkins的文档logging很糟糕!)我发现了一个相当简单的解决scheme。

  1. 安装Groovy插件
  2. 添加一个Post Step到types为Execute **system** Groovy script Maven构buildExecute **system** Groovy script
  3. 粘贴到以下Groovy代码片段中:

脚本:

 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); 

现在可以使用名为MAVEN_VERSION的构build环境variables以通常方式( ${MAVEN_VERSION} )replace到其他构build后步骤。 我使用它来进行Git标记等等。

正如已经指出的其他答案,如果您正在使用Maven项目types,您可以访问$ POM_VERSIONvariables。 但是,如果你不是,你可以使用这一系列的步骤(丑陋但可靠)。 这样做依赖于相同版本的maven来确定pom版本(当处理复杂的父/子pominheritance时,对于孩子甚至可能不存在<version> )。

  1. Maven迈出这一目标:

    org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version -l version.log

  2. Shell步骤 :(您可能需要根据您的层次结构调整到version.log的path)

    echo "POM_VERSION=$(grep -v '\[' version.log)" > props.properties

  3. 注入环境variables步骤 (环境注入器插件):

    属性文件path: props.properties

现在你可以使用$ POM_VERSION ,就好像这是一个Maven项目。

这是什么:使用maven打印输出一起混乱的版本,然后greps out只剩下版本的输出乱七八糟,把它写入一个文件使用属性文件格式,然后注入到构build环境。 这是比mvn ..... | grep -v '\['更好的原因mvn ..... | grep -v '\[' mvn ..... | grep -v '\['是使用Maven步骤不会对已安装的Maven版本进行假设,并且将通过与其他Maven步骤相同的自动安装进行处理。

我们使用了Groovy Postbuild插件 。

  String regex = '.*\\[INFO\\] Building .+ (.+)'; def matcher = manager.getLogMatcher(regex); if (matcher == null) { version = null; } else { version = matcher.group(1); } 

把它添加到Jenkins稍后使用是有点棘手。 给我一个镜头,虽然我记得这让我们头疼。 (对不起,我们很久以前就这样做了)

 def addBuildParameter(String key, String value) { manager.build.addAction(new hudson.model.ParametersAction(new hudson.model.StringParameterValue(key,value))); } 

有同样的需要和解决build议与Groovyparsing的POM。

 import jenkins.util.*; import jenkins.model.*; def thr = Thread.currentThread(); def currentBuild = thr?.executable; def workspace = currentBuild.getModuleRoot().absolutize().toString(); def project = new XmlSlurper().parse(new File("$workspace/pom.xml")) def param = new hudson.model.StringParameterValue("project.version", project.version.toString()) currentBuild.addAction(new hudson.model.ParametersAction(param)); 

添加这个脚本作为“Execute system Groovy script”types的后续步骤(所以不需要安装Groovy)并将代码粘贴到“Groovy命令”中。

执行“Execute Shell”中的Maven插件“exec-maven-plugin”作为“有条件的一步”为我工作:

 mvn -q -Dexec.executable="echo" -Dexec.args='${projects.version}' --non-recursive org.codehaus.mojo:exec-maven-plugin:1.3.1:exec 

在Jenkins集成:

 -> "Add post-build step" -> "Conditional steps (single or multiple)" -> "Execute Shell:" 

export MY_POM_VERSION =`mvn -q -Dexec.executable =“echo”-Dexec.args ='$ {projects.version}' – 非recursionorg.codehaus.mojo:exec-maven-plugin:1.3.1:exec `&& [[“$ {MY_POM_VERSION}”==“THE_VERSION_TO_BE_MATCHED”]] && echo“CONDITION_IS_MET”

  -> "Steps to run if condition is met" -> Add any build step you need 

笔记:

  • THE_VERSION_TO_BE_MATCHED必须与您的版本进行交换
  • '&& echo“CONDITION_IS_MET”'仅用于debugging目的。 为了同样的目的,你可以在mvn命令后加一个'&& echo“MY_POM_VERSION = $ {MY_POM_VERSION}”'来理解发生了什么。

这种方法比“grep”更可靠,如果没有安装Jenkins Ruby插件,它可能是一个替代scheme。

你也可以这样做:

 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`" 

说明:假定您的项目名称在一行或两行以上/以下的版本中,如正常的pom:

 <groupId>org.apache.bigtop</groupId> <artifactId>bigpetstore</artifactId> <version>1.0-SNAPSHOT</version> 

然后你可以很容易地grep artifactId,使用“之前/之后”的grep动作来吸取它的版本,然后grep版本,并使用简单的unix“cut”命令来拼接出“版本”标签。

我喜欢Jenkins-groovy集成,但是这样更容易,甚至可以在你不能控制的构build服务器(即bash是通用的)上运行。

解:

 POM_VERSION=$( \ xmlstarlet sel \ -N x='http://maven.apache.org/POM/4.0.0' \ -t \ -v '//x:project/x:version/text()' \ pom.xml \ ) 

说明:

您可以使用命令行XPath工具单行执行此操作,例如“ 如何从shell执行XPath单行程序 ”中提到的那些工具。 我select了XMLStarlet ,但它们都有类似的语法。

parsingPOM时,必须考虑名称空间。 这里的文档帮助我弄清楚了这一点。

为了获得XPath中元素的文本,可以使用text()函数,如XPath中所述:select文本节点 。

我的POM看起来像这样:

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

这里的缺点是,如果命名空间改变,你必须改变命令。