2012-03-27 61 views
44

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

我有一些项目,其中版本控制是由Maven控制的,在后期构建工作中,我们想创建一个Debian包并调用一些shell脚本。我需要的是Maven曾经作为Jenkins环境变量提供的版本号,所以我可以将它传递给构建后的操作。

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

+0

只是一个建议:这个是什么:http://mojo.codehaus.org/deb-maven-plugin/ – khmarbaise 2012-03-28 09:04:51

回答

21

很多四处之后(我从来没有意识到不良的记录詹金斯怎么样了!)我发现了一个很平凡的解决方案。

  1. 安装Groovy插件
  2. 添加Post Step到Maven构建类型的Execute **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现在可用于以通常方式替换到其他构建后步骤(${MAVEN_VERSION})。我将其用于Git标记等。

+2

这个工程就像一个魅力,如果你更新'def mavenVer ='行到什么在你的[稍后跟进](http://stackoverflow.com/a/10205702/487663) - def mavenVer = currentBuild.getParent() .getModules()。toArray()[0] .getVersion();' – 2012-09-26 13:13:36

+0

确实将“def mavenVer ...”替换为上一条评论中的代码。 – 2012-10-29 15:25:24

+1

这与'POM_VERSION'相同,因为这个bug .jenkins-ci.org/browse/JENKINS-24869 – yegeniy 2016-10-31 14:35:55

3

我们使用了Groovy Postbuild Plugin

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))); 
} 
+0

你会怎样做,然后'版本'可用于其他事情步骤的工作? – 2012-03-28 11:22:56

+0

你好,我有点扩大了答案。祝你好运! – 2012-03-28 11:41:25

+0

此解决方案适用于在POM文件中使用变量有动态填充的版本号的情况。在这些情况下使用POM_VERSION或解析pom.xml文件将不起作用。 – swbandit 2015-02-10 15:42:51

2

与Groovy解析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)); 

添加此脚本类型的后工序“执行系统Groovy脚本”(所以安装的Groovy是没有必要的),并粘贴在“常规命令”的代码。

+0

