Jenkinsfile参数化构建中的环境和参数之间有什么关系?

Dan*_*ham 8 groovy jenkins jenkins-pipeline

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

if(!deploy_environments.contains(env.ENVIRONMENT_NAME.trim()) || params.INVOKE_PARAMETERS ) {
Run Code Online (Sandbox Code Playgroud)

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

java.lang.NullPointerException: Cannot invoke method trim() on null object
Run Code Online (Sandbox Code Playgroud)

该版本作为另一个版本的子代执行。该ENVIRONMENT_NAME参数从该父代构建传递到子代。

在其他詹金斯大师身上,他根本没有看到这个错误。当我从改变高于参考env.ENVIRONMENT_NAMEparams.ENVIRONMENT_NAME这个问题就走了。

params == env在Jenkins文档中找不到任何参考,因此我创建了一个构建以尝试阐明它们之间的关系。

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"'                  
             }
           }
       }
    }
}
Run Code Online (Sandbox Code Playgroud)

我第一次跑这对我的詹金斯高手,只包括前四行(echo env.ENVecho param.PARAMecho env.PARAMecho param.ENV)它成功与下面的输出:

[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
Run Code Online (Sandbox Code Playgroud)

我想:“啊哈!” 问题解决了。他们不一样。

但是,此框此后立即冻结了我,并拒绝再排队。我还没有完成调试,但是并没有奇怪要问那个大师是否被搞砸了。

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

[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
Run Code Online (Sandbox Code Playgroud)

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

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

[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
Run Code Online (Sandbox Code Playgroud)

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

诚然,没有以前的那个构建表现env.PARAMnull已经真正成功在干净的环境(即成功的一次是在一个环境中迅速崩盘对我算账)。因此,如果Jenkins管道中存在错误,是否会使将参数加载到环境中或其他东西短路?我尝试添加echo "$I_SHOULD_FAIL"到脚本中以强制错误,以重现我所看到的内容。没有骰子:

[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
Run Code Online (Sandbox Code Playgroud)

那么这是怎么回事?Jenkins管道之间environment和之间有什么关系parameters?这种关系应该是什么,为什么它看起来不一致?

Vit*_*nko 12

基本上如下

  • env包含所有环境变量
  • Jenkins管道会为每个环境变量自动创建一个全局变量
  • params 包含所有构建参数
  • Jenkins还会自动为每个构建参数创建一个环境变量(由于第二点而导致一个全局变量)。

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

  • 当您运行没有参数的作业时,“ parameters {}”会为该作业设置新参数,但*不会*为该参数创建变量。仅当您第二次运行作业并为其设置一些值时,才会创建参数变量。 (3认同)