詹金斯(Jenkins):在全局函数的主体中获取环境变量

詹金斯(Jenkins):在全局函数的主体中获取环境变量

问题描述:

我在PublishGitHub上有一个共享的全局函数.groovy看起来像这样:

I have a shared global function on PublishGitHub.groovy looks like this:

#!/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"      
}

以及我的JenkinsFile上的代码:

And a code on my 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}"
            }               
        }
    }
}

这是我的输出:

[Pipeline] echo
INFO: Start Publish...
[Pipeline] echo
INFO: Publishing...
[Pipeline] }

并遵循下一个错误:

java.lang.NullPointerException:无法在null上获取属性"VERSION" 对象

java.lang.NullPointerException: Cannot get property 'VERSION' on null object

因为我体内没有环境变量?

Because inside the body I do not have access to the environment variables?

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

Your shared library code runs outside of the workflow CPS context, that is why closure you pass to the vars script does not recognize env property. You can fix this problem by passing a reference to the workflow script. If you call your function like this

PublishGitHub(this) {
    echo "This is a body with version: ${env.VERSION}"
}

,您对vars/PublishGitHub.groovy脚本进行了小的修改,例如:

and you apply a small modification to vars/PublishGitHub.groovy script like:

#!/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"
}

那么您将成功运行管道:

then you will run your pipeline successfully:

[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

如果要限制共享库的范围,则始终可以简单地传递env而不是this并将vars/PublishGitHub.groovy更改为以下内容:

If you want to limit the scope for the shared library, you can always simply pass env instead of this and change vars/PublishGitHub.groovy to something like this:

#!/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"
}

在这种情况下,您授予共享库仅对环境变量的访问权限.

In this scenario you give your shared library an access to environment variables only.