Подтвердить что ты не робот

Получение версии проекта от Maven POM в Дженкинсе

Есть ли способ, которым Jenkins build может знать о версии версии Maven проекта после обработки POM?

У меня есть некоторые проекты, в которых управление версиями контролируется Maven, и в задании после сборки мы хотели бы создать пакет Debian и вызвать некоторые сценарии оболочки. Мне нужен номер версии, которую Maven использовал для использования в качестве переменной среды Jenkins, поэтому я могу передать ее для действий после сборки.

Чтобы быть ясным, мне не нужно знать, как заставить Дженкинса передать номер версии Maven; вместо этого я хочу, чтобы Maven передал номер версии Дженкинсу!

4b9b3361

Ответ 1

После долгих рывков (я никогда не понимал, насколько плохо документированы Дженкинс!) Я нашел довольно тривиальное решение.

  • Установите плагин Groovy
  • Добавьте Post Step к вашей конструкции Maven типа Execute **system** Groovy script
  • Вставить следующий фрагмент Groovy:

Script:

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 среди других вещей.

Ответ 3

Как уже указывалось в других ответах, если вы используете тип проекта Maven, у вас есть доступ к переменной $POM_VERSION. Но если вы этого не сделаете, вы можете использовать эту последовательность шагов (уродливую, но надежную). Выполнение этого способа основывается на одной и той же версии maven для определения версии pom (при обработке сложного наследства родительского/дочернего pom, где <version> может даже не присутствовать для дочернего элемента).

  • Шаг Maven с этой целью:

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

  • Шаг шага: (Возможно, вам потребуется настроить путь к версии .log в зависимости от вашей иерархии)

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

  • Шаг переменных Inject Environment (плагин инжектора окружающей среды):

    Путь к файлу свойств: props.properties

Теперь вы можете использовать $POM_VERSION, как если бы это был проект Maven.

Что это делает: Использует maven для печати версии вместе с беспорядком вывода, а затем сглаживает беспорядок вывода, оставляя только версию, записывает ее в файл с использованием формата файла свойств и затем вводит его в среду сборки, Причина, по которой это лучше, чем однострочный, такой как mvn ..... | grep -v '\[', заключается в том, что использование шага Maven не делает предположений о установленных версиях maven и будет обрабатываться одной и той же автоматической установкой, как и любые другие шаги maven.

Ответ 4

Мы использовали 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))); 
}

Ответ 5

Была такая же потребность и решена, как предложено с помощью 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));

Добавьте этот script в качестве постулата типа "Выполнить систему Groovy script" (поэтому не нужно устанавливать Groovy) и вставить код в команду "Groovy".

Ответ 6

Я использовал плагин 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() после создания задания в разделе "Управление jenkins> Утверждение внутрипроцессного сценария".

Смотрите также:

Ответ 7

Выполните Maven Plugin "exec-maven-plugin" в "Execute Shell", поскольку "Условный шаг" работал у меня:

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" ]] && & && эхо "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" 'предназначен только для целей отладки. С этой же целью вы можете добавить '& & echo "MY_POM_VERSION = ${MY_POM_VERSION}" после команды mvn, чтобы понять, что происходит.

Этот подход более надежный, чем "grep", и это может быть альтернативой, если Jenkins Ruby Plugin не установлен.

Ответ 8

Вы также можете сделать:

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 и использовать простую команду "cut" unix для сращивания содержимого между теги "версии".

Мне нравится интеграция Jenkins- groovy, но это намного проще и будет работать даже на сервере сборки, на который у вас нет контроля (т.е. поскольку bash является универсальным).

Ответ 9

Решение:

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

Объяснение:

Вы можете сделать это в одном слое с помощью инструмента XPath из командной строки, например, упомянутого в разделе Как выполнить однострочные оболочки XPath из оболочки? ". Я выбрал XMLStarlet, но все они имеют схожий синтаксис.

При анализе POM вы должны учитывать пространства имен. Документы здесь помогли мне понять это.

Чтобы получить текст для элемента в XPath, вы используете функцию text(), как описано в XPath: выберите текст 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>

Недостатком здесь является то, что если пространство имен изменяется, вам нужно изменить команду.

Ответ 10

Используя "Выполнить системный 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 у вас есть прямой доступ к сборке, из которой вы можете получить проект и, следовательно, "дочерний" файл в данном случае pom.xml.

Вам не нужно создавать новый файл, и, как вы видите, он предлагает очень мощный доступ к каждому файлу в рабочей области.

Ответ 11

На основе ответа @Akom предварительные шаги для получения 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