请参阅[项目版本从maven到sonar -using-hudson](http://stackoverflow.com/questions/14691818/project-version-from-maven-to-sonar-using-hudson/15879456# 15879456) – Sylvain 2013-04-08 12:51:57

+0

我尝试在shell脚本步骤中使用'$ {project.version}',之后它失败了:''''''''''''''''''''''' 。似乎jenkins不允许var名称中的'dot'? – yetanothercoder 2013-05-20 10:01:09

+0

这在Jenkins 2.46+中似乎不起作用。虽然Groovy提取的版本很好,但我的Freestyle项目的其余部分中的'project.version'环境变量是空的。在Jenkins 2+中有没有改变它的作用?我试图以'$ {project.version}'的形式访问这个var' – 2017-07-26 21:14:43

0

你也可以这样做:

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> 

然后你就可以很容易地对于artifactId使用grep,使用“before/after”grep操作来吸引版本,然后grep版本,并使用简单的unix“cut”命令来拼接出“版本”标签之间的内容。

我喜欢Jenkins-groovy集成,但是这很容易,即使在你不能控制的构建服务器上(即bash是通用的),它也能工作。

+0

这个工作就像一个魅力,但是获取了多个版本信息,因为它也包含一个版本标签。 在它为我工作的grep和管道之前添加一个头 MAVEN_VERSION ='head“”“pom.xml | grep A -2 -B 2 | grep版本| cut -d \> -f 2 | cut -d \ <-f 1'-commit-“'echo $ GIT_COMMIT'” – JoeDred 2014-07-10 06:58:00

+0

@JoeDred我仍然获得多个版本。但我的 “另一版本” 是不是从依赖,但是从性能:** cz.px.iis \t IIS的核心纳克 \t 罐子 \t 2.1.1-SNAPSHOT \t \t \t 7.7.5 \t \t UTF-8 \t \t 1.8 \t \t 1.8 \t **和输出是__2.1.1-SNAPSHOT 7.7.5__ – agad 2017-01-18 15:43:05

+0

@agad也许你应该限制你管道的第一个grep。 Head采用可选参数-n或--lines。试试** head --help **,它显示了它是如何使用的。 – JoeDred 2017-01-20 07:03:36

56

您可以使用$ {POM_VERSION}变量,这与https://issues.jenkins-ci.org/browse/JENKINS-18272

+0

太棒了!验证你需要Jenkins maven plugin v2.3或更高版本的'$ {POM_VERSION}'工作,我认为它需要是一个Maven项目类型。 – 2014-05-13 12:55:08

+1

这不适合我。 Jenkins中的Maven Interation插件是2.5版本,仍然是这样说的:$ {ENV,var =“POM_VERSION”}:如果我尝试直接或通过上述方式尝试使用此变量,则会导致错误的替换。 “Build Number Set”插件框中的“$ {POM_VERSION}。$ {BUILD_NUMBER}”中无法识别宏'POM_VERSION'。 – 2014-07-30 20:46:28

+2

请记住,POM_VERSION不会考虑可能已传递给maven构建过程的任何环境变量。例如: $ {CUSTOM_VERSION} 将为空或具有默认值。 – swbandit 2015-02-04 18:13:41

1

介绍,执行中的“执行shell”的Maven插件“的exec-Maven的插件”作为“条件步”工作对我来说:

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

整合詹金斯:

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

出口MY_POM_VERSION =`MVN -q -Dexec.executable =“ECH o“ -Dexec.args ='$ {projects.version}' - 非递归org.codehaus.mojo:exec-maven-plugin:1.3.1:exec` & & [[ ”$ {MY_POM_VERSION}“ == “THE_VERSION_TO_BE_MATCHED”]] & &呼应 “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”'仅用于调试目的。出于同样的目的,您可以在mvn命令之后添加一个'& & echo“MY_POM_VERSION = $ {MY_POM_VERSION}”',以便了解发生了什么。

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

6

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

  1. Maven的一步这一目标:

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

  2. 壳牌迈:(您可能需要调整路径取决于你的层次结构件version.log)

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

  3. 进样环境变量步骤(环境喷油器插件):

    属性文件路径:props.properties

现在你可以使用$ POM_VERSION仿佛这是一个Maven项目。

这是干什么的:使用maven打印输出一起输出的版本,然后输出只剩下版本的输出乱码,使用属性文件格式将其写入文件,然后将其注入到构建中环境。这比像mvn ..... | grep -v '\['这样的单线程更好的原因在于,使用Maven步骤不会对已安装的Maven版本做出假设,并且将通过与任何其他Maven步骤相同的自动安装进行处理。

+0

存在grep过滤器的一个问题:如果你没有存储库中的插件,你会得到还有POM_VERSION中的“下载...”行。例如:'+ echo'POM_VERSION =正在下载:...' – apa64 2017-11-22 08:23:57

0

解决方案:

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

说明:

您可以在一个班轮使用命令行工具的XPath,如在 “How to execute XPath one-liners from shell?” 提到的那些做到这一点。我选择了XMLStarlet,但它们都有类似的语法。

解析POM时,必须考虑命名空间。文档here帮助我弄清楚了这一点。

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

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

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

0

我在声明式管道作业中使用Pipeline Utility Steps插件来获取Maven版本。在下面的示例中,我使用脚本变量而不是环境变量,因为可以修改并在各阶段之间传递。

def TAG_SELECTOR = "UNINTIALIZED" 
pipeline { 
    agent any 
    stages { 
     stage('Build') { 
      steps { 
       sh "mvn --batch-mode -U deploy" 
       script { 
        TAG_SELECTOR = readMavenPom().getVersion() 
       } 
       echo("TAG_SELECTOR=${TAG_SELECTOR}") 
      } 
     } 
    } 
} 

注:您必须在创建工作后,批准的getVersion()方法管理詹金斯>在处理脚本审批

参见:

相关问题