Извлечь версию pom в трубопроводе Дженкинса
Я создал конвейер и использую встроенное определение сценария groovy конвейера и не могу получить версию pom. Я попробовал это, которое работает в отличной консоли, но в сценарии сборки Jenkins:
def project = new XmlSlurper().parse(new File("pom.xml"))
def pomv = project.version.toString()
Согласно документации Дженкинс имеет $POM_VERSION
но значение не имеет ничего, когда я назначаю его переменной и выводю его.
def pomv = "$POM_VERSION"
ИЛИ ЖЕ
def pomv = '$POM_VERSION"
У кого-нибудь есть идея?
11 ответов
Использование readMavenPom
как это:
pom = readMavenPom file: 'pom.xml'
pom.version
См. Модель ссылки для свойств (как и выше версия).
Чтобы это работало, нужно установить плагин Pipeline Utility Steps
В Jenkins 2.138.3 есть два разных типа конвейеров.
Декларативные и скриптовые конвейеры.
"Декларативные конвейеры - это новое расширение конвейерной DSL (это в основном конвейерный скрипт с одним шагом, конвейерным шагом с аргументами (так называемыми директивами), эти директивы должны следовать определенному синтаксису. Смысл этого нового формата в том, что он является более строгим и, следовательно, должно быть проще для новичков в конвейерах, допускает графическое редактирование и многое другое. Сценарии конвейеров являются запасным вариантом для расширенных требований ".
конвейер Дженкинса: агент против узла?
Вот пример декларативного конвейера:
pipeline {
agent any
environment {
//Use Pipeline Utility Steps plugin to read information from pom.xml into env variables
IMAGE = readMavenPom().getArtifactId()
VERSION = readMavenPom().getVersion()
}
stages {
stage('Test') {
steps {
echo "${VERSION}"
}
}
}
}
Пример скриптового конвейера
node('master') {
stage('Test') {
IMAGE = readMavenPom().getArtifactId()
VERSION = readMavenPom().getVersion()
echo "IMAGE: ${IMAGE}"
echo "VERSION: ${VERSION}"
}
}
Вот несколько хороших ссылок:
Декларативный https://github.com/jenkinsci/pipeline-examples/blob/master/declarative-examples/jenkinsfile-examples/mavenDocker.groovy
Сценарий https://bulldogjob.com/articles/726-exploring-jenkins-pipelines-a-simple-delivery-flow
Страница Начало работы с конвейером показала еще один вариант. Работает без дополнительных плагинов.
Чуть более надежную версию можно найти в общей библиотеке ces-build-lib (она также имеет несколько базовых модульных тестов):
def version() {
def matcher = readFile('pom.xml') =~ '<version>(.+?)</version>'
matcher ? matcher[0][1] : null
}
Это всегда соответствует первому <version>
тег можно найти в pom.xml
, В большинстве случаев это должна быть версия модуля maven или его родителя.
Я обычно использую readFile
шаг вместо new File()
где это возможно.
Так это будет выглядеть так:
def project = new XmlSlurper().parseText(readFile('pom.xml'))
def pomv = project.version.text()
Также убедитесь, что версия не наследуется от родителя. В этом случае вам понадобится:
def pomv = project.parent.version.text()
Не в последнюю очередь будьте осторожны XmlSlurper
не сериализуем. Вы вообще хотите использовать
@com.cloudbees.groovy.cps.NonCPS
в тех случаях. Я настоятельно рекомендую прочитать учебник Github - Сериализация локальных переменных.
Ты можешь попробовать readMavenPom
функция, которая доступна.
Более подробная информация здесь: https://jenkins.io/doc/pipeline/steps/pipeline-utility-steps/
Я обычно использую карту, чтобы сделать это.
def pomFile = readFile(pomName)
def pom = new XmlParser().parseText(pomFile)
def gavMap = [:]
gavMap['groupId'] = pom['groupId'].text().trim()
gavMap['artifactId'] = pom['artifactId'].text().trim()
gavMap['version'] = pom['version'].text().trim()
конвейер jenkins добавить этот этап. больше см.
stage('info')
{
steps
{
script
{
def version = sh script: 'mvn help:evaluate -Dexpression=project.version -q -DforceStdout', returnStdout: true
def artifactId = sh script: 'mvn help:evaluate -Dexpression=project.artifactId -q -DforceStdout', returnStdout: true
}
}
}
Я только что улучшил решение @haridsv без использования grep:
#!/usr/bin/env
def call(String mvnBin = 'mvn',String pom_file = 'pom.xml') {
return sh(
script: mvnBin+''' -N -f '''+pom_file+''' org.apache.maven.plugins:maven-help-plugin:evaluate -Dexpression=project.version -q -DforceStdout''',
returnStdout: true).trim()
}
Вам лучше не использовать readMavenPom, так как он будет устаревшим (см. PR https://github.com/jenkinsci/pipeline-utility-steps-plugin/pull/47/commits/eeebaa891a006c083ce10f883b7c1264533bb692). Вы можете скопировать и вставить это в файл, такой как valuMavenPomVersion.groovy:-)
Maven — источник истины, используйте его напрямую.
Например, чтобы получить стоимость имуществаfoo.bar
из pom.xml в Jenkinsfile:
def bar = sh(script: 'mvn help:evaluate -Dexpression=foo.bar -q -DforceStdout', returnStdout: true)
Кроме того, документы Pipeline Utility Steps предлагают избегать использованияreadMavenPom
.
Избегайте использования этого шага и напишите MavenPom. Лучше использовать шаг sh для запуска целей mvn.
Похоже на readMavenPom
это самый простой ответ, но так как он требует установки дополнительного конвейерного плагина, вот еще один, который использует родной подход maven вместо загрузки xml (на основе этого ответа)
def mvn_project_version(pom_file) {
return sh(
script: """mvn -N -f $pom_file org.apache.maven.plugins:maven-help-plugin:evaluate -Dexpression=project.version |
grep -Ev '(^\\s*\\[|Download\\w+:)'""",
returnStdout: true).trim()
}
Из-за использования grep
Команда this может не работать на некоторых платформах, которые не совместимы с posix, но вы всегда можете обработать вывод в Groovy вместо передачи по конвейеру grep
,
Я только начинаю с Jenkisfile
и у меня была такая же проблема, как и у вас. поскольку XmlSlurper
а также XmlParser
запрещены конфигурацией по умолчанию, я перечислил ниже функцию, чтобы извлечь версию maven:
String readProjectVersion(String pom) {
//Take value of the <project> tag
def matcher = pom.trim() =~ /(?s)<project[^>]*>(.*)<\/project>/
def pomWithoutProject = matcher[0][1].trim()
//remove every tag except <version>, since only project version is not encapsulated in the other tag e.g. dependency, parent, plugin
def nonVersionMatcher = pomWithoutProject =~ /(?s)\s*(?!<version>)<([a-zA-Z][a-zA-Z0-9]*)\b[^>]*>(.*?)<\/\1>\s*/
def versionTag = nonVersionMatcher.replaceAll("").trim()
//Take value of the <version> tag
def versionTagMatcher = versionTag =~ /<version>(.*)<\/version>/
if (versionTagMatcher.matches()) {
return versionTagMatcher[0][1]
}
//no version tag, version should be inherited from parent version
def parentVersionMatcher = pomWithoutProject =~ /(?s)\s*<parent>.*<version>(.*)<\/version>.*<\/parent>\s*/
return parentVersionMatcher[0][1]
}
Я проверил это решение для файлов, в которых родительский объект был объявлен, версия была первым оператором, версия была последним оператором и с наличием версии во вложенных тегах, таких как dependency
, plugin
и т.п.