如何在Jenkins声明式流水线阶段锁中使用运行时环境变量
Jenkins声明式流水线锁使用运行时环境变量的问题解决
问题场景
配置Jenkins声明式流水线的阶段锁时,希望使用前置阶段设置的运行时环境变量作为锁资源名称,但直接使用${env.MYVAR}时,锁名称显示为null。
原始测试流水线代码
import hudson.console.* pipeline { agent none stages { stage('Init') { stages{ stage('init_1') { steps { script { env.MYVAR = "value" } } } stage('init_2') { steps { print("${env.MYVAR}") } // other init stuff } } } stage('run') { agent any options { lock resource: "${env.MYVAR}" } stages { stage('actually do stuff') { steps { print("${env.MYVAR}") } } } } } }
执行输出日志
10:30:47 [Pipeline] Start of Pipeline 10:30:47 [Pipeline] stage 10:30:47 [Pipeline] { (Init) 10:30:47 [Pipeline] stage 10:30:47 [Pipeline] { (init_1) 10:30:47 [Pipeline] script 10:30:47 [Pipeline] { 10:30:47 [Pipeline] } 10:30:47 [Pipeline] // script 10:30:47 [Pipeline] } 10:30:47 [Pipeline] // stage 10:30:47 [Pipeline] stage 10:30:47 [Pipeline] { (init_2) 10:30:47 [Pipeline] echo 10:30:47 value 10:30:47 [Pipeline] } 10:30:47 [Pipeline] // stage 10:30:47 [Pipeline] } 10:30:47 [Pipeline] // stage 10:30:47 [Pipeline] stage 10:30:47 [Pipeline] { (run) 10:30:47 [Pipeline] lock 10:30:47 Trying to acquire lock on [null] 10:30:47 Resource [null] did not exist. Created. 10:30:47 Lock acquired on [null] 10:30:47 [Pipeline] { 10:30:48 [Pipeline] node 10:30:48 Running on Jenkins in /var/jenkins_home/workspace/Pipeline for tests 10:30:48 [Pipeline] { 10:30:48 [Pipeline] stage 10:30:48 [Pipeline] { (actually do stuff) 10:30:48 [Pipeline] echo 10:30:48 value 10:30:48 [Pipeline] } 10:30:48 [Pipeline] // stage 10:30:48 [Pipeline] } 10:30:48 [Pipeline] // node 10:30:48 [Pipeline] } 10:30:48 Lock released on resource [null] 10:30:48 [Pipeline] // lock 10:30:48 [Pipeline] } 10:30:48 [Pipeline] // stage 10:30:48 [Pipeline] End of Pipeline 10:30:48 Finished: SUCCESS
问题原因
声明式流水线的options块属于流水线的初始化配置阶段,会在流水线开始执行任何阶段前就被解析。而原始代码中env.MYVAR是在Init阶段内设置的,此时options块已经完成解析,所以无法获取到该变量值,导致锁名称为null。
解决方案
将环境变量的初始化逻辑移到pipeline块外部的node中执行,这样变量会在流水线解析前就被设置到全局环境里,后续options块就能正确读取到变量值。
修改后的适配代码
import hudson.console.* node { stage('init_1') { script { env.MYVAR = "value" } } } pipeline { agent none stages { stage('Init') { stages{ stage('init_2') { steps { print("${env.MYVAR}") } // other init stuff } } } stage('run') { agent any options { lock(resource: "${env.MYVAR}") } stages { stage('actually do stuff') { steps { print("${env.MYVAR}") } } } } } }
内容的提问来源于stack exchange,提问作者Coco
相关产品推荐
相关产品推荐

