Jenkinsfile声明性管道定义动态环境变量

时间:2017-05-09 20:57:07

标签: jenkins jenkins-pipeline

我是詹金斯管道的新手;我正在定义一个声明性语法管道,我不知道我是否可以解决我的问题,因为我找不到解决方案。

在这个例子中,我需要将一个变量传递给ansible插件(在旧版本中我使用ENV_VAR或从带有inject插件的文件中注入它)该变量来自脚本。

这是我的完美场景(但它不起作用,因为环境{}):

pipeline {
  agent { node { label 'jenkins-node'}}

  stages {
    stage('Deploy') {
      environment {
        ANSIBLE_CONFIG = '${WORKSPACE}/chimera-ci/ansible/ansible.cfg'
        VERSION = sh("python3.5 docker/get_version.py")
      }
      steps {
        ansiblePlaybook credentialsId: 'example-credential', extras: '-e version=${VERSION}', inventory: 'development', playbook: 'deploy.yml'
      }
    }
  }
}

我尝试了其他方法来测试env vars在其他帖子中的工作方式,例如:

pipeline {
  agent { node { label 'jenkins-node'}}

  stages {
    stage('PREPARE VARS') {
      steps {
        script {
          env['VERSION'] = sh(script: "python3.5 get_version.py")
        }
        echo env.VERSION
      }
    }
  }
}

但是“echo env.VERSION”返回null。

还尝试了同样的例子: - 版本= python3.5 get_version.py - VERSION = python3.5 get_version.py> props.file(并尝试注入它,但没有找到)

如果这是不可能的,我将以ansible角色进行。

更新

Ansible插件中还有另一个“问题”,要在额外的变量中使用变量,它必须有双引号而不是单引号。

ansiblePlaybook credentialsId: 'example-credential', extras: "-e version=${VERSION}", inventory: 'development', playbook: 'deploy.yml'

5 个答案:

答案 0 :(得分:74)

您可以在管道块启动之前创建变量。您可以让sh返回stdout来分配这些变量。您没有相同的灵活性来分配environment节中的环境变量。因此,在python3.5 get_version.py替换脚本中的echo 0.0.1(并确保您的python脚本只将版本返回到stdout):

def awesomeVersion = 'UNKNOWN'

pipeline {
  agent { label 'docker' }
  stages {
    stage('build') {
      steps {
        script {
          awesomeVersion = sh(returnStdout: true, script: 'echo 0.0.1')
        }
      }
    }
    stage('output_version') {
      steps {
        echo "awesomeVersion: ${awesomeVersion}"
      }
    }
  }
}

上述管道的输出是:

awesomeVersion: 0.0.1

答案 1 :(得分:17)

在Jenkins 2.76中,我能够将@burnettk的解决方案简化为:

pipeline {
  agent { label 'docker' }
  environment {
    awesomeVersion = sh(returnStdout: true, script: 'echo 0.0.1')
  }
  stages {
    stage('output_version') {
      steps {
        echo "awesomeVersion: ${awesomeVersion}"
      }
    }
  }
}

答案 2 :(得分:2)

使用“管道实用程序步骤”插件,可以从属性文件定义可用于所有阶段的常规变量。例如,将props.txt设置为:

version=1.0
fix=alfa

并将脚本和声明性Jenkins管道混合为:

def props
def VERSION
def FIX
def RELEASE

node {
   props = readProperties file:'props.txt'
   VERSION = props['version']
   FIX = props['fix']
   RELEASE = VERSION + "_" + FIX
}

pipeline {
   stages {
      stage('Build') {
         echo ${RELEASE}
      }
   }
}

答案 3 :(得分:0)

您也可以将所有变量转储到文件中,然后使用' -e @ file'句法。如果您要填充许多变量,这非常有用。

steps {
  echo "hello World!!"
  sh """
  var1: ${params.var1}
  var2: ${params.var2}
  " > vars
  """
  ansiblePlaybook inventory: _inventory, playbook: 'test-playbook.yml', sudoUser: null, extras: '-e @vars'
}

答案 4 :(得分:0)

主要答案的可能变体是使用另一个管道而不是sh脚本来提供变量。

示例(设置变量管道):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}]"
}

(使用这些变量)在另一个管道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 
    {
       // call set variable job
       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}"

}