Jenkins:在全局函数的主体中获取环境变量

Scr*_*ler 3 groovy jenkins jenkins-plugins jenkins-pipeline

我在 PublishGitHub.groovy 上有一个共享的全局函数,如下所示:

#!/usr/bin/env groovy
def call(body)
{
    def config = [:]
    body.resolveStrategy = Closure.DELEGATE_FIRST
    body.delegate = config

    echo "\u001B[32mINFO: Publishing...\u001B[m"
    body()
    echo "\u001B[32mINFO: End Publish...\u001B[m"      
}
Run Code Online (Sandbox Code Playgroud)

以及我的 JenkinsFile 上的代码:

environment {
    VERSION = "v1.3.${env.BUILD_NUMBER}"
}
stages {
    stage ('Publish WebAPI'){
        steps{
            echo "\u001B[32mINFO: Start Publish...\u001B[m"

            PublishGitHub{
                echo "This is a body with version: ${env.VERSION}"
            }               
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的输出:

[Pipeline] echo
INFO: Start Publish...
[Pipeline] echo
INFO: Publishing...
[Pipeline] }
Run Code Online (Sandbox Code Playgroud)

并遵循下一个错误:

java.lang.NullPointerException:无法在空对象上获取属性“VERSION”

因为我在body里面没有访问环境变量?

Szy*_*iak 5

您的共享库代码在工作流 CPS 上下文之外运行,这就是您传递给 vars 脚本的闭包无法识别env属性的原因。您可以通过传递对工作流脚本的引用来解决此问题。如果你这样调用你的函数

PublishGitHub(this) {
    echo "This is a body with version: ${env.VERSION}"
}
Run Code Online (Sandbox Code Playgroud)

并对vars/PublishGitHub.groovy脚本进行一些小的修改,例如:

#!/usr/bin/env groovy

def call(config, body) {
    body.resolveStrategy = Closure.DELEGATE_FIRST
    body.delegate = config

    echo "\u001B[32mINFO: Publishing...\u001B[m"
    body()
    echo "\u001B[32mINFO: End Publish...\u001B[m"
}
Run Code Online (Sandbox Code Playgroud)

然后您将成功运行您的管道:

[Pipeline] {
[Pipeline] withEnv
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Publish WebAPI)
[Pipeline] echo
[32mINFO: Start Publish...[m
[Pipeline] echo
[32mINFO: Publishing...[m
[Pipeline] echo
This is a body with version: v1.3.537
[Pipeline] echo
[32mINFO: End Publish...[m
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
Run Code Online (Sandbox Code Playgroud)

如果您想限制共享库的范围,您总是可以简单地传递env而不是this更改vars/PublishGitHub.groovy为如下内容:

#!/usr/bin/env groovy

def call(env, body) {
    def config = [
            env: env
    ]
    body.resolveStrategy = Closure.DELEGATE_FIRST
    body.delegate = config

    echo "\u001B[32mINFO: Publishing...\u001B[m"
    body()
    echo "\u001B[32mINFO: End Publish...\u001B[m"
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您只允许共享库访问环境变量。