我最近在与同事一起制作一些Jenkins构建时遇到了一些益智游戏。他一直在使用params.VARIABLE
和env.VARIABLE
,并且没有任何问题。同时,我开始通过这行代码中的环境调用参数对象的一个空对象错误:
if(!deploy_environments.contains(env.ENVIRONMENT_NAME.trim()) || params.INVOKE_PARAMETERS ) {
ENVIRONMENT_NAME
这是一个参数。我开始收到此错误:
java.lang.NullPointerException: Cannot invoke method trim() on null object
此构建作为另一个构建的子代执行。 ENVIRONMENT_NAME
参数从该父版本向下传递给子项。
他在一个不同的Jenkins大师身上根本没有看到这个错误。当我将上述参考从env.ENVIRONMENT_NAME
更改为params.ENVIRONMENT_NAME
时,问题就消失了。
我在Jenkins文档中找不到params == env
的引用,所以我创建了一个构建来试图澄清它们之间的关系。
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.ENV
,echo param.PARAM
,echo env.PARAM
,echo 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
我想,“啊哈!”问题解决了。他们不一样。
然而,那个盒子后来立即冻结了我,拒绝排队。我还没有完成它的调试,但是不知道那个主人是不是搞砸了。
所以我去了第三个Jenkins大师,我们一直闲逛。在这一点上,我添加了您在上面的脚本中看到的其他行,以进一步澄清。我第一次在那个盒子上运行这个脚本时,它在“Inspecific reference to $ PARAMETER_VARIABLE line”上输出失败,输出如下:
[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
好的,到目前为止一切顺利。这是有道理的。他们不一样。您可以在没有专门引用环境对象的情况下引用回声和shell中的环境变量,但不能对参数执行相同的操作。一致,合理,我很擅长这一点。
然后我删除了执行“inspecific reference”的两行,脚本成功完成了以下输出:
[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
现在我完全糊里糊涂了。我勒个去?为了确保我运行了几次,并且始终如一地获得了与上面相同的成功输出。
当然,以前没有显示env.PARAM
null
的构建在一个干净的环境中成功了(成功的那个环境在之后迅速崩溃的环境中)。那么也许如果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
那么这里发生了什么? Jenkins管道中environment
和parameters
之间的关系是什么?应该是什么关系,为什么它似乎不一致?
答案 0 :(得分:6)
基本上它的工作原理如下
env
包含所有environment variables params
包含所有构建参数可以覆盖或取消设置环境变量,但params
是不可变的Map,无法更改。最佳做法是在需要获取构建参数时始终使用params
。