DevOps/System&Tools

variables in Jenkinsfile

Jacob_baek 2019. 11. 22. 17:32

Jenkins pipeline 작성시 로컬 및 전역변수 사용에 대한 내용에 대하여 기술하고자 한다.

Scripted pipeline

아래는 scripted 방식으로 pipeline 을 기술했을때의 전역변수와 로컬변수에 대한 사용법과 그에 대한 실행결과이다.

아래와 같이 l_val(local) / g_val(global)로 나누어 테스트를 수행하였었다.

node {
    g_val = null

    stage('test local variable') {
        echo "[local variable test]"
        def l_val = null
        $l_val = "local val"
        sh "echo '(sh)l_val : '$l_val"
        echo "(echo)l_val : " + $l_val

        echo "[global variable test #1]"
        $g_val = "global val"
        script {
            echo "(echo_script)g_val : " + $g_val
        }
        sh "echo '(sh)g_val : '$g_val"
        echo "(echo)g_val : " + $g_val

    }

    stage('test global variables') {
        echo "[global variable test #2]"
        $g_val = "global val2"
        sh "echo '(sh)g_val : '$g_val"
        echo "(echo)g_val : " + $g_val

        echo "[global variable test #3]"
        $g_val += "global val3"
        sh "echo '(sh)g_val : '$g_val"
        echo "(echo)g_val : " + $g_val
    }
}

아래는 결과이다.

[local variable test]
[Pipeline] sh
(sh)l_val : null
(echo)l_val : local val

[global variable test #1]
(echo_script)g_val : global val
(sh)g_val : null
(echo)g_val : global val

[global variable test #2]
(sh)g_val : null
(echo)g_val : global val2

[global variable test #3]
(sh)g_val : null
(echo)g_val : global val2global val3

해당 테스트를 수행했던 목적은 전역변수를 선언하고 서로 다른 stage에서 사용했던 결과를 공유하고자 함이었다.

안타깝게도 "test local variable" stage에서 선언했던 결과가 "test global variable" stage에서는 참조할 수 없었다.

즉, (sh)로 불러온 결과는 로컬 변수로 인지하고 전역변수를 참조하지 않아 (echo)와 (sh)로 출력했을때의 결과가 상이했다.

구글링을 통해 다른 방식을 찾아보니 아래 사이트에서 제안된 방식이 동작하는것을 확인되었다.

https://stackoverflow.com/questions/43879733/jenkinsfile-declarative-pipeline-defining-dynamic-env-vars

실제 Jenkinsfile 내용이다.

node {
  def g_val = null
  stage('first test') {
    script {
        g_val = sh(returnStdout: true, script: "echo 'global val'")
    }
    sh "echo $g_val"
  }
  stage('second test') {
    sh "echo $g_val"
  }
}

즉, script block을 추가하여 sh의 결과값을 대입한 결과 다른 stage에서도 해당 값을 참조할 수 있었다.

실제 결과 또한 아래와 같이 global variable를 사용하려는 목적에 부합한 결과가 출력되었다.

global val
global val

declarative pipeline 구성

def var1 = "init"

pipeline {
  agent { xxx }
  stages {
    stage('stage1') {
      steps {
        sh """echo ${var1}""" 
        script {
          var1 = sh(script: 'echo "abc"', returnStdout: true).trim()
        }
        sh 'echo ${var1}' // <== empty value로 출력
        sh """echo ${var1}""" // <== abc로 출력
      }
    }

    stage('stage2') {
      steps {
        sh """echo ${var1}""" // <== abc로 출력
      }
    }
}

참고사이트