1 - Jenkins Pipeline
在Jenkins 2.0中,基於 Jenkins Pipeline,用戶可以在一個 JenkinsFile 中快速實現一個項目的從構建、測試以到發布的完整流程,靈活方便地實現持續交付,並且可以保存和管理這個流水線的定義。
也就是說,Jenkins 2.0把Jenkins1.0中相關配置信息都轉換成Code形式,即Pipeline as Code。
Jenkinsfile
- 是一個文本文件,包含了流水線的邏輯,定義了流水線的各個階段,在每個階段可以執行相應的任務;
- 是流水線概念在Jenkins中的表現形式,實現了構建步驟代碼化、構建過程視圖化;
- 不同的Jenkins Plugin 擴展了Pipeline DSL可用的步驟和操作。
1.1 使用條件
- Jenkins 2.x或更高版本
- 安裝了Pipeline插件
1.2 創建方式
以流水線任務為例:
在Jenkins job配置頁面的pipeline部分,可以選擇pipeline script 或者 pipeline script from SCM
點擊“Pipeline Syntax”可以查看Pipeline內置文檔。
- pipeline script : 直接script輸入框里面輸入pipeline script語句即可
- pipeline script from SCM : 配置代碼存儲地址,並指定Jenkinsfile路徑
1.3 pipeline 語法
通過Groovy語言來實現pipeline。
2 - 腳本式(Scripted Pipeline)
在Scripted Pipeline的JenkinsFile 中可以定義多個 Groovy 函數來擴展 Jenkins Pipeline 的能力,實現腳本式pipeline,其實就是在寫Groovy代碼。
因此這種方式受 Jenkins 的限制較少,可以靈活控制和定義一個流水線,實現復雜的功能。
- Node: Jenkins 節點,是執行 Step 的具體運行環境
- Stage: 每個 Stage 代表一組操作,是一個邏輯分組的概念,可以跨多個 Node
- Step: 最基本的操作單元,例如:執行Shell腳本、構建Docker鏡像等。
3 - 聲明式(Declarative Pipeline)
更簡單更結構化的語法,更適合閱讀和理解。
使用預定義的結構,Jenkins 已經預置了很多描述流水線的結構,可以快速建立流水線
雖然同樣支持寫 Groovy 腳本,官方推薦將Groovy 腳本內容定義在 Shared Libraries 中
由於需要使用預定義的結構,對於復雜性的功能難以有效支持
為與BlueOcean腳本編輯器兼容,通常建議使用Declarative Pipeline的方式進行編寫,這種語法結構也會是未來的趨勢。
3.1 常用結構
所有有效的Declarative Pipeline必須包含在一個pipeline塊內。
除了個別限定外,Declarative Pipeline中的基本語句和表達式遵循與Groovy語法相同的規則。
pipeline {
agent {}
options {}
parameters {}
stages {
stage {
when {}
steps {}
}
parallel {
stage {}
stage {}
}
}
post {
always {}
}
}
stages
- 是stage的集合,Pipeline完成的所有實際工作都將包含在一個或多個stage指令中
- 一般情況下,stages至少包含一個stage指令,用於連接各個交付過程,如構建,測試和部署等
stage
- 用來區分pipeline的各個階段
- 包含的steps部分定義了具體操作內容
- stage與stages可以互相嵌套,stage中可以包含stages
steps
- 包含一個或多個具體操作步驟
- 可以使用Steps reference(https://
/pipeline-syntax/html)中的所有可用步驟 - script步驟可以提供一個有效的功能增強
3.2 常用語法
# agent
- 通過 agent 定義整個Pipeline或特定階段的執行環境,實現靈活調度資源
- Agent在Pipeline中必需存在
- 參數
- any : 在任何可用的agent 上執行Pipeline或stage
- none : 當在pipeline塊的頂層使用none時,將不會為整個Pipeline運行分配全局agent ,每個stage部分將需要包含其自己的agent部分
- label : 指定具體的 Jenkins Slave Node,也可以單獨指定Stage的執行環境
- docker : 執行Pipeline或stage時會動態啟動一個docker節點執行Pipelines,還可以接受一個args,直接傳遞給docker run調用
- dockerfile : 使用從Dockerfile源存儲庫中包含的容器來構建執行Pipeline或stage
- node : 在node中可以定義 label 和 customWorkspace(自定義運行的工作空間)等
# 環境變量
- 可以為全局或stage定義變量,例如`environment { aaa = 'bbb' }`
- 通過 env 訪問自定義的和Jenkins預置的環境變量,例如`${env.JOB_NAME}`
# 參數
- 通過 parameters 定義參數,例如`parameters { string(defaultValue: "xxx", description: 'yyy', name: 'zzz') }`
- 通過 params 訪問構建時的參數,例如`${params.xxx}`
- 支持booleanParam, choice, credentials, file, text, password, string等參數類型
# options
- 在Pipeline本身內配置Pipeline專用選項
- buildDiscarder : pipeline保持構建的最大個數
- disableConcurrentBuilds : 不允許並行執行Pipeline,可用於防止同時訪問共享資源等
- skipStagesAfterUnstable : 一旦構建狀態進入了“Unstable”狀態,就跳過此stage
- timeout : 設置Pipeline運行的超時時間,例如`options { timeout(time: 1, unit: 'HOURS') }`
- retry : 失敗后,重試整個Pipeline的次數,例如`options { retry(3) }`
- timestamps : 預定義由Pipeline生成的所有控制台輸出時間,例如`options { timestamps() }`
# tools
- 通過tools可自動安裝工具,並放置環境變量到PATH。如果agent none,將被忽略。
- 工具名稱必須在Jenkins的全局工具配置中存在。
- 示例`tools { maven 'apache-maven-3.5.2' }`
# when
- 通過 when 根據給定的條件確定是否執行該階段,控制流程走向
- 必須至少包含一個條件
- 多種內置條件
- branch : 當正在構建的分支與給出的分支模式匹配時執行(僅適用於多分支Pipeline)
- environment : 當指定的環境變量設置為給定值時執行
- expression : 當指定的Groovy表達式求值為true時執行
- not : 當嵌套條件為false時執行。必須包含一個條件
- allOf : 當所有嵌套條件都為真時執行。必須至少包含一個條件
- anyOf : 當至少一個嵌套條件為真時執行。必須至少包含一個條件
# Parallel
- 通過 parallel 定義並發步驟
- 對耗時長,相互不存在依賴的stage可以使用此方式提升運行效率
- 除了parallel stage,單個parallel里的多個step也可以使用並行的方式運行
# 超時、重試
- 通過 timout 定義超時時間,例如`timeout(time: 3, unit: "MINUTES") { xxxyyyzzz }`
- 通過 retry 定義重試次數,例如`retry(3) { xxxyyyzzz }`
# post
- 通過 post 定義資源清理、通知等,也就是定義Pipeline或stage運行結束時的操作
- 與Stages平級
- 有多種不同的condition: always、success、failure、unstable、changed
- always : 總是運行,無論Pipeline運行的完成狀態如何。
- changed : 只有當前Pipeline運行的狀態與先前完成的Pipeline的狀態不同時,才能運行。
- failure : 僅當前Pipeline處於“失敗”狀態時才運行,通常在Web UI中用紅色指示表示。
- success : 僅當前Pipeline具有“成功”狀態時才運行,通常在具有藍色或綠色指示的Web UI中表示。
- unstable : 僅當前Pipeline具有“不穩定”狀態時才運行,通常在具有黃色指示的Web UI中表示。
- aborted : 只有當前Pipeline處於“中止”狀態時,才會運行,通常在具有灰色指示的Web UI中表示。
# 觸發方式
- 通過 triggers 定義Pipeline自動化觸發的方式
- cron : 以cron風格來定義Pipeline觸發的常規間隔
- pollSCM : 以cron風格來定義Jenkins檢查SCM源更改的常規間隔。如果存在新的更改,則Pipeline將被重新觸發
4 - 聲明式與腳本式的比較
都是pipeline代碼的持久實現,都能夠使用pipeline內置的插件或者插件提供的steps,兩者都可以利用共享庫擴展。
不同之處在於語法和靈活性:
- Declarative pipeline對用戶來說,語法更嚴格,有固定的組織結構,更容易生成代碼段,使其成為用戶更理想的選擇。但是
- Scripted pipeline更加靈活,因為Groovy本身只能對結構和語法進行限制,對於更復雜的pipeline來說,用戶可以根據自己的業務進行靈活的實現和擴展。
5 - pipeline-syntax
- Snippet Generator:
https://<jenkins-server-url>/pipeline-syntax/
- Declarative Directive Generator:
https://<jenkins-server-url>/directive-generator/
- Declarative Online Documentation: https://jenkins.io/doc/book/pipeline/syntax/
- Steps Reference:
https://<jenkins-server-url>/pipeline-syntax/html
- Global Variable Reference:
https://<jenkins-server-url>/pipeline-syntax/globals
- Online Documentation: https://www.jenkins.io/doc/book/pipeline/
- Examples Reference: https://www.jenkins.io/doc/pipeline/examples/
- IntelliJ IDEA GDSL:
https://<jenkins-server-url>/pipeline-syntax/gdsl
5.1 變量
- 環境變量:
https://<jenkins-server-url>/env-vars.html/
- Global Variable Reference:
https://<jenkins-server-url>/pipeline-syntax/globals
5.2 代碼段生成器
- Snippet Generator:
https://<jenkins-server-url>/pipeline-syntax/
- 內置的“Snippet Generator”程序有助於為單個步驟生成代碼段。
- 只需要選擇所需的步驟並配置,然后單擊生成Pipeline腳本以創建一個可以復制並粘貼到Pipeline中的Pipeline代碼段。
6 - 參考信息
- Jenkins中文文檔 : https://www.w3cschool.cn/jenkins/
- 用代碼描述流水線-Jenkins Pipeline 詳解 : http://www.uml.org.cn/jchgj/201802051.asp