在 Jenkins Pipeline 中使用全局变量
Posted
技术标签:
【中文标题】在 Jenkins Pipeline 中使用全局变量【英文标题】:Using global variables in Jenkins Pipeline 【发布时间】:2019-02-03 10:35:14 【问题描述】:我尝试了各种方法,但似乎没有任何效果。这是我的詹金斯文件。
def ZIP_NODE
def CODE_VERSION
pipeline
/*A declarative pipeline*/
agent
/*Agent section*/
// where would you like to run the code
label 'ubuntu'
options
timestamps()
parameters
choice(choices: ['dev'], description: 'Name of the environment', name: 'ENV')
choice(choices: ['us-east-1', 'us-west-1','us-west-2','us-east-2','ap-south-1'], description: 'What AWS region?', name: 'AWS_DEFAULT_REGION')
string(defaultValue: "", description: '', name: 'APP_VERSION')
stages
/*stages section*/
stage('Initialize the variables')
// Each stage is made up of steps
steps
script
CODE_VERSION='$BUILD_NUMBER-$ENV'
ZIP_NODE='abcdefgh-0.0.$CODE_VERSION.zip'
stage ('code - Checkout')
steps
checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'xxxxxxxxxxxxxxxxxxxxxxxxxx', url: 'http://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.git']]])
stage ('code - Build')
steps
sh '''
echo $JOB_NAME
pwd
echo $ZIP_NODE
echo 'remove alraedy existing zip files'
rm -rf *.zip
zip -r $ZIP_NODE .
chmod 777 $ZIP_NODE
'''
stage('Deploy on Beanstalk')
steps
build job: 'abcdefgh-PHASER' , parameters: [[$class: 'StringParameterValue', name: 'vpc', value: ENV], [$class: 'StringParameterValue', name: 'ZIP_NODE', value: ZIP_NODE], [$class: 'StringParameterValue', name: 'CODE_VERSION', value: CODE_VERSION], [$class: 'StringParameterValue', name: 'APP_VERSION', value: BUILD_NUMBER], [$class: 'StringParameterValue', name: 'AWS_DEFAULT_REGION', value: AWS_DEFAULT_REGION], [$class: 'StringParameterValue', name: 'ParentJobName', value: JOB_NAME]]
阶段中步骤脚本的输出('初始化变量')什么也没给我,它没有设置全局变量 ZIP_NODE 的值:
[Pipeline] stage
[Pipeline] (Initialize the variables)
[Pipeline] script
[Pipeline]
[Pipeline]
[Pipeline] // script
[Pipeline]
[Pipeline] // stage
然后我们进入阶段(代码 - 构建)我们没有得到 ZIP_NODE 的值。请参阅 22:34:17 的 echo 声明
[Pipeline] stage
[Pipeline] (code - Build)
[Pipeline] sh
22:34:16 [abcdefgh-ci-dev-pipeline] Running shell script
22:34:17 + echo abcdefgh-ci-dev-pipeline
22:34:17 abcdefgh-ci-dev-pipeline
22:34:17 + pwd
22:34:17 /home/advisor/Jenkins/workspace/abcdefgh-ci-dev-pipeline
22:34:17 + echo
22:34:17
22:34:17 + echo remove alraedy existing zip files
感谢@awefsome,我有一些观察,我想补充一下细节: 当我使用下面的代码时,我得到了所需的输出,即 ZIP_NODE 的正确值:
stage ('code - Build')
steps
sh "echo $JOB_NAME && pwd && echo $ZIP_NODE && echo 'remove alraedy existing zip files' && rm -rf *.zip && zip -r $ZIP_NODE . && chmod 777 $ZIP_NODE"
但是当我使用下面的代码时,我没有得到 ZIP_NODE 的值:
stage ('code - Build')
steps
sh '''
echo $ZIP_NODE
echo $JOB_NAME
pwd
echo $ZIP_NODE
echo $CODE_VERSION
#rm -rf .ebextensions
echo 'remove alraedy existing zip files'
rm -rf *.zip
zip -r $ZIP_NODE .
chmod 777 $ZIP_NODE
'''
【问题讨论】:
【参考方案1】:sh '''
'''
应该是
sh """
"""
带有单引号的变量不会被处理。
【讨论】:
参考:Groovy Syntax, String interpolation.【参考方案2】:试试看,看看效果如何:
def ZIP_NODE
def CODE_VERSION
pipeline
/*A declarative pipeline*/
agent
/*Agent section*/
// where would you like to run the code
label 'master'
options
timestamps()
parameters
choice(choices: ['dev'], description: 'Name of the environment', name: 'ENV')
choice(choices: ['us-east-1', 'us-west-1','us-west-2','us-east-2','ap-south-1'], description: 'What AWS region?', name: 'AWS_DEFAULT_REGION')
string(defaultValue: "", description: '', name: 'APP_VERSION')
stages
/*stages section*/
stage('Initialize the variables')
// Each stage is made up of steps
steps
script
CODE_VERSION="$BUILD_NUMBER-$ENV"
ZIP_NODE="abcdefgh-0.0.$CODE_VERSION.zip"
stage ('code - Checkout')
steps
println "checkout skipped"
//checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'xxxxxxxxxxxxxxxxxxxxxxxxxx', url: 'http://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.git']]])
stage ('code - Build')
steps
sh "echo $JOB_NAME && pwd && echo $ZIP_NODE && echo 'remove alraedy existing zip files' && rm -rf *.zip && zip -r $ZIP_NODE . && chmod 777 $ZIP_NODE"
stage('Deploy on Beanstalk')
steps
println "build job skipped"
//build job: 'abcdefgh-PHASER' , parameters: [[$class: 'StringParameterValue', name: 'vpc', value: ENV], [$class: 'StringParameterValue', name: 'ZIP_NODE', value: ZIP_NODE], [$class: 'StringParameterValue', name: 'CODE_VERSION', value: CODE_VERSION], [$class: 'StringParameterValue', name: 'APP_VERSION', value: BUILD_NUMBER], [$class: 'StringParameterValue', name: 'AWS_DEFAULT_REGION', value: AWS_DEFAULT_REGION], [$class: 'StringParameterValue', name: 'ParentJobName', value: JOB_NAME]]
我得到以下输出:
Started by user jenkins
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] node
Running on Jenkins in /Users/Shared/Jenkins/Home/workspace/test
[Pipeline]
[Pipeline] timestamps
[Pipeline]
[Pipeline] stage
[Pipeline] (Initialize the variables)
[Pipeline] script
[Pipeline]
[Pipeline]
[Pipeline] // script
[Pipeline]
[Pipeline] // stage
[Pipeline] stage
[Pipeline] (code - Checkout)
[Pipeline] echo
21:19:06 checkout skipped
[Pipeline]
[Pipeline] // stage
[Pipeline] stage
[Pipeline] (code - Build)
[Pipeline] sh
21:19:06 [test] Running shell script
21:19:06 + echo test
21:19:06 test
21:19:06 + pwd
21:19:06 /Users/Shared/Jenkins/Home/workspace/test
21:19:06 + echo abcdefgh-0.0.17-dev.zip
21:19:06 abcdefgh-0.0.17-dev.zip
21:19:06 + echo 'remove alraedy existing zip files'
21:19:06 remove alraedy existing zip files
21:19:06 + rm -rf '*.zip'
21:19:06 + zip -r abcdefgh-0.0.17-dev.zip .
21:19:06
21:19:06 zip error: Nothing to do! (try: zip -r abcdefgh-0.0.17-dev.zip . -i .)
[Pipeline]
[Pipeline] // stage
【讨论】:
同样的问题仍然存在 我已经编辑了我的答案以适应输出。它似乎至少在我的最后工作。您能否详细说明一下,按照答案中的建议进行更改后,您得到了什么确切的错误。 以下代码有效:stage ('code - Build') steps sh "echo $JOB_NAME && pwd && echo $ZIP_NODE && echo 'remove alraedy existing zip files' && rm - rf *.zip && zip -r $ZIP_NODE . && chmod 777 $ZIP_NODE" 但这不会暂存 ('code - Build') steps sh ''' echo $ZIP_NODE ''' 对我来说,它只有在我定义没有“def”且没有类型说明的全局变量时才有效。 是否可以使用相同的模式,但是使用 powershell 内联脚本而不是 sh inline?【参考方案3】:jenkins 上的全局环境应该在管道之外,可以在脚本内部初始化/使用,当然管道内的所有范围都知道:
示例:
def internal_ip
pipeline
agent node label "test"
stages
stage('init')
steps
script
def x
if(env.onHold.toBoolean() == true)
x=1
else
x=2
internal_ip = sh (
script: "echo 192.168.0.$x",
returnStdout: true
).trim()
stage('test')
steps
script
echo "my internal ip is: $internal_ip"
【讨论】:
【参考方案4】:除了@avivamg 的answer 是正确的。
剩下的一个问题是,如果你想访问 Jenkins 的环境变量(参见 http://<JENKINS_URL>/env-vars.html/
)来初始化这些全局变量,例如:
def workspaceDir=$WORKSPACE
你得到:
groovy.lang.MissingPropertyException: No such property: WORKSPACE for class: groovy.lang.Binding
的想法:
def workspaceDir
pipeline
environment
workspaceDir=$WORKSPACE
stages
stage('Globals test')
steps
script
echo "workspaceDir=$workspaceDir"
echo workspaceDir
导致输出:
workspaceDir=null
null
因为涉及到两个不同的上下文:environment 和 Groovy,它们显然是相互独立的。
它适用于:
environment
workspaceDir=$WORKSPACE
但那是一个环境变量,而不是 Groovy 上下文中的变量。
在 Groovy 上下文中声明和初始化是通过阶段进行的:
def workspaceDir
pipeline
stages
stage('Initializing globals')
steps
script
workspaceDir = "$WORKSPACE"
stage('Globals test')
steps
script
echo "workspaceDir=$workspaceDir"
echo workspaceDir
输出:
workspaceDir=C:\Users\jenkins\AppData\Local\Jenkins\.jenkins\workspace\Globals-test-project
C:\Users\jenkins\AppData\Local\Jenkins\.jenkins\workspace\Globals-test-project
【讨论】:
这是因为环境变量在环境范围内声明时是不可变的。当在脚本范围内声明时,它们是完全可变的。不过,无论哪种情况,它们都只能是字符串。我的首选资源是e.printstacktrace.blog/…【参考方案5】:我在 groovy shellscript 中使用全局变量的经验是将它们声明为全局变量,然后使用阶段环境变量。看起来 shell 脚本只能访问这个私有环境变量,而不能访问全局。作为样本:
environment
COMMIT_ID = "foo"
stages
stage('Build')
environment
commitId = sh(returnStdout: true, script: 'git rev-parse HEAD').trim()
steps
script
COMMIT_ID = commitId
stage ('Build-Win-Container')
environment
commitId = "$COMMIT_ID"
steps
sh label: 'build/push container', script: '''
echo "With Windows commitId: $commitId"
'''
我也从 *** 尝试了十几种方法,但没有一种方法可以访问 shell 脚本中的变量。我认为这是因为 shell 脚本是一个步骤中的私有实例,并且只能访问此步骤中的变量(我的观点) 所以我设置了一个全局环境变量 在步骤 1 中填写此脚本 在下一步中设置环境变量并在那里填充。 最后,它在 shell 脚本中可用。没有其他方法对我有用。
【讨论】:
''' ... "... $commit"'''
不会插入到 triple-single-quoted string 中。你必须使用triple-double-quoted string。以上是关于在 Jenkins Pipeline 中使用全局变量的主要内容,如果未能解决你的问题,请参考以下文章
Jenkins 2 Pipeline 中的声纳 - 缺少全局配置
jenkins集群使用k8s部署,pipeline中文乱码的问题解决记录
jenkins pipeline之流水线脚本版本化学习二(简化版)