Jenkins高階篇之Pipeline語法篇-9-多個stage的關係:順序和並行
在Declarative Pipeline模式的程式碼中,可能會在一個stages{…}中宣告一竄巢狀的stages{…}, 並以順序執行。需要指出的是,一個stage{…}必須有且只有一個steps{…}, 或者parallel{…} 或者stages{…}
看看下面這個順序巢狀例子程式碼
pipeline { agent none stages { stage('Non-Sequential Stage') { agent { label 'for-non-sequential' } steps { echo "On Non-Sequential Stage" } } stage('Sequential') { agent { label 'for-sequential' } environment { FOR_SEQUENTIAL = "some-value" } stages { stage('In Sequential 1') { steps { echo "In Sequential 1" } } stage('In Sequential 2') { steps { echo "In Sequential 2" } } } } } }
這個例子展示了巢狀,其實更好的順序執行stage的例子就是我們前面寫過的 Build Test Deploy這三個stage.
認真看,可以看到這些特點。
- 所有的stage,都會內嵌在最外層的stages{…}
- 一個stage{…}下可以內嵌有且只有一個stages{…}
- 多層巢狀只支援在最後一個stage{…}裡面
- 巢狀越多越複雜,最簡單就是觀察每一個stage的大括號的範圍
原則上,我們儘量少寫巢狀的stage{…},寫了巢狀就意味很難維護。但是有時候,由於業務邏輯需要,和stage{…}組織結構好看,我們會寫巢狀,巢狀裡面可能存在順序和平行的stage{…} 前面我們演示的demo都是順序,也就是一個接著一個執行,下面我們來看看並行的stage{…}
並行stage{…}需要用到指令paraller, 有一個paraller{…} 裡面包含多個stage{…},最後一個stage{…}內部支援巢狀多個stages{…}。在paraller{…}如果要設定只要裡面有一個stage{…}執行失敗就強制停止,可以使用表示式failFast true
來條件控制。
並行stage{…}舉例:
pipeline { agent any pipeline { agent any stages { stage('Non-Parallel Stage') { steps { echo 'This stage will be executed first.' } } stage('Parallel Stage') { failFast true parallel { stage('並行一') { steps { echo "並行一" } } stage('並行二') { steps { echo "並行二" } } stage('並行三') { stages { stage('Nested 1') { steps { echo "In stage Nested 1 within Branch C" } } stage('Nested 2') { steps { echo "In stage Nested 2 within Branch C" } } } } } } } }
關於這個並行,我建立了一個jenkins job,跑一下就可以幫助你瞭解。
http://65.49.216.200:8080/job/paraller_demo/
執行完之後的stage 檢視是這樣的
並行1 並行2 並行3 三個stage之間的關係是並行的,上面截圖顯示都執行成功。這裡我們測試一下如果並行二發生報錯,會發生生成。在並行二里面的echo 改成echo1,再次執行。
由於我們添加了程式碼failFast true
,但是並行二這個stage發生了報錯。本來並行1 並行2 並行3下面兩個巢狀的stage都在同一時間併發執行,但是這個job最終的結果是
aborted, 從控制檯日誌或者UI顯示灰色能看出來確實是中止了。
總結一下,paraller{…}這個要會使用,使用這個表示並行執行裡面的多個stage。這裡舉例一下這個使用場景,例如我有一個模組的程式碼分別要在windows 和mac 和linux上三種環境下去測試。那麼我可以提前準備好三個環境的agent node機器,然後一套環境寫一個stage,把這三個stage都放在paraller{…}裡面,讓三個並行測試。paraller{…}上面一層這個stage名稱就可以叫xxx模組相容性測試。因為這三個環境都同等重要,你就可以設定failFast true,只要有一個不通過,就中止執行pipeline下面的程式碼。關於巢狀,非不得已,不要去使用,確實讓其他人不好讀程式碼和不好維護。
流程控制
由於pipeline是基於groovy語言開發的,所以支援在pipeline{...}程式碼塊寫流程控制語句程式碼和迴圈程式碼。原則上,大部分java和groovy的語法都可以在pipeline上得到很好的處理,但是還是有一些是不好相容的,所以,Jenkins特意為了更好使用pipeline,開發了一些工具類,方便我們更好地在step中處理各種需求。接下來,我要帶大家一起學習
https://jenkins.io/doc/pipeline/steps/pipeline-utility-steps/
這個頁面的一些常用的工具類的使用,算是一個實戰練習過程吧。pipeline語法就學習完了,對了還有一種script pipeline我不打算介紹,從頭到尾我們都在學習更容易維護和直觀的Declarative Pipeline模式。下面寫一個if控制語句來展開接下來我們要實戰的練習。
專案job: http://65.49.216.200:8080/job/flow_control_demo/
jenkins pipeline程式碼
pipeline {
agent any
stages {
stage('flow control') {
steps {
script {
if ( 10 == 10) {
println "pass"
}else {
println "failed"
}
}
}
}
}
}
接下來,我會盡量把程式碼全部放github,真正模擬開發過程來介紹各種工具類的實戰練習。