Получение версии проекта от Maven POM в Дженкинсе
Есть ли способ, которым Jenkins build может знать о версии версии Maven проекта после обработки POM?
У меня есть некоторые проекты, в которых управление версиями контролируется Maven, и в задании после сборки мы хотели бы создать пакет Debian и вызвать некоторые сценарии оболочки. Мне нужен номер версии, которую Maven использовал для использования в качестве переменной среды Jenkins, поэтому я могу передать ее для действий после сборки.
Чтобы быть ясным, мне не нужно знать, как заставить Дженкинса передать номер версии Maven; вместо этого я хочу, чтобы Maven передал номер версии Дженкинсу!
Ответы
Ответ 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 среди других вещей.
Ответ 2
Вы можете использовать переменную ${POM_VERSION}, которая была введена с https://issues.jenkins-ci.org/browse/JENKINS-18272
Ответ 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:
- "Введите переменные среды" с помощью файла свойств your_property_file. Обратите внимание, что если вы выберете "Внедрить переменные среды в процесс сборки", файл должен существовать в рабочей области jenkins.
- выполнить в предварительном шаге выполнить 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