系列目錄html
有的童鞋可能已經發現,PipeLine項目與自由式項目相比,可配置的項少了不少,好比說環境變量定義,全部步驟完成後執行動做,拉git代碼庫等.其實這些功能並無缺,而是配置的方式不同了,之前是經過圖形化界面配置,雖然直觀簡便,可是功能不能包羅萬像,對於一些複雜的項目顯得捉襟見肘,而Jenkins PipeLine使用代碼配置功能更增強大.之後的章節中咱們會介紹經常使用的配置如何經過PipeLine裏的Groovy腳原本實現.node
前面講參數化構建的時候已經講到對於複雜的構建把一些重複的,經常使用的代碼作成變量的重要性,這裏講解如何經過PipeLine方式定義項目級別的參數以及環境變量.git
首先須要說明的是,節點級別和全局級別以及文件參數變量的配置在PipeLine裏依然有效,讀取的方式也同樣,只是會有一些小坑,這裏也會介紹程序員
PipeLine中能夠定義變量和環境變量,下面分別介紹如何定義變量和環境變動.sql
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
上面定義變量的方式是定義了一個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裏能夠書寫Groovy腳本,腳本若是出錯則代碼將不會再繼續往下走,咱們如何保證不論如何最終都會執行某一步動做呢,好比說釋放非託管資源,腳本出錯時發出郵件通知等,這裏其實處理辦法很是簡單,那就是使用groovy的try finally語法,把最終要執行的代碼寫在finally裏,這對程序員來講應該很是容易理解.
咱們前面已經說過,能夠在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並行執行了a
和b
兩個任務.這樣將極大節約代碼拉取時間.
咱們保存項目後點擊構建,構建完成後打開BlueOcean
視圖,點擊進入本次構建,就會看到以下圖
能夠從圖形界面形象地看到poll source
步驟分爲a和b
兩個並行的任務.而後它們聚集到下一步.
使用並行任務時必定要梳理好構建的邏輯,不然將會出現意想不到的結果.若是以上
a b 和build
並行執行,則將會致使構建失敗,由於構建依賴於以上兩個步驟都執行完成.