Jenkinsfile中直接定义的变量在阶段脚本参数中无法被解析的问题
解决Jenkins Pipeline中顶层变量无法在声明式阶段解析的问题
这个问题我之前也碰到过,核心是Jenkins Pipeline的作用域隔离搞的鬼!你在Jenkinsfile顶部定义的变量属于脚本式Pipeline的顶层作用域,但声明式Pipeline的pipeline { ... }块是一个独立的闭包,默认不会自动继承顶层的变量,所以在里面的bat命令里就无法解析这些变量了。而之前用params.xxx能正常工作,是因为params是Jenkins提供的全局内置对象,在任何作用域都能直接访问。
下面给你两种靠谱的解决方案,你可以根据自己的需求选:
方案一:用@Field注解让顶层变量全局可访问
Groovy的@Field注解可以把顶层变量提升为类级别的字段,这样声明式Pipeline的闭包就能访问到这些变量了。你只需要在变量定义前加上注解即可:
import groovy.transform.Field @Field def env = "T" @Field def layer = "SS" @Field def bank_param = "333,332,333,334" @Field def banks = bank_param.split(',') @Field def saspath = "C:\\Progra~1\\SAS94\\SASFoundation\\9.4\\sas.exe" @Field def nunitpath = "bin\\nbi\\nunit\\bin\\nunit-console.exe" @Field def sasnbit = "src\\macros\\CREATE_NBITS_BANKNR_ENV.sas" @Field def lognbit = "log\\nbi\\BUILD_NBI_TEST.log"
修改后,你原来的声明式Pipeline代码不需要改动,bat命令就能正常解析这些变量了。
方案二:把变量移到声明式的environment块中
如果更符合你的使用习惯,也可以把变量放到声明式Pipeline的environment块里,这样变量会被注册为Jenkins的环境变量,在整个Pipeline的任何阶段都能通过env.变量名访问。这种方式也更符合声明式Pipeline的最佳实践:
pipeline { agent { label 'Deploymentserver' } environment { // 用大写命名是Jenkins环境变量的惯例,避免和全局env对象冲突 ENV = "T" LAYER = "SS" BANK_PARAM = "333,332,333,334" SASPATH = "C:\\Progra~1\\SAS94\\SASFoundation\\9.4\\sas.exe" NUNITPATH = "bin\\nbi\\nunit\\bin\\nunit-console.exe" SASNBIT = "src\\macros\\CREATE_NBITS_BANKNR_ENV.sas" LOGNBIT = "log\\nbi\\BUILD_NBI_TEST.log" } stages { stage("test parametre"){ steps{ script{ echo "This is bank_param: ${env.BANK_PARAM}" echo "This is saspath: ${env.SASPATH}" echo "This is samlet: ${env.SASPATH} -sysin ${env.SASNBIT} -set env ${env.ENV} -set layer ${env.LAYER} -set banks \"${env.BANK_PARAM}\" -log ${env.LOGNBIT}" } } } stage("Build test"){ steps{ script{ bat(script: "${env.SASPATH} -sysin ${env.SASNBIT} -set env ${env.ENV} -set layer ${env.LAYER} -set banks \"${env.BANK_PARAM}\" -log ${env.LOGNBIT}", returnStatus: true, returnStdout: true) findText regexp: '^(ERROR:)(?!.*(?i)page)', fileSet:'log/nbi/*.log' , alsoCheckConsoleOutput: true , unstableIfFound: true } } } } }
额外小技巧:局限变量到单个阶段
如果这些变量只在Build test阶段用到,也可以直接把变量定义放到该阶段的script块里,这样作用域就局限在这个阶段内,同样能正常使用:
stage("Build test"){ steps{ script{ def env = "T" def layer = "SS" def bank_param = "333,332,333,334" def saspath = "C:\\Progra~1\\SAS94\\SASFoundation\\9.4\\sas.exe" def sasnbit = "src\\macros\\CREATE_NBITS_BANKNR_ENV.sas" def lognbit = "log\\nbi\\BUILD_NBI_TEST.log" bat(script: "${saspath} -sysin ${sasnbit} -set env ${env} -set layer ${layer} -set banks \"${bank_param}\" -log ${lognbit}", returnStatus: true, returnStdout: true) findText regexp: '^(ERROR:)(?!.*(?i)page)', fileSet:'log/nbi/*.log' , alsoCheckConsoleOutput: true , unstableIfFound: true } } }
内容的提问来源于stack exchange,提问作者havmaage
相关产品推荐
相关产品推荐

