持續集成高級篇之Jenkins參數傳入與常見任務

系列目錄html

有的童鞋可能已經發現,PipeLine項目與自由式項目相比,可配置的項少了不少,好比說環境變量定義,全部步驟完成後執行動做,拉git代碼庫等.其實這些功能並無缺,而是配置的方式不同了,之前是經過圖形化界面配置,雖然直觀簡便,可是功能不能包羅萬像,對於一些複雜的項目顯得捉襟見肘,而Jenkins PipeLine使用代碼配置功能更增強大.之後的章節中咱們會介紹經常使用的配置如何經過PipeLine裏的Groovy腳原本實現.node

前面講參數化構建的時候已經講到對於複雜的構建把一些重複的,經常使用的代碼作成變量的重要性,這裏講解如何經過PipeLine方式定義項目級別的參數以及環境變量.git

首先須要說明的是,節點級別和全局級別以及文件參數變量的配置在PipeLine裏依然有效,讀取的方式也同樣,只是會有一些小坑,這裏也會介紹程序員

PipeLine中能夠定義變量和環境變量,下面分別介紹如何定義變量和環境變動.sql

PipeLine中定義變量

PipeLine中定義變量很是簡單,只須要使用def 變量名=變量值的形式便可shell

看以下PipeLine代碼(你們本身建立項目)ui

node {
    def hello="world"
    stage("echo"){
        bat "echo $hello"
    }
}

以上腳本中咱們先是定義了一個名爲hello的變量,而後經過$變量名方式獲取到它,而後把它打印到控制檯.插件

有些童鞋對以上代碼可能有點懵圈,bat執行的字符串怎麼能包含$變量名這樣的內容呢,bat不是隻能解析%變量名%類型的變量嗎.其實是$變量名是groovy腳本插值語法,執行到這行文本的時候groovy就會去嘗試解析$變量名,對於本實例,groovy會解析$hello,上面已經定義過,它的值是world,所以 groovy會把 echo $hello先解析爲'echo world'這樣純字符串,而後再傳給bat執行.code

須要注意的是以上定義的變量並不是環境變量,對於bat腳本,不能經過%變量名%的形式被解析,由於環境變量中不存在這樣一個環境變量名,所以bat沒法解析它.固然對於定義的節點級別的或者全局的變量bat腳本仍然能夠經過%變量名%形式被解析.你們不要迷糊.sqlite

PipeLine中定義環境變量

上面定義變量的方式是定義了一個groovy變量,咱們也說過它不能被傳入到腳本內部被解析(好比bat 經過%變量名%形式解析),它必須經過groovy腳本解析成普通字符串而後傳給相應的腳本執行程序.實際上PipeLine中也提供了一種建立環境變量的方法.這裏咱們就介紹一下.

咱們仍是經過一段demo來說解

node {
    withEnv(['build=Production',
             'DB_ENGINE=sqlite']) {
        stage('Build') {
           bat "echo $build"
        }
    }
}

以上經過WithEnv來定義環境變量,值放在中括號裏,你們注意寫法是"變量名=變量值",也就是變量名和賦值都放在一個引號內(單引號和雙引號均可以),而不是"變量名"="變量值"這種形式,必定要注意.

bat命令裏的解析方法是經過$變量名形式,咱們講過,它是groovy的插件方式,經過這裏咱們能夠看到,在PipeLine裏,環境變量也被看成了普通變量(便可以經過$變量名形式解析).固然咱們說了這裏定義的是環境變量,環境變量是能夠傳入腳本內部被解析的,咱們把bat這段代碼改成以下

bat "echo %build%"

控制檯仍然可以輸出world.

對於powershell腳本能夠經過$env:變量名方式獲取.可是對於powershell腳本有一個坑必須注意,那就是Powershell獲取環境變量名使用$開頭,同時groovy腳本插值變量也是以$開頭,這就會致使Groovy會嘗試解析 powershell的變量,這樣顯然沒法獲取正確結果.如何解決這一問題呢?答案是執行powershell腳本的時候使用powershell '要執行的腳本',也即把雙引號改成單引號,若是雙引號改單引號,則groovy再也不進行插值計算.

最佳實踐

1) 前面說過,groovy除了能夠獲取經過def定義的變量外,也可以獲取環境變量,所以建議使用$變量名的方式獲取變量的值,這樣groovy會提交對它們進行插值計算,這樣就彌補了不一樣腳本使用環境變量方法不同的問題.同也沒必要考慮powrshell 引用變量會被插值計算,必須使用單引號包括腳本的問題,減小腦細胞消耗量.

2) 經過以上咱們能夠看到PipeLine裏便可以經過def來定義變量,也能夠經過WithEnv來定義,實際使用中發現WithEnv更麻煩,全部使用到它的代碼塊都必須包含在withEnv代碼塊內,若是嵌套過深,代碼可讀性很是差.而def便可以聲明爲全局的(這裏說的全局是對整個當前腳本有效),也能夠是塊級的,而且不用花括號,可讀性也更好.

常見任務在PipeLine中的處理

保證某一步驟最終必定執行

咱們知道PipeLine裏能夠書寫Groovy腳本,腳本若是出錯則代碼將不會再繼續往下走,咱們如何保證不論如何最終都會執行某一步動做呢,好比說釋放非託管資源,腳本出錯時發出郵件通知等,這裏其實處理辦法很是簡單,那就是使用groovy的try finally語法,把最終要執行的代碼寫在finally裏,這對程序員來講應該很是容易理解.

Script代碼塊

咱們前面已經說過,能夠在jenkins PipeLine裏直接執行groovy腳本,若是僅僅是定義一個變量這樣簡單的動做無所謂,若是有大量的代碼和業務邏輯摻雜在一塊,則勢必影響代碼可讀性.此時可使用script代碼塊把要執行的大段groovy腳本包在裏面

以下圖示

node {
     def hello="world"
    
    stage("echo"){
        
           script{
                for(i=0;i<=3;i++){
                println(i)
            }
           }
       
        bat "echo $version"
    }
   
}

以上咱們把循環語句放在代碼塊裏,println能夠把內容打印到Jenkins控制檯.

邏輯分支

這裏僅僅是列出來但願引發你們的注意,在腳本式PipeLine裏邏輯分支很是簡單,只須要使用if分支語句便可,熟悉groovy腳本的童鞋能夠盡情發揮所掌握知識

並行任務

在PipeLine裏能夠執行並行任務,充分利用並行任務在特定場景下將極大節約構建時間,提高構建效率.好比說咱們的項目是一個模塊很是多的項目,每一個模塊存在不一樣的倉庫裏,則咱們在拉取項目進行編譯的時候能夠並行拉取這個庫,把這些並行任務放在一個步驟裏,完成後再執行下一步編譯工做.

請看下面示例代碼

node{
    stage("poll source"){
        parallel(
      a: {
        echo "This is branch a"
         },
      b: {
        echo "This is branch b"
         }
            )
    }
   stage("build"){
       echo "build successfully"
   }
}

以上代碼在poll source步驟裏,咱們經過parallel並行執行了ab兩個任務.這樣將極大節約代碼拉取時間.

咱們保存項目後點擊構建,構建完成後打開BlueOcean視圖,點擊進入本次構建,就會看到以下圖

img

能夠從圖形界面形象地看到poll source步驟分爲a和b兩個並行的任務.而後它們聚集到下一步.

使用並行任務時必定要梳理好構建的邏輯,不然將會出現意想不到的結果.若是以上a b 和build並行執行,則將會致使構建失敗,由於構建依賴於以上兩個步驟都執行完成.

相關文章
相關標籤/搜索