10分鐘搞定讓你困惑的 Jenkins 環境變量

前言

Jenkins, DevOps 技術棧的核心之一,CI/CD 離不開編寫 Pipeline 腳本,上手 Jenkins ,簡單查一下文檔,你就應該不會被 agent,stages,step 這類關鍵詞弄懵,也能很快構建出 pipeline 的骨架html

可是當向骨架中填充內容的時候,尤爲如何利用環境變量(系統內置 | 自定義),多數人都會變得比較混亂,浪費不少時間,本文就幫助你們快速通關環境變量docker

準備

若是你想一邊閱讀本文,一邊實踐,可是沒有 Jenkins 服務可用,又想快速嘗試,能夠應用 Docker 一個命令快速搭建 Jenkins 服務shell

docker container run --rm -p 8080:8080 -p 50000:50000 --name=jenkins -v $(pwd):/var/jenkins_home jenkins/jenkins

2021 年了,本地沒有 Docker 說不過去了,過來瞧瞧 Docker 系列是否入得了你的法眼?

打開瀏覽器輸入:localhost:8080編程

  1. 找到終端的臨時密碼登錄
  2. 安裝推薦的依賴
  3. 建立新的 Pipeline 類型的 Item
  4. 點擊左側 Config,而後在頁面底部 Pipeline 部分輸入咱們接下來寫的腳本進行測試就行了

就是這麼簡單.....瀏覽器

認識 Jenkins 環境變量

Jenkins 環境變量就是經過 env 關鍵字暴露出來的 全局變量,能夠在 Jenkins 文件的 任何位置使用

其實和你使用的編程語言中的全局變量沒有實質差異編程語言

查看 Jenkins 系統內置環境變量

Jenkins 在系統內置了不少環境變量方便咱們快速使用,查看起來有兩種方式:ide

方式一:

直接在瀏覽器中訪問 ${YOUR_JENKINS_HOST}/env-vars.html 頁面就能夠,好比 http://localhost:8080/env-vars.html ,每一個變量的用途寫的都很清楚函數

方式二

經過執行 printenv shell 命令來獲取:測試

pipeline {
    agent any

    stages {
        stage("Env Variables") {
            steps {
                sh "printenv"
            }
        }
    }
}

直接 Save - Build, 在終端 log 中你會看到相應的環境變量,而且能夠快速看到他們當前的值ui

一般這兩種方式能夠結合使用

讀取環境變量

上面咱們說了 env 是環境變量的關鍵字,可是讀取 Jenkins 內置的這些環境變量,env 關鍵字是無關緊要, 但不能沒了底褲,都要使用 ${xxx} 包圍起來。以 BUILD_NUMBER 這個內置環境變量舉例來講明就是這樣滴:

若是你在 Jenkins 文件中使用 shell 命令,使用這些內置環境變量甚至能夠不用 {}, 來看一下:

pipeline {
    agent any

    stages {
        stage("Read Env Variables") {
            steps {
                echo "帶 env 的讀取方式:${env.BUILD_NUMBER}"
                echo "不帶 env 的讀取方式:${BUILD_NUMBER}"
                sh 'echo "shell 中讀取方式 $BUILD_NUMBER"'
            }
        }
    }
}

能夠看到結果是同樣同樣滴,無論有幾種,記住第一種最穩妥

內置的環境變量雖好,但也不能徹底知足咱們自定義的 pipeline 的執行邏輯,因此咱們也得知道如何定義以及使用自定義環境變量

自定義 Jenkins 環境變量

Jenkins pipeline 分聲明式(Declarative)和 腳本式(imperative)寫法,相應的環境變量定義方式也略有不一樣,概括起來有三種方式:

仍是看個實際例子吧:

pipeline {
    agent any

    environment {
        FOO = "bar"
    }

    stages {
        stage("Custom Env Variables") {
            environment {
                NAME = "RGYB"
            }

            steps {
                echo "FOO = ${env.FOO}"
                echo "NAME = ${env.NAME}"

                script {
                    env.SCRIPT_VARIABLE = "Thumb Up"
                }

                echo "SCRIPT_VARIABLE = ${env.SCRIPT_VARIABLE}"

                withEnv(["WITH_ENV_VAR=Come On"]) {
                    echo "WITH_ENV_VAR = ${env.WITH_ENV_VAR}"
                }
            }
        }
    }
}

來看運行結果:

注意: withEnv(["WITH_ENV_VAR=Come On"]) {} 這裏的 = 號兩側不能有空格,必須是 key=value 的形式

一個完整的 pipeline 一般會有不少個 stage,環境變量在不一樣的 stage 有不一樣的值是很常見的,知道如何設置以及讀取環境變量後,咱們還得知道如何重寫環境變量

重寫 Jenkins 環境變量

