I think this is a variable scoping question.
I have a Jenkins pipeline like this with a repeated switch-case statement. My real use-case has about 10 sites and a lot of different variables that are set, and several Jenkins jobs could use it, so I'd like to pull out that logic into a reusable function / class.
pipeline {
agent any
parameters {
choice (
name: 'SOURCE_ENV',
choices: [
'site_01'
'site_02'
],
description: 'The source environment you want to copy to another server.',
)
choice (
name: 'TARGET_ENV',
choices: [
'site_01'
'site_02'
],
description: 'The environment you want to refresh from another server.',
)
} // end params
stages {
stage('Initialization') {
steps {
script {
switch (SOURCE_ENV) {
case 'site_01':
def SOURCE_WEB_SERVER = 'site_01.someplace.org'
def SOURCE_DB_SERVER = 'site_01.db.someplace.org'
def SOURCE_DB_NAME = 'site_01_db'
def SOURCE_SITE_URL = 'https://some-spiffy-name.org'
break
case 'site_02':
def SOURCE_WEB_SERVER = 'site_02.someplace.org'
def SOURCE_DB_SERVER = 'site_02.db.someplace.org'
def SOURCE_DB_NAME = 'site_02_db'
def SOURCE_SITE_URL = 'https://some-different-name.org'
break
default:
error("ERROR: Unknown environment ${SOURCE_ENV}.")
break
}
switch (TARGET_ENV) {
case 'site_01':
def TARGET_WEB_SERVER = 'site_01.someplace.org'
def TARGET_DB_SERVER = 'site_01.db.someplace.org'
def TARGET_DB_NAME = 'site_01_db'
def TARGET_SITE_URL = 'https://some-spiffy-name.org'
break
case 'site_02':
def TARGET_WEB_SERVER = 'site_02.someplace.org'
def TARGET_DB_SERVER = 'site_02.db.someplace.org'
def TARGET_DB_NAME = 'site_02_db'
def TARGET_SITE_URL = 'https://some-different-name.org'
break
default:
error("ERROR: Unknown environment ${TARGET_ENV}.")
break
}
} // end script
} // end steps
} // end stage
stage('Do the Thing') {
steps {
script {
echo "Do the thing we want to do."
}
} // end steps
} // end stage
} // end stages
} // end pipeline
I have moved the logic into a new file and it loads, but it errors and doesn't work how I wanted.
Excerpt from the Jenkinsfile:
...
stage('Initialization') {
steps {
script {
def source = load 'website_environment_ops/setEnvironments.groovy'
source.setEnvironments(params.SOURCE_ENV)
def target = load 'website_environment_ops/setEnvironments.groovy'
target.setEnvironments(params.TARGET_ENV)
echo "SOURCE WEB_SERVER: ${source.WEB_SERVER}\n"
echo "TARGET WEB_SERVER: ${target.WEB_SERVER}\n"
} // end script
} // end steps
} // end stage
...
The setEnvironments.groovy file.
def setEnvironments(ENV) {
switch (ENV) {
case 'site_01':
def WEB_SERVER = 'site_01.someplace.org'
def DB_SERVER = 'site_01.db.someplace.org'
def DB_NAME = 'site_01_db'
def SITE_URL = 'https://some-spiffy-name.org'
break
case 'site_02':
def WEB_SERVER = 'site_02.someplace.org'
def DB_SERVER = 'site_02.db.someplace.org'
def DB_NAME = 'site_02_db'
def SITE_URL = 'https://some-different-name.org'
break
default:
error("ERROR: Unknown environment.")
break
}
}
return this
I am getting errors like this: 'Script1.groovy: 50: The current scope already contains a variable of the name WEB_SERVER'
I understand this is because my variables are not actually scoped into 'source' and 'target' as I would have hoped, and are being loaded into the same scope.
However, I don't know how to get variables of the same name scoped to different entities that can be used within one Jenkinsfile. Or, I don't know how to dynamically name these variables. Or, I don't know how to use a solution like setEnvironments.groovy file to reduce duplication in my code.
I'd like to be able to call variables like source.WEB_SERVER vs target.WEB_SERVER, or use setEnvironments.groovy to name its variables dynamically like SOURCE_WEB_SERVER vs TARGET_WEB_SERVER.
Does anyone have any ideas? Thx