从Jenkins的Maven POM获取项目版本

问题描述 投票:49回答:11

在处理POM之后,Jenkins构建是否有任何方法可以了解项目的Maven版本号?

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

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

maven jenkins
11个回答
61
投票

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


0
投票

使用'Execute System Groovy Script'如下:

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

通过使用Execute System Groovy脚本,您可以直接访问构建,从中可以获取项目,因此在本例中为“child”文件pom.xml。

您不必创建新文件,因为您可以看到它提供了对工作区内每个文件的非常强大的访问权限。


0
投票

基于@ Akom`sanswer,POM_VERSION的前步骤是:

  1. 使用属性文件your_property_file“注入环境变量”。请注意,如果选择“将环境变量注入构建过程”,则该文件需要存在于jenkins工作空间中。
  2. 在预先执行shell中运行以下bash脚本。

脚本

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

21
投票

经过大量的挖掘(我从来没有意识到Jenkins的文档记录是多么糟糕!)我找到了一个非常简单的解决方案。

  1. 安装Groovy插件
  2. Post Step添加到Execute **system** Groovy script类型的Maven版本中
  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标记等。


8
投票

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

  1. Maven迈出了这个目标: org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version -l version.log
  2. Shell步骤:(您可能需要根据您的层次结构调整version.log的路径) echo "POM_VERSION=$(grep -v '\[' version.log)" > props.properties
  3. 注入环境变量步骤(Environment Injector Plugin): 属性文件路径:props.properties

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

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


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

3
投票

有同样的需求并解决了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)并将代码粘贴到“Groovy命令”中。


3
投票

我在声明性管道作业中使用了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}")
            }
        }
    }
}

注意:在管理jenkins>进程内脚本批准中创建作业后,必须批准getVersion()方法。

也可以看看:


1
投票

在“执行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

整合在詹金斯:

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

export MY_POM_VERSION =`mvn -q -Dexec.executable =“echo”-Dexec.args ='$ {projects.version}' - non-recursive org.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”'仅用于调试目的。出于同样的目的,您可以在mvn命令之后添加'&& echo“MY_POM_VERSION = $ {MY_POM_VERSION}”',以便了解发生了什么。

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


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>

然后你可以轻松地grep for artifactId,使用“之前/之后”grep动作来吸引它的版本,然后grep版本并使用简单的unix“cut”命令拼出“版本”之间的内容标签。

我喜欢Jenkins-groovy集成,但这很容易,甚至可以在你无法控制的构建服务器上工作(即因为bash是通用的)。


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中元素的文本,可以使用XPath: select text node中解释的text()函数。

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

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

© www.soinside.com 2019 - 2024. All rights reserved.