如何在声明性Jenkins管道中的阶段之间传递变量?

Joh*_*ohn 62 jenkins jenkins-pipeline

如何在声明性管道中的阶段之间传递变量?

在脚本管道中,我收集的程序是写入临时文件,然后将文件读入变量.

我如何在声明性管道中执行此操作?

例如,我想基于shell动作创建的变量触发不同作业的构建.

stage("stage 1") {
    steps {
        sh "do_something > var.txt"
        // I want to get var.txt into VAR
    }
}
stage("stage 2") {
    steps {
        build job: "job2", parameters[string(name: "var", value: "${VAR})]
    }
}
Run Code Online (Sandbox Code Playgroud)

bur*_*ttk 71

如果你想使用一个文件(因为脚本是生成你需要的值的东西):

// Define a groovy global variable, myVar.
// A local, def myVar = 'initial_value', didn't work for me.
// Your mileage may vary.
// Defining the variable here maybe adds a bit of clarity,
// showing that it is intended to be used across multiple stages.
myVar = 'initial_value'

pipeline {
  agent { label 'docker' }
  stages {
    stage('one') {
      steps {
        echo "${myVar}" // prints 'initial_value'
        sh 'echo hotness > myfile.txt'
        script {
          // OPTION 1: set variable by reading from file.
          // FYI, trim removes leading and trailing whitespace from the string
          myVar = readFile('myfile.txt').trim()

          // OPTION 2: set variable by grabbing output from script
          myVar = sh(script: 'echo hotness', returnStdout: true).trim()
        }
        echo "${myVar}" // prints 'hotness'
      }
    }
    stage('two') {
      steps {
        echo "${myVar}" // prints 'hotness'
      }
    }
    // this stage is skipped due to the when expression, so nothing is printed
    stage('three') {
      when {
        expression { myVar != 'hotness' }
      }
      steps {
        echo "three: ${myVar}"
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 你是对的@Dirkos但是有一种更好的方法来实现所请求的而不涉及文件读/写.请参阅此答案/sf/answers/3071721201/ (4认同)
  • 不写文件非常邪恶,并创建不需要的磁盘? (3认同)
  • 如果您想将配置放在文件的顶部,您也可以只使用 `def myVar` 并在之后使用它与 `echo ${myVar}` 一起使用 ;) (2认同)
  • 嗨伙计!如果您在阶段中定义代理,如果您在阶段之间切换机器,那么这不起作用...其他想法是隐藏 - 但您需要为此修改现有文件... (2认同)

小智 12

只是:

  pipeline {
        parameters {
            string(name: 'custom_var', defaultValue: '')
        }

        stage("make param global") {
             steps {
               tmp_param =  sh (script: 'most amazing shell command', returnStdout: true).trim()
               env.custom_var = tmp_param
              }
        }
        stage("test if param was saved") {
            steps {
              echo "${env.custom_var}"
            }
        }
  }
Run Code Online (Sandbox Code Playgroud)

  • 不确定这将如何运作。我认为您不能在不使用“脚本”步骤的情况下直接在“步骤”块内设置变量。 (5认同)
  • 我错了。parameters {}用于所提供的已使用参数,并且似乎是不可变的,尝试在管道中进行设置(除了在parameter {}中为它们分配默认值)将使该阶段失败而没有任何错误消息。因此,env.custom_var是必经之路。在这种情况下,可以忽略parameter {}块。 (3认同)
  • 文档在这里:https://jenkins.io/doc/book/pipeline/syntax/#parameters (2认同)
  • 根据 @KatieS 指向的文档,参数 {} 块中定义的参数将作为 ${params.custom_var} 而不是 ${env.custom_var} 进行访问。两者都可以工作,但它们是不同的变量,可以包含不同的值。但是您使用参数{}块的解决方案对于我通过 ${params.custom_var} 访问它们来说效果很好 (2认同)

Ian*_*ter 8

不需要(隐藏插件)参数定义或临时文件访问。跨阶段共享变量可以通过在 Jenkinsfile 中使用全局 Groovy 变量来完成,如下所示:

#!/usr/bin/env groovy 
def MYVAR

def outputOf(cmd) { return sh(returnStdout:true,script:cmd).trim(); }

pipeline {
    agent any    
    stage("stage 1") {
        steps {
            MYVAR = outputOf('echo do_something')
            sh "echo MYVAR has been set to: '${MYVAR}'"
        }
    }
    stage("stage 2") {
        steps {
            sh '''echo "...in multiline quotes: "''' + MYVAR + '''" ... '''
            build job: "job2", parameters[string(name: "var", value: MYVAR)]
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 7

我有一个类似的问题,因为我想要一个特定的管道来提供变量,而许多其他管道使用它来获取这个变量。

我创建了一个 my-set-env-variables 管道

script
{
    env.my_dev_version = "0.0.4-SNAPSHOT"
    env.my_qa_version  = "0.0.4-SNAPSHOT"
    env.my_pp_version  = "0.0.2"
    env.my_prd_version = "0.0.2"
    echo " My versions  [DEV:${env.my_dev_version}] [QA:${env.my_qa_version}] [PP:${env.my_pp_version}] [PRD:${env.my_prd_version}]"
}
Run Code Online (Sandbox Code Playgroud)

我可以在另一个管道中重用这些变量 my-set-env-variables-test

script 
{
    env.dev_version = "NOT DEFINED DEV"
    env.qa_version  = "NOT DEFINED QA"
    env.pp_version  = "NOT DEFINED PP"
    env.prd_version = "NOT DEFINED PRD"
}

stage('inject variables') {

    echo "PRE DEV version = ${env.dev_version}"
    script 
    {
       def variables = build job: 'my-set-env-variables'
       def vars = variables.getBuildVariables()
      //println "found variables" + vars
      env.dev_version = vars.my_dev_version
      env.qa_version  = vars.my_qa_version
      env.pp_version  = vars.my_pp_version
      env.prd_version = vars.my_prd_version
    }
}

stage('next job') {
    echo "NEXT JOB DEV version = ${env.dev_version}"
    echo "NEXT JOB QA version = ${env.qa_version}"
    echo "NEXT JOB PP version = ${env.pp_version}"
    echo "NEXT JOB PRD version = ${env.prd_version}"

}


Run Code Online (Sandbox Code Playgroud)