【问题标题】:How to use Jenkins Pipeline global variable on another stages?如何在其他阶段使用 Jenkins Pipeline 全局变量?
【发布时间】:2020-01-25 16:38:53
【问题描述】:

我在 Jenkins 管道中定义了全局变量

def BUILDNRO = '0'
pipeline { ...

然后我使用 shell 脚本操作变量,通过使用作业构建号作为标识符来启用并行运行构建,这样我们就不会混合不同的 docker swarm。

    stage('Handle BUILD_NUMBER') {
        steps {
            script {
            BUILDNRO = sh( script: '''#!/bin/bash
            Build=`echo ${BUILD_NUMBER} | grep -o '..$'`
            # Check if BUILD first character is 0
            if [[ $Build:0:1 == "0" ]]; then
                # replace BUILD first character from 0 to 5
                Build=`echo $Build | sed s/./5/1`
            fi
            echo $Build
            ''',returnStdout: true).trim()
            }
        }
    }

我从前一个阶段获取价值并尝试在下一阶段获取全局变量

    stage('DOCKER: Init docker swarm') {
        steps {
            echo "BUILDNRO is: ${BUILDNRO}"  --> Value is here.
            sh '''#!/bin/bash
            echo Buildnro is: ${BUILDNRO}   --> This is empty.
            ...
        }
    }

这将使全局变量为空。为什么?在之前的阶段,它是有价值的。

编辑 1. 修改代码块以反映当前状态。

【问题讨论】:

    标签: jenkins jenkins-pipeline sh jenkins-groovy


    【解决方案1】:

    我设法弄明白了。这是我如何做到的解决方案。 BUILDNRO 是 groovy 变量,如果想在 bash 变量中使用它必须使用 withEnv 传递。第一阶段的BUILD_NUMBER是bash变量,因此可以在第一阶段直接使用脚本。

    def BUILDNRO = '0'
    
    pipeline {
      ....
      stages {
        stage('Handle BUILD_NUMBER') {
          steps {
            script {
              BUILDNRO = sh( script: '''#!/bin/bash
              Build=`echo ${BUILD_NUMBER} | grep -o '..$'`
              ''',returnStdout: true).trim()
            }
          }
        }
        stage('DOCKER: Init docker swarm') {
          steps {
            dir("prose_env/prose_api_dev_env") {
              withEnv(["MYNRO=${BUILDNRO}"]) {
                sh(returnStdout: false, script: '''#!/bin/bash
                echo Buildnro is: ${MYNRO}`
                '''.stripIndent())
              }
            }
          }     
        }
      }
    }
    

    【讨论】:

      【解决方案2】:

      如果您在 shell 模块中使用单引号(```),Jenkins 会将每个变量都视为 bash 变量。解决方案是使用双引号(“”“),但是如果你制作了 bash 变量,你必须转义它。下面是一个使用你的用例和转义 bash 变量的示例

      pipeline {
          agent any
          stages {
              stage('Handle BUILD_NUMBER') {
                  steps {
                      script {
                          BUILDNRO = sh(script: 'pwd', returnStdout: true).trim()
                          echo "BUILDNRO is: ${BUILDNRO}"
                      }
                  }
              }
              stage('DOCKER: Init docker swarm') {
                  steps {
                      sh """#!/bin/bash
                  echo Buildnro is: ${BUILDNRO}
                  variable=world
                  echo "hello \${variable}"
                  sh """
                  }
              }
      
          }
      }
      

      第二阶段的输出:

      Buildnro is: /var/lib/jenkins/workspace/stack1
      hello world
      

      【讨论】:

      • 只是好奇 ${BUILD_NUMBER} 是用于“处理 BUILD_NUMBER”阶段的环境变量。 BUILDNRO 是未在 sh 脚本中导入的全局变量。值是从脚本返回给它的,还是因为它是在外部定义的,但它在脚本 { } 部分下使用。
      • 双引号(""") 的问题是它比字符串操作等更难。
      • ${BUILD_NUMBER} 是一个 bash 变量。您可以在此处检查 Jenkins 提供的所有 bash 变量:url-to-your-jenkinsl/env-vars.html/ 或在 Jenkins 的 shell 脚本中传递“env”。
      • 究竟哪个更难?如果您的意思是转义 bash 变量-是的,有时可能会出现问题。尝试使用 groovy,这对 Jenkins 来说是最自然的。
      • 好的。现在这就解释了为什么接受 ${BUILD_NUMBER}。我站得更正了。不转义 bash 变量,而是执行 shell 脚本。在进行 shell 脚本字符串操作时使用单引号(''')与双引号(“”“)更容易。我在使用双引号时遇到了很多麻烦。
      猜你喜欢
      • 2019-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-19
      • 1970-01-01
      • 1970-01-01
      • 2012-08-25
      相关资源
      最近更新 更多