Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
417 views
in Technique[技术] by (71.8m points)

bash - Jenkinsfile groovy, setting global variable that is only evaluated once, and creating another variable from first var

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?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...