从Jenkins管道中的POM中提取版本ID

时间:2016-06-02 23:18:55

标签: maven jenkins jenkins-pipeline

我已经创建了一个管道并使用了嵌入式groovy管道脚本定义,似乎无法从POM获取项目的版本ID。我试过这个在groovy控制台中工作,但是在Jenkins构建管道脚本中:

def project = new XmlSlurper().parse(new File("pom.xml"))
def pomv = project.version.toString()

根据文档,Jenkins有一个$POM_VERSION但是当我将它分配给变量并将其回显时,该值中没有任何内容。

def pomv = "$POM_VERSION"

OR

def pomv = '$POM_VERSION"

8 个答案:

答案 0 :(得分:66)

像这样使用readMavenPom

pom = readMavenPom file: 'pom.xml'
pom.version

请参阅Model参考资料(如上述版本)。

为此,必须安装Pipeline Utility Steps plugin

答案 1 :(得分:6)

Getting Started with Pipeline页面显示了另一种选择。它没有额外的插件工作。

在共享库ces-build-lib中可以找到稍强大的版本(它还有一些基本的unit tests):

def version() {
    def matcher = readFile('pom.xml') =~ '<version>(.+?)</version>'
    matcher ? matcher[0][1] : null
}

这始终与<version>中找到的第一个pom.xml标记相匹配。在大多数情况下,此 应该是maven模块或其父级的版本。

答案 2 :(得分:5)

在詹金斯2.138.3中,有两种不同类型的管道。

声明性和脚本化管道。

“声明性管道是管道DSL的新扩展(基本上是只有一步的管道脚本,带有参数的管道步骤(称为指令),这些指令应遵循特定的语法。这种新格式的要点在于它更加严格,因此对于管道新手来说应该更容易,允许进行图形编辑等等。 脚本化管道是高级需求的后备。”

jenkins pipeline: agent vs node?

以下是声明性管道的示例:

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

答案 3 :(得分:3)

您可以尝试readMavenPom可用的功能。

更多信息在这里:https://jenkins.io/doc/pipeline/steps/pipeline-utility-steps/#readmavenpom-read-a-maven-project-file

答案 4 :(得分:0)

似乎readMavenPom是最直接的答案,但由于它需要安装额外的管道插件,所以这是另一个使用本机maven方法而不是加载xml(基于this answer

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命令,这可能不适用于某些不兼容posix的平台,但您始终可以在Groovy中处理输出,而不是通过grep进行管道传输。

答案 5 :(得分:0)

我只是在不使用grep的情况下增强了@haridsv解决方案:

#!/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)。您可以将其复制并粘贴到诸如validateMavenPomVersion.groovy的文件中:-)

答案 6 :(得分:-1)

我通常使用地图来做到这一点。

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

答案 7 :(得分:-1)

我刚开始Jenkisfile,我遇到了和你一样的问题。由于默认配置禁止使用XmlSlurperXmlParser,因此我在下面的函数中创建以提取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]
}

我已经针对声明了父文件,版本是第一个语句,版本是最后一个语句以及在dependencyplugin等嵌套标签中存在版本的文件测试了此解决方案。