Jenkins 讓人相對困惑最多的地方就是重寫環境變量,可是隻要記住下面這三條規則,就能夠搞定一切了

  1. withEnv(["WITH_ENV_VAR=Come On"]) {} 內置函數的這種寫法,能夠重寫任意環境變量
  2. 定義在 environment {} 的環境變量不能被腳本式定義的環境變量(env.key="value")重寫
  3. 腳本式環境變量只能重寫腳本式環境變量

這三點是硬規則,沒涵蓋在這 3 點規則以內的也就是被容許的了

三條規則就有點讓人頭大了,農夫選豆種,舉例爲證吧

pipeline {
    agent any

    environment {
        FOO = "你當像鳥飛往你的山"
        NAME = "Tan"
    }

    stages {
        stage("Env Variables") {
            environment {
                  // 會重寫第 6 行 變量
                NAME = "RGYB" 
                  // 會重寫系統內置的環境變量 BUILD_NUMBER
                BUILD_NUMBER = "10" 
            }

            steps {
                  // 應該打印出 "FOO = 你當像鳥飛往你的山"
                echo "FOO = ${env.FOO}" 
                  // 應該打印出 "NAME = RGYB"
                echo "NAME = ${env.NAME}" 
                  // 應該打印出 "BUILD_NUMBER = 10"
                echo "BUILD_NUMBER =  ${env.BUILD_NUMBER}" 

                script {
                      // 腳本式建立一個環境變量
                    env.SCRIPT_VARIABLE = "1" 
                }
            }
        }

        stage("Override Variables") {
            steps {
                script {
                      // 這裏的 FOO 不會被重寫,違背 Rule No.2
                    env.FOO = "Tara"
                      // SCRIPT_VARIABLE 變量會被重寫,符合 Rule No.3
                    env.SCRIPT_VARIABLE = "2" 
                }

                  // FOO 在第 37 行重寫失敗,還會打印出 "FOO = 你當像鳥飛往你的山"
                echo "FOO = ${env.FOO}" 
                  // 會打印出 "SCRIPT_VARIABLE = 2"
                echo "SCRIPT_VARIABLE = ${env.SCRIPT_VARIABLE}" 

                  // FOO 會被重寫,符合 Rule No.1
                withEnv(["FOO=Educated"]) { 
                      // 應該打印 "FOO = Educated"
                    echo "FOO = ${env.FOO}" 
                }

                  // 道理同上
                withEnv(["BUILD_NUMBER=15"]) {
                      // 應該打印出 "BUILD_NUMBER = 15"
                    echo "BUILD_NUMBER = ${env.BUILD_NUMBER}"
                }
            }
        }
    }
}

來驗證一下結果吧

看到這,基本的設置應該就沒有什麼問題了,相信你也發現了,Jenkins 設置環境變量和編程語言的那種設置環境變量仍是略有不一樣的,後者能夠將變量賦值爲對象,但 Jenkins 就不行,由於在 Jenkins 文件中,全部設置的值都會被當成 String, 難道沒辦法應用 Boolean 值嗎?

Jenkins 中使用 Boolean 值

若是設置一個變量爲 false ,Jenkins 就會將其轉換爲 "false", 若是想使用 Boolean 來作條件判斷,必需要調用 toBoolean() 方法作轉換

pipeline {
    agent any

    environment {
        IS_BOOLEAN = false
    }

    stages {
        stage("Env Variables") {
            steps {
                script {
                      // Hello 會被打印出來,由於非空字符串都會被認爲是 Boolean.True
                    if (env.IS_BOOLEAN) {
                        echo "Hello"
                    }

                      // 真正的 Boolean 比較
                    if (env.IS_BOOLEAN.toBoolean() == false) {
                        echo "日拱一兵"
                    }
                  
                      // 真正的 Boolean 
                    if (!env.IS_BOOLEAN.toBoolean()) {
                        echo "RGYB"
                    }
                }
            }
        }
    }
}

來看運行結果:

若是你寫過 Pipeline,你必定會知道,寫 Pipeline 是離不開寫 shell 的,有些時候,須要將 shell 的執行結果賦值給環境變量,Jenkins 也有方法支持

Shell 結果賦值給環境變量

實現這種方式很簡單,只須要記住一個格式:sh(script: 'cmd', returnStdout:true)

pipeline {
    agent any

    environment {
          // 使用 trim() 去掉結果中的空格
        LS_RESULT = "${sh(script:'ls -lah', returnStdout: true).trim()}"
    }

    stages {
        stage("Env Variables") {
            steps {
                echo "LS_RESULT = ${env.LS_RESULT}"
            }
        }
    }
}

總結

關於 Jenkins 環境變量,瞭解這些基本上就知足絕大多數應用場景了,當再遇到環境變量問題時,能夠回過來翻看一下了,有解決的困惑嗎?

相關文章
相關標籤/搜索