Reputation: 148
I have this code:
#!groovy
pipeline {
agent any
environment {
def SUPER_VAR = sh(returnStdout: true, script: """openssl rand -base64 12""").trim()
SUPER_VALUE = sh(returnStdout: true, script: """echo ${SUPER_VAR}""").trim()
SUPER_DUPER_VALUE = sh(returnStdout: true, script: """echo ${SUPER_VAR}""").trim()
}
stages {
stage("initialise") {
steps {
script {
sh "echo SUPER_VAR \${SUB_VAR}"
sh "echo SUPER_VALUE \${SUPER_VALUE}"
sh "echo SUPER_DUPER_VALUE \${SUPER_DUPER_VALUE}"
sh "env"
}
}
}
}
}
My desired output is, where each time I call / create a new var, the value is the same:
[Pipeline] { (initialise)
[Pipeline] script
[Pipeline] {
[Pipeline] sh
+ echo SUPER_VAR
SUPER_VAR
[Pipeline] sh
+ echo SUPER_VALUE FSDYe8VNL3VTvASj
SUPER_VALUE FSDYe8VNL3VTvASj
[Pipeline] sh
+ echo SUPER_DUPER_VALUE FSDYe8VNL3VTvASj
SUPER_DUPER_VALUE FSDYe8VNL3VTvASj
[Pipeline] sh
What happens in jenkins is this:
[Pipeline] { (initialise)
[Pipeline] script
[Pipeline] {
[Pipeline] sh
+ echo SUPER_VAR
SUPER_VAR
[Pipeline] sh
+ echo SUPER_VALUE FSDYe8VNL3VTvASj
SUPER_VALUE FSDYe8VNL3VTvASj
[Pipeline] sh
+ echo SUPER_DUPER_VALUE NSmVwW9xz6IPG5AO
SUPER_DUPER_VALUE NSmVwW9xz6IPG5AO
[Pipeline] sh
Every time I created a var
based on SUPER_VAR
it seems the script is ran again, and I get different output.
How does one register output of script in to a global var, so it can later be used to create new vars globally?
Upvotes: 1
Views: 711
Reputation: 484
I cannot come with a better solution, but to use a singleton.
class Singleton {
def static Value = 0
def static GetRandomValue() {
if(!Value)
Value = Math.random()
Value
}
}
println Singleton.GetRandomValue()
println Singleton.GetRandomValue()
pipeline {
agent any
environment {
SUPER_VAL1 = Singleton.GetRandomValue()
SUPER_VAL2 = "$SUPER_VAL1"
SUPER_VAL3 = "$SUPER_VAL2"
}
stages {
stage("initialise") {
steps {
script {
bat "set SUPER"
}
}
}
}
}
I rewrote your script to use it on a Windows Jenkins, but for Linux it is the same idea.
You need just to replace Math.random()
with sh(returnStdout: true, script: """openssl rand -base64 12""").trim()
.
First call to Singleton.GetRandomValue()
will initialize the value and any subsequent call to Singleton.GetRandomValue()
will not call the random routine, but return the existing value.
Upvotes: 1
Reputation: 148
This is what I am using as a solution, I have to define vars in each stage, it looks dirty, but it works.
This way, the initial value SUPER_VAR
will only be evaluated once, and subsequently we can use sub-elements of these vars.
My use case, I do not want to use more jenkins plugins to get aws sts assume.
SUPER_VAR
calls sts assume, and returns credentials, I run jq against it, and get a dictionary registered in SUPER_VAR
.
In every stage I run jq to extract credentials for aws for sts assume to work.
#!groovy
pipeline {
agent any
environment {
def SUPER_VAR = sh(returnStdout: true, script: """openssl rand -base64 12""").trim()
}
stages {
stage("initialise") {
environment {
SUPER_VALUE = sh(returnStdout: true, script: """echo ${SUPER_VAR}""").trim()
SUPER_DUPER_VALUE = sh(returnStdout: true, script: """echo ${SUPER_VAR}""").trim()
}
steps {
script {
sh "echo SUPER_VAR \${SUB_VAR}"
sh "echo SUPER_VALUE \${SUPER_VALUE}"
sh "echo SUPER_DUPER_VALUE \${SUPER_DUPER_VALUE}"
sh "env"
}
}
}
stage("go again") {
environment {
SUPER_VALUE = sh(returnStdout: true, script: """echo ${SUPER_VAR}""").trim()
SUPER_DUPER_VALUE = sh(returnStdout: true, script: """echo ${SUPER_VAR}""").trim()
}
steps {
script {
sh "echo SUPER_VAR \${SUB_VAR}"
sh "echo SUPER_VALUE \${SUPER_VALUE}"
sh "echo SUPER_DUPER_VALUE \${SUPER_DUPER_VALUE}"
sh "env"
}
}
}
}
}
Upvotes: 1