Jenkinsfile参数化构建中的环境和参数之间有什么关系? [英] What is the relationship between Environment and Parameters in Jenkinsfile Parameterized Builds?

查看:763
本文介绍了Jenkinsfile参数化构建中的环境和参数之间有什么关系?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近在与同事一起进行某些Jenkins构建工作时遇到了一个令人困惑的问题.他一直在可互换地使用params.VARIABLEenv.VARIABLE,并且没有任何问题.同时,我通过以下代码行通过环境调用他的参数对象之一,开始得到空对象错误:

I recently ran into something of a puzzler while working on some Jenkins builds with a coworker. He's been using params.VARIABLE and env.VARIABLE interchangably and having no issues with it. Meanwhile, I started getting null object errors on one of his calls to a parameter object through the environment on this line of code:

if(!deploy_environments.contains(env.ENVIRONMENT_NAME.trim()) || params.INVOKE_PARAMETERS ) {

ENVIRONMENT_NAME这是一个参数.我开始收到此错误:

ENVIRONMENT_NAME here is a parameter. I started getting this error:

java.lang.NullPointerException: Cannot invoke method trim() on null object

此版本正在作为另一个版本的子代执行. ENVIRONMENT_NAME参数从该父版本向下传递给该孩子.

This build is executing as a child of another build. The ENVIRONMENT_NAME parameter is passed down to the child from that parent build.

在其他詹金斯大师身上,他根本没有看到这个错误.当我将上面的引用从env.ENVIRONMENT_NAME更改为params.ENVIRONMENT_NAME时,问题就消失了.

He was not seeing this error at all on a different Jenkins master. When I changed the reference above from env.ENVIRONMENT_NAME to params.ENVIRONMENT_NAME the issue went away.

在Jenkins文档中找不到对params == env的引用,因此我创建了一个构建以试图阐明它们之间的关系.

I could find no reference to params == env in the Jenkins documentation, so I created a build to try to clarify their relationship.

pipeline {
    agent {
        label 'jenkins-ecs-slave'
    }
    environment {
        ENV_VARIABLE = 'Environment'
    }
    parameters {
        string(description: 'Parameter', name: 'PARAMETER_VARIABLE', defaultValue: 'Parameter')

    }
    stages {
       stage('Output Parameters'){
          steps {
             script {
                 echo "Environment: ${env.ENV_VARIABLE}"
                 echo "Parameter: ${params.PARAMETER_VARIABLE}"
                 echo "Environment from params: ${params.ENV_VARIABLE}"
                 echo "Parameter from Env: ${env.PARAMETER_VARIABLE}"
                 echo "Inspecific reference ENV_VARIABLE: $ENV_VARIABLE"
                 echo "Inspecific reference PARAMETER_VARIABLE: $PARAMETER_VARIABLE"
                 sh 'echo "Shell environment: $ENV_VARIABLE"'
                 sh 'echo "Shell parameter: $PARAMETER_VARIABLE"'                  
             }
           }
       }
    }
}

我第一次在Jenkins主机上运行此命令时,它仅包含前四行(echo env.ENVecho param.PARAMecho env.PARAMecho param.ENV),并成功显示以下输出:

The first time I ran this on my Jenkins master, it only included the first four lines (echo env.ENV, echo param.PARAM, echo env.PARAM, echo param.ENV) it succeeded with the following output:

[Pipeline] {
[Pipeline] withEnv
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Output Parameters)
[Pipeline] script
[Pipeline] {
[Pipeline] echo
Environment: Environment
[Pipeline] echo
Parameter: Parameter
[Pipeline] echo
Environment from params: null
[Pipeline] echo
Parameter from Env: null
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS

我想,啊哈!问题解决了.他们不一样.

And I thought, "Aha!" Problem solved. They're not the same.

但是,此框此后立即冻结了我,并拒绝再排队.我还没有完成调试,但是想知道该主机是否被搞砸了,并不是没有道理的.

However, that box promptly froze up on me afterwards and refused to queue anymore builds. I haven't finished debugging it, but it's not out of line to wonder if that master is just messed up.

因此,我去了第三名詹金斯大师,我们一直在这里闲逛.此时,我添加了您在上面脚本中看到的其他行,以进一步阐明.我第一次在该框上运行此脚本时,它在对$ PARAMETER_VARIABLE行的特定引用"上失败,并显示以下输出:

So I went and ran it on a third Jenkins master we have hanging around. It's at this point I added the additional lines you see in the script above to further clarify. The first time I ran this script on that box, it failed on the "Inspecific reference to $PARAMETER_VARIABLE line" with the following output:

[Pipeline] {
[Pipeline] withEnv
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Output Parameters)
[Pipeline] script
[Pipeline] {
[Pipeline] echo
Environment: Environment
[Pipeline] echo
Parameter: Parameter
[Pipeline] echo
Environment from params: null
[Pipeline] echo
Parameter from Env: null
[Pipeline] echo
Inspecific reference ENV_VARIABLE: Environment
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
groovy.lang.MissingPropertyException: No such property: PARAMETER_VARIABLE for class: groovy.lang.Binding

好的,到目前为止,一切都很好.这是有道理的.他们不一样.您可以在回显和外壳程序中引用环境变量,而无需专门引用环境对象,但不能对参数进行相同的操作.一致,合理,我对此很满意.

Okay, so far so good. This makes sense. They aren't the same. You can reference Environment variables in echos and shells with out specifically referencing the environment object, but can't do the same with parameters. Consistent, reasonable, I'm good with this.

因此,我删除了执行特定参考"的两行,脚本成功输出以下内容:

So then I removed the two lines doing the "inspecific reference" and the script succeeded with the following output:

[Pipeline] {
[Pipeline] withEnv
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Output Parameters)
[Pipeline] script
[Pipeline] {
[Pipeline] echo
Environment: Environment
[Pipeline] echo
Parameter: Parameter
[Pipeline] echo
Environment from params: null
[Pipeline] echo
Parameter from Env: Parameter
[Pipeline] sh
[Environment Testing] Running shell script
+ echo 'Shell environment: Environment'
Shell environment: Environment
[Pipeline] sh
[Environment Testing] Running shell script
+ echo 'Shell parameter: Parameter'
Shell parameter: Parameter
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS

现在我完全感到困惑了.我勒个去?为了确定起见,我运行了几次,并且始终如一地获得了与上述相同的成功输出.

And now I'm completely confuddled. What the hell? I ran it a couple of times just to be sure, and got the same successful output as above, consistently.

当然,以前的任何版本都没有显示env.PARAMnull在清洁的环境中真正成功(成功的环境是在随后迅速向我崩溃的环境中).那么,如果Jenkins管道中存在错误,是否会使将参数加载到环境中或其他东西短路?我尝试将echo "$I_SHOULD_FAIL"添加到脚本中以强制错误,以重现我看到的内容.没有骰子:

Granted, none of the previous builds that showed env.PARAM as null had really succeeded in a clean environment (the one that succeeded was in an environment the promptly imploded on me afterwards). So maybe if there's an error in the Jenkins pipeline, it short circuits the loading of parameters into the environment or something? I tried adding echo "$I_SHOULD_FAIL" to the script to force an error in an attempt to reproduce what was I seeing. No dice:

[Pipeline] {
[Pipeline] withEnv
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Output Parameters)
[Pipeline] script
[Pipeline] {
[Pipeline] echo
Environment: Environment
[Pipeline] echo
Parameter: Parameter
[Pipeline] echo
Environment from params: null
[Pipeline] echo
Parameter from Env: Parameter
[Pipeline] sh
[Environment Testing] Running shell script
+ echo 'Shell environment: Environment'
Shell environment: Environment
[Pipeline] sh
[Environment Testing] Running shell script
+ echo 'Shell parameter: Parameter'
Shell parameter: Parameter
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
groovy.lang.MissingPropertyException: No such property: I_SHOULD_FAIL for class: groovy.lang.Binding

那么这是怎么回事? Jenkins管道中的environmentparameters之间是什么关系?这种关系应该是什么?为什么它看起来不一致?

So what's going on here? What's the relationship between environment and parameters in Jenkins pipelines? What is that relationship supposed to be and why does it seem to be inconsistent?

推荐答案

基本上,其工作原理如下

Basically this works as follows

  • env 包含所有 params 包含所有构建参数
  • Jenkins还会自动为每个构建参数创建一个环境变量(并且由于第二点而导致一个全局变量).
  • env contains all environment variables
  • Jenkins pipeline automatically creates a global variable for each environment variable
  • params contains all build parameters
  • Jenkins also automatically creates an environment variable for each build parameter (and as a consequence of second point a global variable).

环境变量可以被覆盖或未设置,但是params是不变的Map,不能更改.最佳做法是在需要获取构建参数时始终使用params.

Environment variables can be overridden or unset but params is an immutable Map and cannot be changed. Best practice is to always use params when you need to get a build parameter.

这篇关于Jenkinsfile参数化构建中的环境和参数之间有什么关系?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