Jenkins管道可选布尔参数

时间:2018-10-29 19:21:19

标签: jenkins jenkins-pipeline

我正在尝试使用具有默认布尔值的自定义函数,该布尔值可以被覆盖。问题是它不会覆盖默认值。所有迭代都匹配“ else”。

pipeline {

  agent {
    label 'any'
  }

  stages {
    stage('Foo') {
      steps {
        doThing('/opt/prod','athos',true)
        doThing('/opt/demo','aramis',true)
        doThing('/opt/test','porthos')
        doThing('/opt/dev','dartagnan')
      }
    }
  }
}

def doThing(def targetDir, def stackName, def prod=false) {
  if ( env.prod == true ) {
    sh """
      execute-bin \
        -Dbin.target=${targetDir} \
        -Dbin.stackName=${stackName} \
        -Dbin.prod=true
    """
  } else {
    sh """
      execute-bin \
        -Dbin.target=${targetDir} \
        -Dbin.stackName=${stackName}
    """
  }
}

3 个答案:

答案 0 :(得分:4)

您的if块env.prod中包含变量,并将true传递给prod 函数变量def prod ,这是不同的。 prod变量仅针对doThing函数范围定义,它不同于env.prod或仅在常规代码中可用的prod。如果您不更改env.prod,则它始终位于doThing()中。要么在代码中的某个地方(依赖关系或逻辑)更改其值,要么简单地尝试以下操作:

pipeline {

  agent {
    label 'any'
  }

  stages {
    stage('Foo') {
      steps {
        doThing('/opt/prod','athos',true)
        doThing('/opt/demo','aramis',true)
        doThing('/opt/test','porthos')
        doThing('/opt/dev','dartagnan')
      }
    }
  }
}

def doThing(def targetDir, def stackName, def prod=false) {
  if ( prod == true ) {
    sh """
      execute-bin \
        -Dbin.target=${targetDir} \
        -Dbin.stackName=${stackName} \
        -Dbin.prod=true
    """
  } else {
    sh """
      execute-bin \
        -Dbin.target=${targetDir} \
        -Dbin.stackName=${stackName}
    """
  }
}

编辑

我将尝试使其更加清晰。我知道您可以仅通过名称来引用环境变量:

  

可以从Groovy代码中以env.VARNAME的形式访问环境变量   或简称为VARNAME。 您也可以写入此类属性(仅   使用环境。前缀):

     

env.MYTOOL_VERSION ='1.33'节点{sh   '/ usr / local / mytool- $ MYTOOL_VERSION / bin / start'}

但是全局变量和函数范围内可访问的变量之间存在差异。如果您将赋值从doThing() prod变量添加到全局env.prod变量,则它也将起作用

def doThing(def targetDir, def stackName, def prod=false) {
  env.prod = prod
  if ( env.prod == true ) {
    sh """
      execute-bin \
        -Dbin.target=${targetDir} \
        -Dbin.stackName=${stackName} \
        -Dbin.prod=true
    """
  } else {
    sh """
      execute-bin \
        -Dbin.target=${targetDir} \
        -Dbin.stackName=${stackName}
    """
  }
}

答案 1 :(得分:2)

尝试与字符串值进行比较:

  if ( prod == 'true' ) 

之所以会发生这种情况,是因为环境变量始终是字符串,并且没有qoutes的true是布尔值,因此它永远不会相等:

考虑这一点:

def doThing(def prod=false) {
  if ( prod == true ) {
    println 'TRUE'   
  } else {
    println 'FALSE'
  }
}

// this is how environment are passed into the pipeline from jenkins UI
doThing('true')
> FALSE
doThing('false')
> FALSE

// if environment variables were boolean (and they are not) it would be ok
doThing(true)
> TRUE
doThing(false)
> FALSE

// the current equality check is always false
println true=='true'
> false
println true=='false'
> false

答案 2 :(得分:1)

作为@chenchuck答案的替代方法,您也可以使用params.prod,它实际上返回一个boolean,因此不需要字符串比较:

def doThing(def targetDir, def stackName, def prod=false) {
  if ( params.prod == true ) {
  ...

但是== true将过时。然后可以将其缩短为:

def doThing(def targetDir, def stackName, def prod=false) {
  if ( params.prod ) {
  ...

在Pipeline作业的信息中心的Pipeline Syntax->Global Variables Reference链接下进行了描述。向下滚动,直到找到params全局变量的描述(指向该链接的链接应为JENKINS_URL/job/globalSharedLib/pipeline-syntax/globals#params)。我从本地Jenkins实例复制的以下描述:

  参数      

将构建中定义的所有参数公开为带有以下内容的只读映射   各种类型的值。示例:

if (params.BOOLEAN_PARAM_NAME) {doSomething()}
     

或提供非平凡的默认值:

if (params.get('BOOLEAN_PARAM_NAME', true)) {doSomething()}
     

关于多分支(Jenkinsfile)使用的注意事项:属性步骤允许   您可以定义作业属性,但是当步骤为   运行,而通常参考构建参数定义   在构建开始之前。为了方便起见,目前所有参数   在作业中定义的具有默认值的内容也会列在   这张地图。这样您就可以编写,例如:

properties([parameters([string(name: 'BRANCH', defaultValue: 'master')])])
git url: '…', branch: params.BRANCH
     

,请确保即使在   分支项目的初始构建,或者如果先前的构建没有   指定参数或使用其他参数名称。