【问题标题】:Jenkinsfile groovy, setting global variable that is only evaluated once, and creating another variable from first varJenkinsfile groovy,设置仅评估一次的全局变量,并从第一个 var 创建另一个变量
【发布时间】:2021-01-07 15:22:39
【问题描述】:

我有这个代码:

#!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"
              }
            }
        }
    }
}

我想要的输出是,每次我调用/创建一个新变量时,值都是一样的:

[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

在詹金斯中发生的事情是这样的:

[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

每次我基于SUPER_VAR 创建一个var 时,似乎脚本再次运行,我得到不同的输出。

如何将脚本的输出注册到全局变量中,以便以后可以用于全局创建新变量?

【问题讨论】:

  • 全局初始化变量是默认行为。在 environment 指令中移动初始化是使它们成为 env 映射中的键值对的原因。删除environment 指令并将变量放在管道中,您应该一切顺利。
  • ????我有很多阶段,@MattSchuchard 当您说“在管道中放置变量”时,您是指在每个阶段定义变量吗?

标签: bash jenkins groovy jenkins-pipeline


【解决方案1】:

这是我正在使用的解决方案,我必须在每个阶段定义 vars,它看起来很脏,但它有效。

这样,初始值SUPER_VAR只会被计算一次,随后我们可以使用这些变量的子元素。

我的用例,我不想使用更多的 jenkins 插件来获取 aws sts 假设。 SUPER_VAR 调用 sts 假设并返回凭据,我对它运行 jq,并获取在 SUPER_VAR 中注册的字典。

在每个阶段,我都会运行 jq 来提取 aws 的凭据,以便 sts 假设可以工作。

#!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"
              }
            }
        }
    }
}

【讨论】:

    【解决方案2】:

    我没有更好的解决方案,只能使用单例。

    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"
                  }
                }
            }
        }
    }
    

    我重写了您的脚本以在 Windows Jenkins 上使用它,但对于 Linux,这是相同的想法。 您只需将Math.random() 替换为sh(returnStdout: true, script: """openssl rand -base64 12""").trim()

    Singleton.GetRandomValue() 的第一次调用将初始化该值,随后对Singleton.GetRandomValue() 的任何调用都不会调用随机例程,而是返回现有值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-14
      相关资源
      最近更新 更多