Keywords: Jenkins Pipeline | Global Variables | String Interpolation
Abstract: This article delves into the definition, scope, and string interpolation issues of global variables in Jenkins pipelines. By analyzing a common case of unresolved variables, it explains the critical differences between single and double quotes in Groovy scripts and provides solutions based on best practices. With code examples, it demonstrates how to effectively manage global variables in declarative pipelines, ensuring data transfer across stages and script execution consistency, helping developers avoid common pitfalls and optimize pipeline design.
Introduction
In Jenkins pipeline development, the use of global variables is fundamental for building complex automation workflows. However, many developers often encounter issues where variables are not correctly resolved when passed across stages, typically due to misunderstandings of string interpolation mechanisms in Groovy. This article analyzes the proper usage of global variables in Jenkins pipelines through a specific case study and explores the impact of quote selection on variable resolution.
Problem Background and Case Analysis
Consider the following Jenkinsfile example, which defines two global variables ZIP_NODE and CODE_VERSION, with assignments in the Initialize the variables stage:
def ZIP_NODE
def CODE_VERSION
pipeline{
agent { label 'ubuntu' }
stages{
stage('Initialize the variables') {
steps{
script{
CODE_VERSION='${BUILD_NUMBER}-${ENV}'
ZIP_NODE='abcdefgh-0.0.${CODE_VERSION}.zip'
}
}
}
stage ('code - Build'){
steps{
sh '''
echo ${ZIP_NODE}
echo ${JOB_NAME}
pwd
echo ${ZIP_NODE}
echo ${CODE_VERSION}
echo 'remove alraedy existing zip files'
rm -rf *.zip
zip -r ${ZIP_NODE} .
chmod 777 $ZIP_NODE
'''
}
}
}
}During execution, the shell script output in the code - Build stage shows the ZIP_NODE variable as empty, causing subsequent commands to fail. A log snippet is as follows:
[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 filesThe root cause is the use of single quotes ''' in the sh step, which prevents Groovy variable interpolation. In Groovy, single-quoted strings are treated as literals with no variable substitution, while double-quoted strings support interpolation, replacing ${variable} with the actual value.
Solution and Best Practices
Based on the best answer (Answer 2), the correction involves changing single quotes to double quotes to ensure variables are resolved before shell command execution:
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"
}
}Additionally, in the variable initialization stage, double quotes should be used to ensure environment variables like BUILD_NUMBER and ENV are interpolated:
stage('Initialize the variables') {
steps{
script{
CODE_VERSION="${BUILD_NUMBER}-${ENV}"
ZIP_NODE="abcdefgh-0.0.${CODE_VERSION}.zip"
}
}
}The corrected pipeline output shows variables are properly resolved:
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 filesIn-Depth Analysis: Global Variable Scope and String Handling
In Jenkins declarative pipelines, variables defined with def have script scope and can be accessed in any stage within the pipeline block. However, value transfer relies on correct string interpolation mechanisms. The following code demonstrates the pattern of defining and using global variables:
def internal_ip
pipeline {
agent { node { label "test" } }
stages {
stage('init') {
steps {
script {
internal_ip = sh (
script: "echo 192.168.0.${x}",
returnStdout: true
).trim()
}
}
}
stage('test') {
steps {
script {
echo "my internal ip is: ${internal_ip}"
}
}
}
}
}Key points include:
- Global variables should be defined with
defoutside thepipelineto ensure visibility across stages. - When referencing variables in strings, double quotes must be used to enable interpolation.
- In
shsteps, double-quoted strings allow Groovy to replace${variable}with values before passing to the shell for execution.
Common Pitfalls and Avoidance Methods
Common errors developers make include:
- Using single quotes in
shsteps, leading to unresolved variables. - Confusing Groovy variable interpolation with shell variable expansion (e.g.,
$ZIP_NODEworks in shell only if the variable value is correctly passed). - Not using double quotes in variable initialization stages, causing nested variables (e.g.,
BUILD_NUMBERinCODE_VERSION) to fail interpolation.
To avoid these issues, it is recommended to:
- Always use double-quoted strings when variable interpolation is needed.
- Use
scriptblocks to clarify variable assignment logic in complex scripts. - Validate variable values through log output, such as using
echo "ZIP_NODE: ${ZIP_NODE}"for debugging.
Conclusion
Effectively using global variables in Jenkins pipelines hinges on understanding Groovy's string interpolation mechanisms and scope rules. By replacing single quotes with double quotes, variables can be correctly resolved in sh steps and other string contexts. The case analysis and solutions in this article provide practical guidance for building more reliable and maintainable automation pipelines. Combining best practices, such as explicit variable definition and debug output, can significantly reduce common errors and enhance development efficiency.