1. 程式人生 > >Jenkins高階篇之Pipeline語法篇-9-多個stage的關係:順序和並行

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.

認真看,可以看到這些特點。

  1. 所有的stage,都會內嵌在最外層的stages{…}
  2. 一個stage{…}下可以內嵌有且只有一個stages{…}
  3. 多層巢狀只支援在最後一個stage{…}裡面
  4. 巢狀越多越複雜,最簡單就是觀察每一個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,真正模擬開發過程來介紹各種工具類的實戰練習。