Pipeline 簡介
Jenkins2.x 的核心是使用 pipeline 來構建項目,也就是流水線,將 Jenkins1.0 版本中基于表單的配置信息比如 JDK/SVN 以及參數的配置都轉變成了代碼,即 pipeline as Code。
傳統的表單方式有以下缺點:
- 需要大量的 web 表單交互,有時候需要進行很多次的切換,比較繁瑣。
- 不能進行版本管理。
- 可重用性差。
而采用 pipeline 的方式,項目的所有流程和配置都寫在 Jenkinsfile 文件中,移植時只要將此文件拷貝即可,無須繁瑣的配置;而且 pipeline 可以很直觀的看到每個階段的構建情況,再結合上 Blue Ocean 可以進行強大的流水線監控,方便、直觀、及時地獲取到構建結果。
在 Jenkins 中,把每一段管道比作是不同的 Job,不同 Job 的鏈接就需要用到 Pipeline 插件。Jenkins 的工作流程可以簡單概括為 build-deploy-test-release,每個流程之間我們都可以用 Pipeline 來連接,大致如下效果圖:
Jenkins pipeline 是基于 Groovy 語言實現的一種 DSL(Domain-Specific Language,領域特定語言),可以理解為適用于 Jenkins 的編程語言。
pipeline 支持兩種語法:腳本式語法(scripted pipeline)和聲明式語法(declarativepipeline)。早期的 pipeline plugin 只支持腳本式語法,聲明式語法是在 pipeline2.5 之后新增加的,相對而言,聲明式語法更簡單,即使沒有 groovy 語言的基礎也能進行基本的操作。Jenkins 社區的動向也是偏向于聲明式語法,所以以聲明式語法為例進行說明。
Pipeline 基本結構
pipeline{agent anystages{stage('build'){steps{echo 'build steps'}}}
}
以上是最最基本的一個 pipeline 結構,具體的含義如下:
- pipeline:后面用一對 {} 也就是閉包,表示整條流水線,里面是流水線中具體的處理流程。
- agent:用來指定整個流水線或者某一個階段在哪個機器節點上執行。如果是 any 的話表示該流水線或者階段可以運行在任意一個定義好的節點上。這個指令必須要有,而且一般會放在頂層 pipeline{...} 的下一層,在 stage{...} 中也可以使用 agent,但是一般不這么用。
- stages:后面跟一對 {},類似于一個容器,封裝了一個或多個 stage,也就是將不同的階段組織在一起;例如 build 是一個 stage, test 是第二個 stage,deploy 是第三個 stage。通過 stage 隔離,讓 Pipeline 代碼讀寫非常直觀。
- stage:后面跟一對 {},流水線中的某個階段,其中封裝了多個執行步驟,每個階段都需要有個名稱。
- steps:封裝了在一個階段中的一個或多個具體的執行步驟。在本例中 echo 就是一個步驟。
接下來我們一一介紹上面提到的 pipeline 中包含的最基本的幾個 section,以及另外一些可選的 section。
agent
用來指定 pipeline 的執行節點,一般放在頂層的 pipeline 中。agent 部分支持幾種不同的參數以此來適應不同的應用場景。
1)any
作用:表示可以在任意的節點或者代理上執行此 pipeline。
代碼示例:
pipeline {agent any
}
2)none
作用:在 pipeline 的頂層應用中使用此參數的話表示不會為整個 pipeline 指定執行的節點,需要在每個 stage 部分用 pipeline 指定執行的節點。
代碼示例:
pipeline {agent nonestages {stage('test'){agent {label '具體的節點名稱'}}}
}
3)label
作用:在標簽指定的可用代理上執行 pipeline 或 stage,比如 agent {label "label"} 表示流水線或者階段可以運行在任何一個具有 label 標簽的代理節點上。
代碼示例:
pipeline {agent {label '具體的一個節點 label 名稱'}
}
4)自定義工作空間
作用:代理節點的標簽新增了一個特性,允許為流水線或階段指定一個自定義的工作空間,用 customWorkspace 指令來指定。和 label 功能類似。
代碼示例:
pipeline {agent {node {label "xxx-agent-機器"customWorkspace "${env.JOB_NAME}/${env.BUILD_NUMBER}"}}
}
此處的 node 可以換成 label,但是為了避免 Docker 代理節點中的 label 用法混淆,一般用 node 表示。這種類型的 agent 在實際工作中的使用場景是最多的。
測試代碼
pipeline {agent {node {label "xxx-agent-機器"customWorkspace "${env.JOB_NAME}/${env.BUILD_NUMBER}"}} stages {stage ("Build") {bat "dir" //執行windows下的bat命令} stage ('test') {echo ${JAVA_HOME} //打印JAVA_HOME}}
}
可以將以上代碼段放到 Jenkinsfile 中或者在 Jenkins ui 中去執行。
POST
post 部分用來指定 pipeline 或者 stage 執行完畢后的一些操作,比如發送郵件、環境清理等。post 部分在 Jenkins 代碼中是可選的,可以放到頂層,也就是和 agent 同級,也可以放到stage 中。在 post 代碼塊中支持多種指令,比如:always、success、failure、aborted、unstable、changed 等等,我們一一來介紹。
1)always
作用:當 pipeline 執行完畢后一定會執行的操作,不管成功還是還失敗。比如說文件句柄的關閉或者數據庫的清理工作等。
代碼示例:
pipeline {agent anystages {stage ("Build") {bat "dir"}} post {always {script {//寫相關清除/恢復環境等操作代碼}}}
}
2)success
作用:當 pipeline 執行完畢后且構建結果為成功狀態時才會執行的操作。
代碼示例:
pipeline {agent anystages {stage ("Build") {bat "dir"}} post {success{script {//寫相關清除/恢復環境等操作代碼}}}
}
3)failure
作用:當 pipeline 執行完畢后且構建結果為失敗時執行的操作,比如發送錯誤日志給相關人員。
4)changed
作用:當 pipeline 執行完畢后且構建狀態和之前不一致時執行的操作。
5)aborted
作用:當 pipeline 被手動終止時執行的操作。
6)unstable
作用:當 pipeline 構建結果不穩定時執行的操作。
7)以上命令的組合
在 post 部分是可以包含多個條件塊,也就是以上命令的組合,比如:
pipeline {agent anystages {stage ("Build") {bat "dir"}}post {always {script {echo "post always "}} success{script {echo "post success"}} failure{script {echo "post failure"}}}
}
stages/stage/steps
- stages:Pipeline 中單個階段的操作封裝到 stages 中,stages 中可以包含多個 stage。
- stage:一個單獨的階段,實際上所有實際工作都將包含在一個或多個 stage 指令中。stage{…} 里面有一個強制的字符串參數,用來描述這個 stage 的作用,這個字符串參數是不支持變量的,只能你自己取名一個描述字段。
- steps:一個 stage 下至少有一個 steps,一般也就是一個 steps。可以在 steps 下寫調用一個或者幾個方法,也就是兩三行代碼。
有以下注意點:
- 在聲明式 pipeline 腳本中,有且只有一個 stages。
- 一個 stage{…} 必須有且只有一個 steps{…}, 或者 parallel{…} 或者 stages {…},多層嵌套只支持在最后一個 stage{…} 里面。
- 在聲明式語法中只支持 steps,不支持在 steps {…} 里面嵌套寫 step{…}。
代碼示例:
pipeline {agent anystages {stage