在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。
- 安装Groovy插件
- 添加一个
Post Step
到types为Execute **system** Groovy script
Maven构buildExecute **system** Groovy script
- 粘贴到以下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> )。
-
Maven迈出这一目标:
org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version -l version.log
-
Shell步骤 :(您可能需要根据您的层次结构调整到version.log的path)
echo "POM_VERSION=$(grep -v '\[' version.log)" > props.properties
-
注入环境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>
这里的缺点是,如果命名空间改变,你必须改变命令。