Jenkins Pipeline
官方網址:
https://jenkins.io/zh/doc/book/pipeline/getting-started/
流水線
1、什麼是Pipeline?
Pipeline是一套jenkins官方提供的插件,它可以用來在jenkins中實作和內建連續傳遞。
下面的流程圖是一個 CD 場景的示例,在Jenkins中很容易對該場景進行模組化:

流水線概念
下面的概念是Jenkins流水線很關鍵的一方面 , 它與流水線文法緊密相連 (參考 overview below).
流水線
流水線是使用者定義的一個CD流水線模型 。流水線的代碼定義了整個的建構過程, 他通常包括建構, 測試和傳遞應用程式的階段 。另外 ,
pipeline
塊是 聲明式流水線文法的關鍵部分.
節點
節點是一個機器 ,它是Jenkins環境的一部分 and is capable of執行流水線。另外,
node
塊是 腳本化流水線文法的關鍵部分.
階段
stage
塊定義了在整個流水線的執行任務的概念性地不同的的子集(比如 “Build”, “Test” 和 “Deploy” 階段), 它被許多插件用于可視化 或Jenkins流水線目前的 狀态/進展.
步驟
本質上 ,一個單一的任務, a step 告訴Jenkins 在特定的時間點要做_what_ (或過程中的 “step”)。 舉個例子,要執行shell指令 ,請使用
sh
步驟:
sh 'make'
。當一個插件擴充了流水線DSL, 通常意味着插件已經實作了一個新的 step。
流水線文法概述
下面的流水線代碼骨架說明了聲明式流水線文法和 腳本化流水線文法之間的根本差異。
請注意 階段 and 步驟 (上面的) 都是聲明式和腳本化流水線文法的常見元素。
聲明式流水線基礎
在聲明式流水線文法中,
pipeline
塊定義了整個流水線中完成的所有的工作。
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any 1
stages {
stage('Build') { 2
steps {
// 3
}
}
stage('Test') { 4
steps {
// 5
}
}
stage('Deploy') { 6
steps {
// 7
}
}
}
}
1 | 在任何可用的代理上,執行流水線或它的任何階段。 |
---|---|
2 | 定義 “Build” 階段。 |
3 | 執行與 “Build” 階段相關的步驟。 |
4 | 定義"Test" 階段。 |
5 | 執行與"Test" 階段相關的步驟。 |
6 | 定義 “Deploy” 階段。 |
7 | 執行與 “Deploy” 階段相關的步驟。 |
腳本化流水線基礎
在腳本化流水線文法中, 一個或多個
node
塊在整個流水線中執行核心工作。 雖然這不是腳本化流水線文法的強制性要求, 但它限制了你的流水線的在
node
塊内的工作做兩件事:
- 通過在Jenkins隊列中添加一個項來排程塊中包含的步驟。 節點上的執行器一空閑, 該步驟就會運作。
-
建立一個工作區(特定為特定流水間建立的目錄),其中工作可以在從源代碼控制檢出的檔案上完成。
Caution: 根據你的 Jenkins 配置,在一系列的空閑後,一些工作區可能不會自動清理 。參考 JENKINS-2111 了解更多資訊。
Jenkinsfile (Scripted Pipeline)
node {
stage('Build') {
//
}
stage('Test') {
//
}
stage('Deploy') {
//
}
}
在任何可用的代理上,執行流水線或它的任何階段。 |
---|
定義 “Build” 階段。 塊 在腳本化流水線文法中是可選的。 然而, 在腳本化流水線中實作 塊 ,可以清楚的顯示Jenkins UI中的每個 的任務子集。 |
執行與 “Build” 階段相關的步驟。 |
定義 “Test” 階段。 |
執行與 “Test” 階段相關的步驟。 |
定義 “Deploy” 階段。 |
執行與 “Deploy” 階段相關的步驟。 |
流水線示例
這有一個使用聲明式流水線的文法編寫的
Jenkinsfile
檔案 - 可以通過點選下面 Toggle Scripted Pipeline 連結來通路它的等效的腳本化文法:
Jenkinsfile (Declarative Pipeline)
pipeline { 1
agent any 2
stages {
stage('Build') { 3
steps { 4
sh 'make' 5
}
}
stage('Test'){
steps {
sh 'make check'
junit 'reports/**/*.xml' 6
}
}
stage('Deploy') {
steps {
sh 'make publish'
}
}
}
}
Toggle Scripted Pipeline (Advanced)
1 | 是聲明式流水線的一種特定文法,他定義了包含執行整個流水線的所有内容和指令的 “block” 。 |
---|---|
2 | 是聲明式流水線的一種特定文法,它訓示 Jenkins 為整個流水線配置設定一個執行器 (在節點上)和工作區。 |
3 | 是一個描述 stage of this Pipeline的文法塊。在 Pipeline syntax 頁面閱讀更多有關聲明式流水線文法的 塊的資訊。如 above所述, 在腳本化流水線文法中, 塊是可選的。 |
4 | 是聲明式流水線的一種特定文法,它描述了在這個 中要運作的步驟。 |
5 | 是一個執行給定的shell指令的流水線 step (由 Pipeline: Nodes and Processes plugin提供) 。 |
6 | 是另一個聚合測試報告的流水線 step (由 JUnit plugin提供)。 |
7 | 是腳本化流水線的一種特定文法,它訓示 Jenkins 在任何可用的代理/節點上執行流水線 (和包含在其中的任何階段)這實際上等效于 聲明式流水線特定文法的 。 |

我的了解就是:pipeline是一個流程,這個流程定義了完成過一個CI/CD流程的步驟,通過執行這個流程代替手工自動去完成CI/CD,這個流程是由使用者自己定義的。
整個流程主要有以下幾個子產品組成:
1.agent
2.param
3.stage
首先介紹stage。pipeline實際上就是由很多個stage組成,每個stage完成一件事情。就像上圖中第二個stage用來建構項目,第三個stage用來測試項目。是以定義pipeline實際上就是定義多個stage。而stage是由多個step組成,由step來定義這個stage是如何完成一個任務的。比如要執行test這個測試stage,通過step定義第一步拉取代碼,第二步進行測試,第三步将測試結果發送郵件。
接着就是agent,agent是用來定義CI/CD流程環境的,比如你在建構gradle項目的時候需要gradle環境,這時候就由agent來定義。agent可以定義全局的,就是所有的stage都會在這個環境中進行,也可以放在stage中,意味這隻有該stage會放在這個環境中執行。
然後就是param。param是為整個流程提供參數的。這一點是很好的,比如你使用git進行代碼管理,你需要建構某個流程,這時候你隻要在建構的時候指定分支參數就可以建構項目。
最後,還有其他部分,比如所有的stage都執行完成了,或者失敗了,這時候你需要發送郵件,你可以在最後的部分定義發送郵件,不論建構成功與否。
2、定義pipeline
pipeline的定義被寫在一個文本檔案——jenkinsfile,該檔案又可以送出給項目的源代碼控制庫, 将pipeline視為應用程式的一部分,以便像任何其他代碼一樣進行版本控制和審查。
建立Jenkinsfile并将其送出給源代碼管理提供了許多直接的好處:
1.自動為所有分支和拉取請求建立pipeline建構過程。
2.pipeline上的代碼審查/疊代(以及剩餘的源代碼)。
3.pipeline的審計跟蹤。
4.可由項目的多個成員檢視和編輯。
雖然在Web UI直接定義pipelins和使用 Jenkinsfile定義是相同的,但通常認為最佳做法是使用Jenkinsfile定義pipeline并檢查其中的源代碼控制。
3、為何選擇Pipeline?
從根本上說,Jenkins是一個支援多種自動化模式的自動化引擎。Pipeline為Jenkins添加了一套功能強大的自動化工具,支援從簡單的持續內建到全面的CD pipeline的用例。通過對一系列相關任務模組化,使用者可以利用Pipeline的許多功能:
代碼:pipeline在代碼中實作,通常檢查到源代碼控制,使團隊能夠編輯,審查和疊代其傳遞管道。
持久:pipeline可以在Jenkins master的計劃内和計劃外重新開機中存活。
Pausable:在繼續pipeline運作之前,pipeline可以選擇停止并等待人工輸入或準許。
多功能:pipeline支援複雜的實際CD要求,包括并行分叉/連接配接,循環和執行工作的能力。
可擴充:Pipeline插件支援其DSL的自定義擴充 和多個與其他插件內建的選項。
一、流水線入門
正如 前文 提到的,Jenkins 流水線是一套插件,它支援實作和內建持續傳遞流水線到 Jenkins。流水線提供了一組可擴充的工具,用于通過流水線 DSL 将簡單到複雜的傳遞流水線模組化為“代碼”。
本節描述了如何在 Jenkins 中開始建立你的流水線并介紹建立和存儲
Jenkinsfile
的各種方式。
配置要求
為了使用 Jenkins 流水線,你需要:
- Jenkins 2.x 或以上版本(舊版本到 1.642.3 可能可以,但不建議)
- 流水線插件,作為“建議插件”的一部分安裝(在安裝 Jenkins 後,運作 Post-installation setup wizard 時指定)。
在 Managing Plugins 中閱讀了解更多與安裝和管理插件有關的資訊。
定義流水線
聲明式和腳本式流水線都是 DSL 語言,[1]用來描述軟體傳遞流水線的一部分。 腳本式流水線是用一種限制形式的 Groovy 文法編寫的。
本文檔将根據需要介紹 Groovy 文法的相關部分,是以雖然了解 Groovy 對使用流水線有所幫助,但并不是必須的。
流水線可以通過以下任一方式來建立:
- 通過 Blue Ocean - 在 Blue Ocean 中設定一個流水線項目後,Blue Ocean UI 會幫你編寫流水線的
檔案并送出到源代碼管理系統。Jenkinsfile
- 通過經典 UI - 你可以通過經典 UI 在 Jenkins 中直接輸入基本的流水線。
- 在源碼管理系統中定義 - 你可以手動編寫一個
檔案,然後送出到項目的源代碼管理倉庫中。[3]Jenkinsfile
使用兩種方式定義流水線的文法是相同的。盡管 Jenkins 支援在經典 UI 中直接進入流水線,但通常認為最好的實踐是在
Jenkinsfile
檔案中定義流水線,Jenkins 之後會直接從源代碼管理系統加載。
通過 Blue Ocean
如果你剛接觸 Jenkins 流水線,Blue Ocean UI 可以幫助你 設定流水線項目,并通過圖形化流水線編輯器為你自動建立和編寫流水線(即
Jenkinsfile
)。
作為在 Blue Ocean 中設定流水線項目的一部分,Jenkins 給你項目的源代碼管理倉庫配置了一個安全的、經過身份驗證的适當的連接配接。是以,你通過 Blue Ocean 的流水線編輯器在
Jenkinsfile
中做的任何更改都會自動的儲存并送出到源代碼管理系統。
了解更多 Blue Ocean 相關資訊請前往 Blue Ocean 章節和 Blue Ocean 入門頁面。
通過經典 UI
使用經典 UI 建立的
Jenkinsfile
由 Jenkins 自己儲存(在 Jenkins 的主目錄下)。
想要通過 Jenkins 經典 UI 建立一個基本流水線:
- 如果有要求的話,確定你已登入進 Jenkins。
- 從Jenkins 首頁(即 Jenkins 經典 UI 的工作台),點選左上的 建立任務。
Jenkins PipelineJenkins Pipeline一、流水線入門二、流水線文法三、使用 Jenkinsfile -
在 輸入一個任務名稱字段,填寫你建立的流水線項目的名稱。
**警告:**Jenkins 使用這個項目名稱在磁盤上建立目錄。建議不要在項目名稱中使用空格,因為這樣做可能會觸發在腳本中不能正确處理目錄路徑中的空格的bug。
- 向下滾動并點選 流水線,然後點選頁面底部的 确定 打開流水線配置頁(已選中 General 選項)。
Jenkins PipelineJenkins Pipeline一、流水線入門二、流水線文法三、使用 Jenkinsfile -
點選頁面頂部的 流水線 頁籤讓頁面向下滾動到 流水線 部分。
**注意:**如果你在源代碼管理系統中定義了
, 請按照下面的在源碼管理系統中定義的說明。Jenkinsfile
- 在 流水線 部分, 確定 定義 字段顯示 Pipeline script 選項。
-
将你的流水線代碼輸入到 腳本 文本區域。
例如,複制并粘貼下面的聲明式示例流水線代碼(在 Jenkinsfile ( … ) 标題下)或者它的腳本化的版本到 腳本 文本區域。(下面的聲明式示例将在整個過程的其餘部分使用。)
Jenkinsfile (Declarative Pipeline)
Toggle Scripted Pipeline (Advanced)pipeline { agent any stages { stage('Stage 1') { steps { echo 'Hello world!' } } } }
訓示 Jenkins 為整個流水線配置設定一個執行器(在 Jenkins 環境中的任何可用代理/節點上)和工作區。agent
寫一個簡單的字元串到控制台輸出。echo
與上面的node
做了同樣的事情。agent
**注意:**你也可以從 腳本 文本區域右上方的 try sample Pipeline… 選項選擇腳本式流水線的示例。注意該區域沒有可用的聲明式流水線示例。Jenkins PipelineJenkins Pipeline一、流水線入門二、流水線文法三、使用 Jenkinsfile - 點選 儲存 打開流水線項目視圖頁面。
- 在該頁面, 點選左側的 立即建構 Build Now 運作流水線。
Jenkins PipelineJenkins Pipeline一、流水線入門二、流水線文法三、使用 Jenkinsfile - 在左側的 Build History 下面,點選 #1 來通路這個特定流水線運作的詳細資訊。
- 點選 Console Output 來檢視流水線運作的全部輸出。下面的輸出顯示你的流水線已成功運作。 注意:
Jenkins PipelineJenkins Pipeline一、流水線入門二、流水線文法三、使用 Jenkinsfile - 你也可以通過點選建構号左邊的彩色地球儀從工作台直接通路控制台輸出(例如 #1)。
- 通過經典的 UI 定義流水線可以很友善的測試流水線代碼片段,也可以處理簡單的或不需要從源代碼倉庫中檢出/克隆的流水線。正如上面提到的,和通過 Blue Ocean(上面)或在版本管理系統中(下面)定義的
不同,在流水線項目的 腳本 文本區域輸入的Jenkinsfile
由 Jenkins 自己存儲在 Jenkins 主目錄下。是以,為了更好地控制和擴充你的流水線,尤其是源代碼管理系統中那些複雜的項目,建議使用 Blue Ocean 或 源碼管理系統來定義你的Jenkinsfile
檔案。Jenkinsfile
在源碼管理系統中
複雜的流水線很難在流水線配置頁面 經典 UI 的腳本文本區域進行編寫和維護。
為簡化操作,流水線的
Jenkinsfile
可以在文本編輯器或內建開發環境(IDE)中進行編寫并送出到源碼管理系統 [3](可選擇性地與需要 Jenkins 建構的應用程式代碼放在一起)。然後 Jenkins 從源代碼管理系統中檢出
Jenkinsfile
檔案作為流水線項目建構過程的一部分并接着執行你的流水線。
要使用來自源代碼管理系統的
Jenkinsfile
檔案配置流水線項目:
- 按照 通過經典 UI上面的步驟定義你的流水線直到第5步(在流水線配置頁面通路流水線部分)。
- 從 定義 字段選擇 Pipeline script from SCM 選項。
- 從 SCM 字段,選擇包含
檔案的倉庫的源代碼管理系統的類型。Jenkinsfile
-
填充對應倉庫的源代碼管理系統的字段。
Tip: 如果你不确定給定字段應填寫什麼值,點選它右側的 ? 圖示以擷取更多資訊。
- 在 腳本路徑 字段,指定你的
檔案的位置(和名稱)。這個位置是 Jenkins 檢出/克隆包括Jenkinsfile
檔案的倉庫的位置,它應該與倉庫的檔案結構比對。該字段的預設值采取名稱為 “Jenkinsfile” 的Jenkinsfile
檔案并位于倉庫的根路徑。Jenkinsfile
當你更新指定的倉庫時,隻要流水線配置了版本管理系統的輪詢觸發器,就會觸發一個新的建構。
由于流水線代碼(特别是腳本式流水線)是使用類似 Groovy 的文法編寫的, 如果你的IDE不能正确的使用文法高亮顯示你的 ,可以嘗試在 檔案的頂部插入行 糾正這個問題。 |
---|
内置文檔
流水線擁有内置文檔的特性可以讓建立各種複雜的流水線變得更容易。該内置文檔基于 Jenkins 執行個體中安裝的插件自動生成和更新。
該内置文檔可以在
${YOUR_JENKINS_URL}/pipeline-syntax
全局地找到。對于任何已配置的流水線項目,這個文檔也被連結到側欄的流水線文法。
片段生成器
内置的“片段生成器”工具有助于為各個步驟建立代碼段,發現插件提供的新步驟,或者為特定的步驟嘗試不同的參數。
片段生成器由 Jenkins 執行個體中可用的步驟動态添加。可用的步驟的數量依賴于安裝的插件,這些插件顯式地公開了流水線中使用的步驟。
要使用代碼生成器生成一個步驟的片段:
- 從已配置好的流水線導航到 流水線文法 連結(見上),或通路
。${YOUR_JENKINS_URL}/pipeline-syntax
- 在 示例步驟 下拉菜單中選擇需要的步驟。
- 使用 示例步驟 下拉菜單的動态填充區來配置已選的步驟。
- 點選 生成流水線腳本 生成一個能夠被複制并粘貼到流水線中的流水線片段。
要通路所選步驟的附加資訊和/或文檔,請點選幫助圖示(上圖中的紅色箭頭所示)。
全局變量參考
對于隻展示步驟的片段生成器的補充,流水線還提供了一個内置的“全局變量參考”。和片段生成器一樣,它也是由插件動态添加。但和片段生成器不一樣的是,全局變量參考隻包含由流水線或插件提供的可用于流水線的變量文檔。
流水線預設提供的變量是:
-
env
可以從腳本式流水線中通路的環境變量,例如:
或env.PATH
。 通路内置的全局變量參考頁面env.BUILD_ID
以擷取完整的,最新的,可用于流水線的環境變量清單。${YOUR_JENKINS_URL}/pipeline-syntax/globals
-
params
将為流水線定義的所有參數作為 Map,例如:
。params.MY_PARAM_NAME
-
currentBuild
可用于發現目前正在執行的流水線的資訊, 比如
,currentBuild.result
等屬性。參考内置的全局變量參考頁面currentBuild.displayName
以擷取完整的,最新的,${YOUR_JENKINS_URL}/pipeline-syntax/globals
的屬性清單。currentBuild
聲明式指令生成器
片段生成器可以幫助生成腳本式流水線的步驟或者聲明式流水線的
stage
中的
steps
代碼塊,但是其并沒有包含用于定義聲明式流水線的 section(節段)和 directive(指令)。聲明式指令生成器(Declarative Directive Generator)這個工具可以做到這點。和 片段生成器類似,指令生成器允許你選擇聲明式的指令,對其以一種方式進行配置,然後生成這個指令的配置,讓你将其用于聲明式流水線。
要使用聲明式指令生成器生成一個聲明式的指令:
- 從已配置好的流水線導航到 Pipeline Syntax/流水線文法 連結(見上),然後點選側欄的 Declarative Directive Generator,或直接通路
。${YOUR_JENKINS_URL}/directive-generator
- 在下拉菜單中選擇需要的指令。
- 使用下拉菜單下面動态生成的區域配置已選的指令。
- 點選 Generate Declarative Directive 生成一個能夠被複制到流水線中的指令配置。
指令生成器可以生成嵌套的指令配置,比如在
when
指令内的條件,但是它不能生成流水線步驟。對于包含步驟的指令内容,比如
stage
内的
steps
或
post
内的條件如
always
或
failure
,指令生成器添加一個占位符注釋。你仍然需要手動添加步驟到流水線中。
Jenkinsfile (Declarative Pipeline)
stage('Stage 1') {
steps {
// One or more steps need to be included within the steps block.
}
}
二、流水線文法
本節是建立在 流水線入門内容的基礎上,而且,應當被當作一個參考。 對于在實際示例中如何使用流水線文法的更多資訊, 請參閱本章在流水線插件的2.5版本中的 使用 Jenkinsfile部分, 流水線支援兩種離散的文法,具體如下對于每種的優缺點, 參見文法比較。
正如 本章開始讨論的, 流水線最基礎的部分是 “步驟”。基本上, 步驟告訴 Jenkins 要做什麼,以及作為聲明式和腳本化流水線文法的基本建構塊。
對于可用步驟的概述, 請參考 流水線步驟引用,它包含了一個建構到流水線的步驟和 插件提供的步驟的全面的清單。
聲明式流水線
聲明式流水線是最近添加到 Jenkins 流水線的 ,它在流水線子系統之上提供了一種更簡單,更有主見的文法。
所有有效的聲明式流水線必須包含在一個
pipeline
塊中, 比如:
pipeline {
/* insert Declarative Pipeline here */
}
在聲明式流水線中有效的基本語句和表達式遵循與 Groovy的文法同樣的規則, 有以下例外:
- 流水線頂層必須是一個 block, 特别地:
pipeline { }
- 沒有分号作為語句分隔符,,每條語句都必須在自己的行上。
- 塊隻能由 節段, 指令, 步驟, 或指派語句組成。 *屬性引用語句被視為無參方法調用。 例如, input被視為 input()
節段
聲明式流水線中的節段通常包含一個或多個 指令 或 步驟。
代理
agent
部分指定了整個流水線或特定的部分, 将會在Jenkins環境中執行的位置,這取決于
agent
區域的位置。該部分必須在
pipeline
塊的頂層被定義, 但是 stage 級别的使用是可選的。
Required | Yes |
---|---|
Parameters | Described below |
Allowed | In the top-level block and each block. |
參數
為了支援作者可能有的各種各樣的用例流水線,
agent
部分支援一些不同類型的參數。這些參數應用在
pipeline
塊的頂層, 或
stage
指令内部。
-
any
在任何可用的代理上執行流水線或階段。例如:
agent any
-
none
當在
塊的頂部沒有全局代理, 該參數将會被配置設定到整個流水線的運作中并且每個pipeline
部分都需要包含他自己的stage
部分。比如:agent
agent none
-
label
在提供了标簽的 Jenkins 環境中可用的代理上執行流水線或階段。 例如:
agent { label 'my-defined-label' }
- node
和agent { node { label 'labelName' } }
一樣, 但是agent { label 'labelName' }
允許額外的選項 (比如node
)。customWorkspace
-
docker
使用給定的容器執行流水線或階段。該容器将在預置的 node上,或在比對可標明義的
參數上,動态的供應來接受基于Docker的流水線。label
也可以選擇的接受docker
參數,該參數可能包含直接傳遞到args
調用的參數, 以及docker run
選項, 該選項強制alwaysPull
,即使鏡像名稱已經存在。 比如:docker pull
或agent { docker 'maven:3-alpine' }
agent { docker { image 'maven:3-alpine' label 'my-defined-label' args '-v /tmp:/tmp' } }
-
dockerfile
執行流水線或階段, 使用從源代碼庫包含的
建構的容器。為了使用該選項,Dockerfile
必須從多個分支流水線中加載, 或者加載 “Pipeline from SCM.” 通常,這是源代碼倉庫的根目錄下的Jenkinsfile
:Dockerfile
. 如果在另一個目錄下建構agent { dockerfile true }
, 使用Dockerfile
選項:dir
。如果agent { dockerfile {dir 'someSubDir' } }
有另一個名稱, 你可以使用Dockerfile
選項指定該檔案名。你可以傳遞額外的參數到filename
使用docker build ...
選項送出, 比如additionalBuildArgs
。 例如, 一個帶有agent { dockerfile {additionalBuildArgs '--build-arg foo=bar' } }
的倉庫,期望一個建構參數build/Dockerfile.build
:version
agent { // Equivalent to "docker build -f Dockerfile.build --build-arg version=1.0.2 ./build/ dockerfile { filename 'Dockerfile.build' dir 'build' label 'my-defined-label' additionalBuildArgs '--build-arg version=1.0.2' } }
常見選項
有一些應用于兩個或更多
agent
的實作的選項。他們不被要求,除非特别規定。
-
label
一個字元串。該标簽用于運作流水線或個别的
。該選項對stage
,node
和docker
可用,dockerfile
要求必須選擇該選項。node
-
customWorkspace
一個字元串。在自定義工作區運作應用了
的流水線或個别的agent
, 而不是預設值。 它既可以是一個相對路徑, 在這種情況下,自定義工作區會存在于節點工作區根目錄下, 或者一個絕對路徑。比如:stage
該選項對agent { node { label 'my-defined-label' customWorkspace '/some/other/path' } }
,node
和docker
有用 。dockerfile
-
reuseNode
一個布爾值, 預設為false。 如果是true, 則在流水線的頂層指定的節點上運作該容器, 在同樣的工作區, 而不是在一個全新的節點上。這個選項對
和docker
有用, 并且隻有當 使用在個别的dockerfile
的stage
上才會有效。agent
示例
Jenkinsfile (Declarative Pipeline)
pipeline {
agent { docker 'maven:3-alpine' } 1
stages {
stage('Example Build') {
steps {
sh 'mvn -B clean verify'
}
}
}
}
1 | 在一個給定名稱和标簽( )的建立的容器上執行定義在流水線中的所有步驟 。 |
---|---|
階段級别的
agent
部分
Jenkinsfile (Declarative Pipeline)
pipeline {
agent none 1
stages {
stage('Example Build') {
agent { docker 'maven:3-alpine' } 2
steps {
echo 'Hello, Maven'
sh 'mvn --version'
}
}
stage('Example Test') {
agent { docker 'openjdk:8-jre' } 3
steps {
echo 'Hello, JDK'
sh 'java -version'
}
}
}
}
1 | 在流水線頂層定義 確定 an Executor 沒有被配置設定。 使用 也會強制 部分包含他自己的 部分。 |
---|---|
2 | 使用鏡像在一個建立的容器中執行該階段的該步驟。 |
3 | 使用一個與之前階段不同的鏡像在一個建立的容器中執行該階段的該步驟。 |
post
post
部分定義一個或多個steps ,這些階段根據流水線或階段的完成情況而 運作(取決于流水線中
post
部分的位置).
post
支援以下 post-condition 塊中的其中之一:
always
,
changed
,
failure
,
success
,
unstable
, 和
aborted
。這些條件塊允許在
post
部分的步驟的執行取決于流水線或階段的完成狀态。
Required | No |
---|---|
Parameters | None |
Allowed | In the top-level block and each block. |
Conditions
-
無論流水線或階段的完成狀态如何,都允許在always
部分運作該步驟。post
-
隻有目前流水線或階段的完成狀态與它之前的運作不同時,才允許在changed
部分運作該步驟。post
-
隻有目前流水線或階段的完成狀态為"failure",才允許在failure
部分運作該步驟, 通常web UI是紅色。post
-
隻有目前流水線或階段的完成狀态為"success",才允許在success
部分運作該步驟, 通常web UI是藍色或綠色。post
-
隻有目前流水線或階段的完成狀态為"unstable",才允許在unstable
部分運作該步驟, 通常由于測試失敗,代碼違規等造成。通常web UI是黃色。post
-
隻有目前流水線或階段的完成狀态為"aborted",才允許在aborted
部分運作該步驟, 通常由于流水線被手動的aborted。通常web UI是灰色。post
示例
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Example') {
steps {
echo 'Hello World'
}
}
}
post { 1
always { 2
echo 'I will always say Hello again!'
}
}
}
1 | 按照慣例, 部分應該放在流水線的底部。 |
---|---|
2 | Post-condition 塊包含與 steps 部分相同的steps。 |
stages
包含一系列一個或多個 stage 指令,
stages
部分是流水線描述的大部分"work" 的位置。 建議
stages
至少包含一個 stage 指令用于連續傳遞過程的每個離散部分,比如建構, 測試, 和部署。
Required | Yes |
---|---|
Parameters | None |
Allowed | Only once, inside the block. |
示例
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages { 1
stage('Example') {
steps {
echo 'Hello World'
}
}
}
}
1 | 部分通常會遵循諸如 , 等的指令。 |
---|---|
steps
steps
部分在給定的
stage
指令中執行的定義了一系列的一個或多個steps。
Required | Yes |
---|---|
Parameters | None |
Allowed | Inside each block. |
示例
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Example') {
steps { 1
echo 'Hello World'
}
}
}
}
1 | 部分必須包含一個或多個步驟。 |
---|---|
指令
environment
environment
指令制定一個 鍵-值對序列,該序列将被定義為所有步驟的環境變量,或者是特定于階段的步驟, 這取決于
environment
指令在流水線内的位置。
該指令支援一個特殊的助手方法
credentials()
,該方法可用于在Jenkins環境中通過辨別符通路預定義的憑證。對于類型為 "Secret Text"的憑證,
credentials()
将確定指定的環境變量包含秘密文本内容。對于類型為 "SStandard username and password"的憑證, 指定的環境變量指定為
username:password
,并且兩個額外的環境變量将被自動定義 :分别為
MYVARNAME_USR
和
MYVARNAME_PSW
。
Required | No |
---|---|
Parameters | None |
Allowed | Inside the block, or within directives. |
示例
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
environment { 1
CC = 'clang'
}
stages {
stage('Example') {
environment { 2
AN_ACCESS_KEY = credentials('my-prefined-secret-text') 3
}
steps {
sh 'printenv'
}
}
}
}
1 | 頂層流水線塊中使用的 指令将适用于流水線中的所有步驟。 |
---|---|
2 | 在一個 中定義的 指令隻會将給定的環境變量應用于 中的步驟。 |
3 | 塊有一個 助手方法 定義,該方法可以在 Jenkins 環境中用于通過辨別符通路預定義的憑證。 |
options
options
指令允許從流水線内部配置特定于流水線的選項。 流水線提供了許多這樣的選項, 比如
buildDiscarder
,但也可以由插件提供, 比如
timestamps
.
Required | No |
---|---|
Parameters | None |
Allowed | Only once, inside the block. |
可用選項
-
buildDiscarder
為最近的流水線運作的特定數量儲存元件和控制台輸出。例如:
options { buildDiscarder(logRotator(numToKeepStr: '1')) }
-
disableConcurrentBuilds
不允許同時執行流水線。 可被用來防止同時通路共享資源等。 例如:
options { disableConcurrentBuilds() }
-
overrideIndexTriggers
允許覆寫分支索引觸發器的預設處理。 如果分支索引觸發器在多分支或組織标簽中禁用,
将隻允許它們用于促工作。否則,options { overrideIndexTriggers(true) }
隻會禁用改作業的分支索引觸發器。options { overrideIndexTriggers(false) }
-
skipDefaultCheckout
在
指令中,跳過從源代碼控制中檢出代碼的預設情況。例如:agent
options { skipDefaultCheckout() }
-
skipStagesAfterUnstable
一旦建構狀态變得UNSTABLE,跳過該階段。例如:
options { skipStagesAfterUnstable() }
-
checkoutToSubdirectory
在工作空間的子目錄中自動地執行源代碼控制檢出。例如:
options { checkoutToSubdirectory('foo') }
-
timeout
設定流水線運作的逾時時間, 在此之後,Jenkins将中止流水線。例如:
options { timeout(time: 1, unit: 'HOURS') }
-
retry
在失敗時, 重新嘗試整個流水線的指定次數。 For example:
options { retry(3) }
-
timestamps
預謀所有由流水線生成的控制台輸出,與該流水線發出的時間一緻。 例如:
options { timestamps() }
Example
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
options {
timeout(time: 1, unit: 'HOURS') 1
}
stages {
stage('Example') {
steps {
echo 'Hello World'
}
}
}
}
1 | 指定一個小時的全局執行逾時, 在此之後,Jenkins 将中止流水線運作。 |
---|---|
一個完整的可用選項清單正在等待完成第 INFRA-1503次。 |
---|
階段選項
stage
的
options
指令類似于流水線根目錄上的
options
指令。然而,
stage
-級别
options
隻能包括
retry
,
timeout
, 或
timestamps
等步驟, 或與
stage
相關的聲明式選項,如
skipDefaultCheckout
。
在
stage
,
options
指令中的步驟在進入
agent
之前被調用或在
when
條件出現時進行檢查。
可選的階段選項
-
skipDefaultCheckout
在
指令中跳過預設的從源代碼控制中檢出代碼。例如:agent
options { skipDefaultCheckout() }
-
timeout
設定此階段的逾時時間, 在此之後, Jenkins 會終止該階段。 例如:
options { timeout(time: 1, unit: 'HOURS') }
-
retry
在失敗時, 重試此階段指定次數。 例如:
options { retry(3) }
-
timestamps
預謀此階段生成的所有控制台輸出以及該行發出的時間一緻。例如:
options { timestamps() }
示例
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Example') {
options {
timeout(time: 1, unit: 'HOURS') 1
}
steps {
echo 'Hello World'
}
}
}
}
1 | 指定 階段的執行逾時時間, 在此之後,Jenkins 将中止流水線運作。 |
---|---|
參數
parameters
指令提供了一個使用者在觸發流水線時應該提供的參數清單。這些使用者指定參數的值可通過
params
對象提供給流水線步驟, 了解更多請參考示例。
Required | No |
---|---|
Parameters | None |
Allowed | Only once, inside the block. |
可用參數
-
string
字元串類型的參數, 例如:
parameters { string(name: 'DEPLOY_ENV', defaultValue: 'staging', description: '') }
-
booleanParam
布爾參數, 例如:
parameters { booleanParam(name: 'DEBUG_BUILD', defaultValue: true, description: '') }
示例
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
parameters {
string(name: 'PERSON', defaultValue: 'Mr Jenkins', description: 'Who should I say hello to?')
}
stages {
stage('Example') {
steps {
echo "Hello ${params.PERSON}"
}
}
}
}
一份完整的可用參數清單正在等待 INFRA-1503的完成。 |
---|
觸發器
triggers
指令定義了流水線被重新觸發的自動化方法。對于內建了源( 比如 GitHub 或 BitBucket)的流水線, 可能不需要
triggers
,因為基于 web 的內建很肯能已經存在。 目前可用的觸發器是
cron
,
pollSCM
和
upstream
。
Required | No |
---|---|
Parameters | None |
Allowed | Only once, inside the block. |
-
cron
接收 cron 樣式的字元串來定義要重新觸發流水線的正常間隔 ,比如:
triggers { cron('H */4 * * 1-5') }
-
pollSCM
接收 cron 樣式的字元串來定義一個固定的間隔,在這個間隔中,Jenkins 會檢查新的源代碼更新。如果存在更改, 流水線就會被重新觸發。例如:
triggers { pollSCM('H */4 * * 1-5') }
-
upstream
接受逗号分隔的工作字元串和門檻值。 當字元串中的任何作業以最小門檻值結束時,流水線被重新觸發。例如:
triggers { upstream(upstreamProjects: 'job1,job2', threshold: hudson.model.Result.SUCCESS) }
隻在Jenkins 2.22 及以上版本中可用。 |
---|
示例
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
triggers {
cron('H */4 * * 1-5')
}
stages {
stage('Example') {
steps {
echo 'Hello World'
}
}
}
}
stage
stage
指令在
stages
部分進行,應該包含一個 實際上, 流水巷所做的所有實際工作都将封裝進一個或多個
stage
指令中。
Required | At least one |
---|---|
Parameters | One mandatory parameter, a string for the name of the stage. |
Allowed | Inside the section. |
示例
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Example') {
steps {
echo 'Hello World'
}
}
}
}
工具
定義自動安裝和放置
PATH
的工具的一部分。如果
agent none
指定,則忽略該操作。
Required | No |
---|---|
Parameters | None |
Allowed | Inside the block or a block. |
支援工具
- maven
- jdk
- gradle
示例
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
tools {
maven 'apache-maven-3.0.1' 1
}
stages {
stage('Example') {
steps {
sh 'mvn --version'
}
}
}
}
1 | The tool name must be pre-configured in Jenkins under Manage Jenkins → Global Tool Configuration. |
---|---|
input
stage
的
input
指令允許你使用
input
step提示輸入。 在應用了
options
後,進入
stage
的
agent
或評估
when
條件前,
stage
将暫停。 如果
input
被準許,
stage
将會繼續。 作為
input
送出的一部分的任何參數都将在環境中用于其他
stage
。
配置項
-
message
必需的。 這将在使用者送出
時呈現給使用者。input
- id
的可選辨別符, 預設為input
名稱。stage
- ok
表單上的"ok" 按鈕的可選文本。input
-
submitter
可選的以逗号分隔的使用者清單或允許送出
的外部組名。預設允許任何使用者。input
-
submitterParameter
環境變量的可選名稱。如果存在,用
名稱設定。submitter
-
parameters
提示送出者提供的一個可選的參數清單。 更多資訊參見 [parameters]。
示例
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Example') {
input {
message "Should we continue?"
ok "Yes, we should."
submitter "alice,bob"
parameters {
string(name: 'PERSON', defaultValue: 'Mr Jenkins', description: 'Who should I say hello to?')
}
}
steps {
echo "Hello, ${PERSON}, nice to meet you."
}
}
}
}
when
when
指令允許流水線根據給定的條件決定是否應該執行階段。
when
指令必須包含至少一個條件。 如果
when
指令包含多個條件, 所有的子條件必須傳回True,階段才能執行。 這與子條件在
allOf
條件下嵌套的情況相同 (參見下面的示例)。
使用諸如
not
,
allOf
, 或
anyOf
的嵌套條件可以建構更複雜的條件結構 can be built 嵌套條件刻意潛逃到任意深度。
Required | No |
---|---|
Parameters | None |
Allowed | Inside a directive |
内置條件
-
branch
當正在建構的分支與模式給定的分支比對時,執行這個階段, 例如:
。注意,這隻适用于多分支流水線。when { branch 'master' }
-
environment
當指定的環境變量是給定的值時,執行這個步驟, 例如:
when { environment name: 'DEPLOY_TO', value: 'production' }
-
expression
當指定的Groovy表達式評估為true時,執行這個階段, 例如:
when { expression { return params.DEBUG_BUILD } }
-
not
當嵌套條件是錯誤時,執行這個階段,必須包含一個條件,例如:
when { not { branch 'master' } }
-
allOf
當所有的嵌套條件都正确時,執行這個階段,必須包含至少一個條件,例如:
when { allOf { branch 'master'; environment name: 'DEPLOY_TO', value: 'production' } }
-
anyOf
當至少有一個嵌套條件為真時,執行這個階段,必須包含至少一個條件,例如:
when { anyOf { branch 'master'; branch 'staging' } }
在進入 stage
的 agent
前評估 when
stage
agent
when
預設情況下, 如果定義了某個階段的代理,在進入該
stage
的
agent
後該
stage
的
when
條件将會被評估。但是, 可以通過在
when
塊中指定
beforeAgent
選項來更改此選項。 如果
beforeAgent
被設定為
true
, 那麼就會首先對
when
條件進行評估 , 并且隻有在
when
條件驗證為真時才會進入
agent
。
示例
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Example Build') {
steps {
echo 'Hello World'
}
}
stage('Example Deploy') {
when {
branch 'production'
}
steps {
echo 'Deploying'
}
}
}
}
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Example Build') {
steps {
echo 'Hello World'
}
}
stage('Example Deploy') {
when {
branch 'production'
environment name: 'DEPLOY_TO', value: 'production'
}
steps {
echo 'Deploying'
}
}
}
}
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Example Build') {
steps {
echo 'Hello World'
}
}
stage('Example Deploy') {
when {
allOf {
branch 'production'
environment name: 'DEPLOY_TO', value: 'production'
}
}
steps {
echo 'Deploying'
}
}
}
}
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Example Build') {
steps {
echo 'Hello World'
}
}
stage('Example Deploy') {
when {
branch 'production'
anyOf {
environment name: 'DEPLOY_TO', value: 'production'
environment name: 'DEPLOY_TO', value: 'staging'
}
}
steps {
echo 'Deploying'
}
}
}
}
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Example Build') {
steps {
echo 'Hello World'
}
}
stage('Example Deploy') {
when {
expression { BRANCH_NAME ==~ /(production|staging)/ }
anyOf {
environment name: 'DEPLOY_TO', value: 'production'
environment name: 'DEPLOY_TO', value: 'staging'
}
}
steps {
echo 'Deploying'
}
}
}
}
Jenkinsfile (Declarative Pipeline)
pipeline {
agent none
stages {
stage('Example Build') {
steps {
echo 'Hello World'
}
}
stage('Example Deploy') {
agent {
label "some-label"
}
when {
beforeAgent true
branch 'production'
}
steps {
echo 'Deploying'
}
}
}
}
并行
聲明式流水線的階段可以在他們内部聲明多隔嵌套階段, 它們将并行執行。 注意,一個階段必須隻有一個
steps
或
parallel
的階段。 嵌套階段本身不能包含進一步的
parallel
階段, 但是其他的階段的行為與任何其他
stage
相同。任何包含
parallel
的階段不能包含
agent
或
tools
階段, 因為他們沒有相關
steps
。
另外, 通過添加
failFast true
到包含
parallel
的
stage
中, 當其中一個程序失敗時,你可以強制所有的
parallel
階段都被終止。
示例
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Non-Parallel Stage') {
steps {
echo 'This stage will be executed first.'
}
}
stage('Parallel Stage') {
when {
branch 'master'
}
failFast true
parallel {
stage('Branch A') {
agent {
label "for-branch-a"
}
steps {
echo "On Branch A"
}
}
stage('Branch B') {
agent {
label "for-branch-b"
}
steps {
echo "On Branch B"
}
}
}
}
}
}
步驟
聲明式流水線可能使用在 流水線步驟引用中記錄的所有可用的步驟, 它包含一個完整的步驟清單, 其中添加了下面列出的步驟,這些步驟隻在聲明式流水線中 only supported 。
腳本
script
步驟需要 [scripted-pipeline]塊并在聲明式流水線中執行。 對于大多數用例來說,應該聲明式流水線中的“腳本”步驟是不必要的, 但是它可以提供一個有用的"逃生出口"。 非平凡的規模和/或複雜性的
script
塊應該被轉移到 共享庫 。
示例
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Example') {
steps {
echo 'Hello World'
script {
def browsers = ['chrome', 'firefox']
for (int i = 0; i < browsers.size(); ++i) {
echo "Testing the ${browsers[i]} browser"
}
}
}
}
}
}
腳本化流水線
腳本化流水線, 與[declarative-pipeline]一樣的是, 是建立在底層流水線的子系統上的。與聲明式不同的是, 腳本化流水線實際上是由 Groovy建構的通用 DSL。 Groovy 語言提供的大部分功能都可以用于腳本化流水線的使用者。這意味着它是一個非常有表現力和靈活的工具,可以通過它編寫持續傳遞流水線。
流控制
腳本化流水線從
Jenkinsfile
的頂部開始向下串行執行, 就像 Groovy 或其他語言中的大多數傳統腳本一樣。 是以,提供流控制取決于 Groovy 表達式, 比如
if/else
條件, 例如:
Jenkinsfile (Scripted Pipeline)
node {
stage('Example') {
if (env.BRANCH_NAME == 'master') {
echo 'I only execute on the master branch'
} else {
echo 'I execute elsewhere'
}
}
}
另一種方法是使用Groovy的異常處理支援來管理腳本化流水線流控制。當 步驟 失敗 ,無論什麼原因,它們都會抛出一個異常。處理錯誤的行為必須使用Groovy中的
try/catch/finally
塊 , 例如:
Jenkinsfile (Scripted Pipeline)
node {
stage('Example') {
try {
sh 'exit 1'
}
catch (exc) {
echo 'Something failed, I should sound the klaxons!'
throw
}
}
}
步驟
正如 本章開始所讨論的, 流水線最基礎的部分是"步驟"。從根本上說, 步驟告訴 Jenkins要做 what ,并作為聲明式和腳本化流水線已發的基本建構塊。
腳本化流水線 not 不引入任何特定于其文法的步驟; 流水線步驟引用 包括流水線和插件提供的步驟的完整清單。
差別普通 Groovy
為了提供 durability, 這意味着運作流水線可以在Jenkins master 重新開機後繼續運作,腳本化的流水順序列化資料到主伺服器。由于這個設計需求, 一些Groovy 習慣用語,比如
collection.each { item -> }
都不完全支援。詳情參見 JENKINS-27421 和 JENKINS-26481。
文法比較
當Jenkins 流水線第一次建構時, Groovy 被選為基礎。 Jenkins長期使用嵌入式 Groovy引擎來為管理者和使用者提供 進階腳本功能。另外, Jenkins流水線的實作者發現 Groovy是 建構現在成為 “腳本化流水線” DSL的堅實基礎 [2]。
由于它是一個功能齊全的程式設計環境, 腳本化流水線為Jenkins使用者提供了 大量的靈活性性和可擴充性。 Groovy學習曲線通常不适合給定團隊的所有成員, 是以創造了聲明式流水線來為編寫Jenkins流水線提供一種更簡單、更有主見的文法。
兩者本質上是相同的流水線子系統。 underneath. 他們都是 “流水線即代碼” 的持久實作。它們都能夠使用建構到流水線中或插件提供的步驟。它們都能夠使用 共享庫
但是它們的差別在于文法和靈活性。 聲明式限制了使用者使用更嚴格和預定義的結構, 使其成為更簡單的持續傳遞流水線的理想選擇。 腳本化提供了很少的限制, 以至于對腳本和文法的唯一限制往往是由Groovy子集本身定義的,而不是任何特定于流水線的系統, 這使他成為權利使用者和那些有更複雜需求的人的理想選擇。 顧名思義, 聲明式流水線鼓勵 聲明式程式設計模型。 而腳本化流水線遵循一個更指令式的程式設計模型 。
三、使用 Jenkinsfile
本節基于 流水線入門 所涵蓋的資訊,介紹更多有用的步驟、常見的模式,并且示範
Jenkinsfile
的一些特例。
建立一個檢入到源碼管理系統中的
Jenkinsfile
帶來了一些直接的好處:
- 流水線上的代碼評審/疊代
- 對流水線進行審計跟蹤
- 流水線的單一可信資料源,能夠被項目的多個成員檢視和編輯。
流水線支援 兩種文法:聲明式(在 Pipeline 2.5 引入)和腳本式流水線。 兩種文法都支援建構持續傳遞流水線。兩種都可以用來在 web UI 或
Jenkinsfile
中定義流水線,不過通常認為建立一個
Jenkinsfile
并将其檢入源代碼控制倉庫是最佳實踐。
建立 Jenkinsfile
正如 在 SCM 中定義流水線中所讨論的,
Jenkinsfile
是一個文本檔案,它包含了 Jenkins 流水線的定義并被檢入源代碼控制倉庫。下面的流水線實作了基本的三階段持續傳遞流水線。
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Build') {
steps {
echo 'Building..'
}
}
stage('Test') {
steps {
echo 'Testing..'
}
}
stage('Deploy') {
steps {
echo 'Deploying....'
}
}
}
}
Toggle Scripted Pipeline (Advanced)
不是所有的流水線都有相同的三個階段,但為大多數項目定義這些階段是一個很好的開始。下面這一節将在 Jenkins 的測試安裝中示範一個簡單流水線的建立和執行。
假設已經為項目設定了一個源代碼控制倉庫并在 Jenkins 下的 these instructions中定義了一個流水線。 |
---|
使用文本編輯器,最好支援 Groovy 文法高亮,在項目的根目錄下建立一個
Jenkinsfile
。
上面的聲明式流水線示例包含了實作持續傳遞流水線的最小必要結構。agent指令是必需的,它訓示 Jenkins 為流水線配置設定一個執行器和工作區。沒有
agent
指令的話,聲明式流水線不僅無效,它也不可能完成任何工作!預設情況下,
agent
指令確定源代碼倉庫被檢出并在後續階段的步驟中可被使用。
一個合法的聲明式流水線還需要 stages 指令和 steps 指令,因為它們訓示 Jenkins 要執行什麼,在哪個階段執行。
想要使用腳本式流水線的更進階用法,上面例子中的
node
是關鍵的第一步,因為它為流水線配置設定了一個執行者和工作區。實際上,沒有
node
,流水線無法工作!在
node
内,業務的第一步是檢出這個項目的源代碼。由于
Jenkinsfile
已經從源代碼控制中直接拉取出來,流水線提供了一個快速且簡單的方式來通路正确的源代碼修訂版本。
Jenkinsfile (Scripted Pipeline)
node {
checkout scm 1
/* .. snip .. */
}
1 | 步驟将會從源代碼控制中檢出代碼; 是一個特殊的變量, 它訓示 步驟克隆觸發流水線運作的特定修訂版本。 |
---|---|
建構
對于許多項目來說,流水線“工作”的開始就是“建構”階段。通常流水線的這個階段包括源代碼的組裝、編譯或打包。
Jenkinsfile
檔案不能替代現有的建構工具,如 GNU/Make、Maven、Gradle 等,而應視其為一個将項目的開發生命周期的多個階段(建構、測試、部署等)綁定在一起的粘合層。
Jenkins 有許多插件可以用于調用幾乎所有常用的建構工具,不過這個例子隻是從 shell 步驟(
sh
)調用
make
。
sh
步驟假設系統是基于 Unix/Linux 的,對于基于 Windows 的系統可以使用
bat
替代。
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'make' 1
archiveArtifacts artifacts: '**/target/*.jar', fingerprint: true 2
}
}
}
}
Toggle Scripted Pipeline (Advanced)
1 | 步驟調用 指令,隻有指令傳回的狀态碼為零時才會繼續。任何非零的傳回碼都将使流水線失敗。 |
---|---|
2 | 捕獲符合模式( )比對的傳遞件并将其儲存到 Jenkins master 節點以供後續擷取。 |
制品歸檔不能替代外部制品庫(例如 Artifactory 或 Nexus),而隻應當認為用于基本報告和檔案存檔。 |
---|
測試
運作自動化測試是任何成功的持續傳遞過程的重要組成部分。是以,Jenkins 有許多測試記錄,報告和可視化工具,這些都是由各種插件提供的。最基本的,當測試失敗時,讓 Jenkins 記錄這些失敗以供彙報以及在 web UI 中可視化是很有用的。下面的例子使用由 JUnit 插件提供的
junit
步驟。
在下面的例子中,如果測試失敗,流水線就會被标記為“不穩定”,這通過 web UI 中的黃色球表示。基于測試報告的記錄,Jenkins 還可以提供曆史趨勢分析和可視化。
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Test') {
steps {
/* `make check` 在測試失敗後傳回非零的退出碼;
* 使用 `true` 允許流水線繼續進行
*/
sh 'make check || true' 1
junit '**/target/*.xml' 2
}
}
}
}
Toggle Scripted Pipeline (Advanced)
1 | 使用内聯的 shell 條件( )確定 步驟總是看到退出碼是零,使 步驟有機會捕獲和處理測試報告。在下面處理故障一節中,對它的替代方法有更詳細的介紹。 |
---|---|
2 | 捕獲并關聯與包含模式( )比對的 JUnit XML 檔案。 |
部署
部署可以隐含許多步驟,這取決于項目或組織的要求,并且可能是從釋出建構的傳遞件到 Artifactory 伺服器,到将代碼推送到生産系統的任何東西。 在示例流水線的這個階段,“Build(建構)” 和 “Test(測試)” 階段都已成功執行。從本質上講,“Deploy(部署)” 階段隻有在之前的階段都成功完成後才會進行,否則流水線會提前退出。
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Deploy') {
when {
expression {
currentBuild.result == null || currentBuild.result == 'SUCCESS' 1
}
}
steps {
sh 'make publish'
}
}
}
}
Toggle Scripted Pipeline (Advanced)
1 | 流水線通路 變量确定是否有任何測試的失敗。在這種情況下,值為 。 |
---|---|
假設在示例的 Jenkins 流水線中所有的操作都執行成功,那麼每次流水線的成功運作都會在 Jenkins 中存檔相關的傳遞件、上面報告的測試結果以及所有控制台輸出。
腳本式流水線包含條件測試(如上所示),循環,try/catch/finally 塊甚至函數。下一節将會詳細的介紹這個進階的腳本式流水線文法。
使用 Jenkinsfile 工作
接下來的章節提供了處理以下事項的細節:
-
中的流水線特有文法Jenkinsfile
- 流水線文法的特性和功能,這對于建構應用程式或流水線項目非常重要。
字元串插值
Jenkins 使用與 Groovy 相同的規則進行字元串插值。 Groovy 的字元串插值支援可能會使很多新手感到困惑。盡管 Groovy 支援使用單引号或雙引号聲明一個字元串,例如:
def singlyQuoted = 'Hello'
def doublyQuoted = "World"
隻有後面的字元串才支援基于美元符(
$
)的字元串插值,例如:
def username = 'Jenkins'
echo 'Hello Mr. ${username}'
echo "I said, Hello Mr. ${username}"
其結果是:
Hello Mr. ${username}
I said, Hello Mr. Jenkins
了解如何使用字元串插值對于使用一些流水線的更進階特性是至關重要的。
使用環境變量
Jenkins 流水線通過全局變量
env
提供環境變量,它在
Jenkinsfile
檔案的任何地方都可以使用。Jenkins 流水線中可通路的完整的環境變量清單記錄在
${YOUR_JENKINS_URL}/pipeline-syntax/globals#env
,并且包括:
-
BUILD_ID
目前建構的 ID,與 Jenkins 版本 1.597+ 中建立的建構号 BUILD_NUMBER 是完全相同的。
-
BUILD_NUMBER
目前建構号,比如 “153”。
-
BUILD_TAG
字元串
。可以放到源代碼、jar 等檔案中便于識别。jenkins-${JOB_NAME}-${BUILD_NUMBER}
-
BUILD_URL
可以定位此次建構結果的 URL(比如 http://buildserver/jenkins/job/MyJobName/17/ )
-
EXECUTOR_NUMBER
用于識别執行目前建構的執行者的唯一編号(在同一台機器的所有執行者中)。這個就是你在“建構執行狀态”中看到的編号,隻不過編号從 0 開始,而不是 1。
-
JAVA_HOME
如果你的任務配置了使用特定的一個 JDK,那麼這個變量就被設定為此 JDK 的 JAVA_HOME。當設定了此變量時,PATH 也将包括 JAVA_HOME 的 bin 子目錄。
-
JENKINS_URL
Jenkins 伺服器的完整 URL,比如 https://example.com:port/jenkins/ (注意:隻有在“系統設定”中設定了 Jenkins URL 才可用)。
-
JOB_NAME
本次建構的項目名稱,如 “foo” 或 “foo/bar”。
-
NODE_NAME
運作本次建構的節點名稱。對于 master 節點則為 “master”。
-
WORKSPACE
workspace 的絕對路徑。
引用或使用這些環境變量就像通路 Groovy Map 的 key 一樣, 例如:
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Example') {
steps {
echo "Running ${env.BUILD_ID} on ${env.JENKINS_URL}"
}
}
}
}
Toggle Scripted Pipeline (Advanced)
設定環境變量
在 Jenkins 流水線中,取決于使用的是聲明式還是腳本式流水線,設定環境變量的方法不同。
聲明式流水線支援 environment 指令,而腳本式流水線的使用者必須使用
withEnv
步驟。
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
environment { 1
CC = 'clang'
}
stages {
stage('Example') {
environment { 2
DEBUG_FLAGS = '-g'
}
steps {
sh 'printenv'
}
}
}
}
Toggle Scripted Pipeline (Advanced)
1 | 用在最高層的 塊的 指令适用于流水線的所有步驟。 |
---|---|
2 | 定義在 中的 指令隻适用于 中的步驟。 |
動态設定環境變量
環境變量可以在運作時設定,然後給 shell 腳本(
sh
)、Windows 批處理腳本(
batch
)和 Powershell 腳本(
powershell
)使用。各種腳本都可以傳回
returnStatus
或
returnStdout
。
下面是一個使用
sh
(shell)的聲明式腳本的例子,既有
returnStatus
也有
returnStdout
:
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any 1
environment {
// 使用 returnStdout
CC = """${sh(
returnStdout: true,
script: 'echo "clang"'
)}""" 2
// 使用 returnStatus
EXIT_STATUS = """${sh(
returnStatus: true,
script: 'exit 1'
)}"""
}
stages {
stage('Example') {
environment {
DEBUG_FLAGS = '-g'
}
steps {
sh 'printenv'
}
}
}
}
1 | 必須設定在流水線的最進階。如果設定為 會失敗。 |
---|---|
2 | 使用 時,傳回的字元串末尾會追加一個空格。可以使用 将其移除。 |
處理憑據
Jenkins 中配置的憑據可以在流水線中處理以便于立即使用。請前往 使用憑據頁面閱讀更多關于在 Jenkins 中使用憑據的資訊。
Secret 文本,帶密碼的使用者名,Secret 檔案
Jenkins 的聲明式流水線文法有一個
credentials()
輔助方法(在
environment
指令中使用),它支援 secret 文本,帶密碼的使用者名,以及 secret 檔案憑據。如果你想處理其他類型的憑據,請參考其他憑據類型一節(見下)。
Secret 文本
下面的流水線代碼示範了如何使用環境變量為 secret 文本憑據建立流水線的示例。
在該示例中,将兩個 secret 文本憑據賦予各自的環境變量來通路 Amazon Web 服務(AWS)。這些憑據已在 Jenkins 中配置了各自的憑據 ID
jenkins-aws-secret-key-id
和
jenkins-aws-secret-access-key
。
Jenkinsfile (Declarative Pipeline)
pipeline {
agent {
// 此處定義 agent 的細節
}
environment {
AWS_ACCESS_KEY_ID = credentials('jenkins-aws-secret-key-id')
AWS_SECRET_ACCESS_KEY = credentials('jenkins-aws-secret-access-key')
}
stages {
stage('Example stage 1') {
steps {
// 1
}
}
stage('Example stage 2') {
steps {
// 2
}
}
}
}
1 | 你可以在該階段的步驟中用文法 和 來引用兩個憑據環境變量(定義在流水線的 指令中)。比如,在這裡,你可以使用配置設定給這些憑據變量的 secret 文本憑據對 AWS 進行身份驗證。 為了保持這些憑據的安全性和匿名性,如果任務試圖從流水線中顯示這些憑據變量的值(如 ),Jenkins 隻會傳回 “” 來降低機密資訊被寫到控制台輸出和任何日志中的風險。憑據 ID 本身的任何敏感資訊(如使用者名)也會以 “” 的形式傳回到流水線運作的輸出中。 這隻能降低意外暴露的風險。它無法阻止惡意使用者通過其他方式擷取憑據的值。使用憑據的流水線也可能洩漏這些憑據。不要允許不受信任的流水線任務使用受信任的憑據。 |
---|---|
2 | 在該流水線示例中,配置設定給兩個 環境變量的憑據在整個流水線的全局範圍内都可通路,是以這些憑據變量也可以用于該階段的步驟中。然而,如果流水線中的 指令被移動到一個特定的階段(比如下面的 帶密碼的使用者名流水線示例),那麼這些 環境變量就隻能作用于該階段的步驟中。 |
帶密碼的使用者名
下面的流水線代碼片段展示了如何建立一個使用帶密碼的使用者名憑據的環境變量的流水線。
在該示例中,帶密碼的使用者名憑據被配置設定了環境變量,用來使你的組織或團隊以一個公用賬戶通路 Bitbucket 倉庫;這些憑據已在 Jenkins 中配置了憑據 ID
jenkins-bitbucket-common-creds
。
當在
environment
指令中設定憑據環境變量時:
environment {
BITBUCKET_COMMON_CREDS = credentials('jenkins-bitbucket-common-creds')
}
這實際設定了下面的三個環境變量:
-
- 包含一個以冒号分隔的使用者名和密碼,格式為BITBUCKET_COMMON_CREDS
。username:password
-
- 附加的一個僅包含使用者名部分的變量。BITBUCKET_COMMON_CREDS_USR
-
- 附加的一個僅包含密碼部分的變量。BITBUCKET_COMMON_CREDS_PSW
按照慣例,環境變量的變量名通常以大寫字母中指定,每個單詞用下劃線分割。 但是,你可以使用小寫字母指定任何合法的變量名。請記住, 方法(見上)所建立的附加環境變量總是會有字尾 和 (即以下劃線後跟三個大寫字母的格式)。 |
---|
下面的代碼片段完整的展示了示例流水線:
Jenkinsfile (Declarative Pipeline)
pipeline {
agent {
// 此處定義 agent 的細節
}
stages {
stage('Example stage 1') {
environment {
BITBUCKET_COMMON_CREDS = credentials('jenkins-bitbucket-common-creds')
}
steps {
// 1
}
}
stage('Example stage 2') {
steps {
// 2
}
}
}
}
1 | 下面的憑據環境變量(定義在流水線的 指令中)可以在該階段的步驟中使用,并且可以使用下面的文法引用: 比如,在這裡你可以使用配置設定給這些憑據變量的使用者名和密碼向 Bitbucket 驗證身份。 為了維護這些憑據的安全性和匿名性,如果任務試圖從流水線中顯示這些憑據變量的值,那麼上面的 Secret 文本 描述的行為也同樣适用于這些帶密碼的使用者名憑據變量類型。 同樣,這隻能降低意外暴露的風險。它無法阻止惡意使用者通過其他方式擷取憑據的值。使用憑據的流水線也可能洩漏這些憑據。不要允許不受信任的流水線任務使用受信任的憑據。 |
---|---|
2 | 在該流水線示例中,配置設定給三個 環境變量的憑據僅作用于 ,是以在 階段的步驟中這些憑據變量不可用。然而,如果馬上把流水線中的 指令移動到 塊中(正如上面的 Secret 文本流水線示例一樣),這些 環境變量将應用于全局并可以在任何階段的任何步驟中使用。 |
Secret 檔案
就流水線而言,secret 檔案的處理方式與 Secret 文本 完全相同。
實際上,secret 文本和 secret 檔案憑據之間的唯一不同是,對于 secret 文本,憑據本身直接輸入到 Jenkins 中,而 secret 檔案的憑據則原樣儲存到一個檔案中,之後将傳到 Jenkins。
與 secret 文本不同的是,secret 檔案适合:
- 太笨拙而不能直接輸入 Jenkins
- 二進制格式,比如 GPG 檔案
其他憑據類型
如果你需要在流水線中設定除了 secret 文本、帶密碼的使用者名、secret 檔案(見上)以外的其他憑據——即 SSH 秘鑰或證書,那麼請使用 Jenkins 的片段生成器特性,你可以通過 Jenkins 的經典 UI 通路它。
要從你的流水線項目通路片段生成器:
- 從 Jenkins 首頁(即 Jenkins 的經典 UI 工作台)點選流水線項目的名字。
- 在左側,點選流水線文法并確定 Snippet Generator/片段生成器的連結在右上角粗體顯示(如果沒有,點選它的連結)。
- 從示例步驟字段中,選擇 withCredentials: Bind credentials to variables。
- 在綁定下面,點選新增并從下拉框中選擇:
- SSH User Private Key - 要處理 SSH 公私鑰對憑據,你可以提供:
- Key 檔案變量 - 将要綁定到這些憑據的環境變量的名稱。Jenkins 實際上将此臨時變量配置設定給 SSH 公私鑰對身份驗證過程中所需的私鑰檔案的安全位置。
- 密碼變量(可選)- 将要被綁定到與 SSH 公私鑰對相關的 密碼 的環境變量的名稱。
- 使用者名變量(可選)- 将要綁定到與 SSH 公私鑰對相關的使用者名的環境變量的名稱。
- 憑據 - 選擇存儲在 Jenkins 中的 SSH 公私鑰對證書。該字段的值是憑據 ID,Jenkins 将其寫入生成的代碼片段中。
- Certificate - 要處理 PKCS#12 證書,你可以提供:
- 密鑰庫變量 - 将要綁定到這些憑據的環境變量的名稱。Jenkins 實際上将這個臨時變量配置設定給要求進行身份驗證的證書密鑰庫的安全位置。
- 密碼變量(可選) - 将會被綁定到與證書相關的密碼的環境變量的名稱。
- 别名變量(可選) - 将會被綁定到與證書相關的唯一别名的環境變量的名稱。
- 憑據 - 選擇存儲在 Jenkins 中的證書。該字段的值是憑據 ID,Jenkins 将其寫入生成的代碼片段中。
- Docker client certificate - 用于處理 Docker 主機證書的身份驗證。
- SSH User Private Key - 要處理 SSH 公私鑰對憑據,你可以提供:
- 點選 生成流水線腳本,Jenkins 會為你指定的憑據生成一個
withCredentials( ... ) { ... }
的流水線步驟片段,你可以将其複制并粘貼到你的聲明式或腳本化流水線代碼中。
注意:
- 憑據 字段(見上)顯示的是 Jenkins 中配置的證書的名稱。然而,這些值在點選 生成流水線腳本 之後會被轉換成證書 ID。
- 要在一個
流水線步驟組合多個證書,請檢視 在一個步驟中組合使用憑據(見下)的詳細資訊。withCredentials( ... ) { ... }
SSH User Private Key 示例
withCredentials(bindings: [sshUserPrivateKey(credentialsId: 'jenkins-ssh-key-for-abc', \
keyFileVariable: 'SSH_KEY_FOR_ABC', \
passphraseVariable: '', \
usernameVariable: '')]) {
// some block
}
可選的
passphraseVariable
和
usernameVariable
定義可以在最終的流水線代碼中删除。
Certificate 示例
withCredentials(bindings: [certificate(aliasVariable: '', \
credentialsId: 'jenkins-certificate-for-xyz', \
keystoreVariable: 'CERTIFICATE_FOR_XYZ', \
passwordVariable: 'XYZ-CERTIFICATE-PASSWORD')]) {
// some block
}
可選的
aliasVariable
和
passwordVariable
變量定義可以在最終的流水線代碼中删除。
下面的代碼片段展示了一個完整的示例流水線,實作了上面的 SSH User Private Key 和 Certificate 片段:
Jenkinsfile (Declarative Pipeline)
pipeline {
agent {
// define agent details
}
stages {
stage('Example stage 1') {
steps {
withCredentials(bindings: [sshUserPrivateKey(credentialsId: 'jenkins-ssh-key-for-abc', \
keyFileVariable: 'SSH_KEY_FOR_ABC')]) {
// 1
}
withCredentials(bindings: [certificate(credentialsId: 'jenkins-certificate-for-xyz', \
keystoreVariable: 'CERTIFICATE_FOR_XYZ', \
passwordVariable: 'XYZ-CERTIFICATE-PASSWORD')]) {
// 2
}
}
}
stage('Example stage 2') {
steps {
// 3
}
}
}
}
1 | 在該步驟中,你可以使用文法 引用憑據環境變量。比如,在這裡你可以使用配置的 SSH 公私鑰對證書對 ABC 應用程式進行身份驗證,它的 SSH User Private Key 檔案被配置設定給 。 |
---|---|
2 | 在該步驟中,你可以使用文法 和 引用憑據環境變量。比如,在這裡你可以使用配置的證書憑據對 XYZ 應用程式進行身份驗證。證書 Certificate 的秘鑰存儲檔案和密碼分别被配置設定給 和 變量。 |
3 | 在流水線示例中,配置設定給 、 和 的環境變量的憑據隻适用于它們各自 步驟中,是以這些憑據變量在 階段的步驟中不可用。 |
為了維護這些證書的安全性和匿名性,如果你試圖從
withCredentials( ... ) { ... }
步驟中檢索這些憑據變量的值,在 Secret 文本 示例(見上)中的相同行為也适用于這些 SSH 公私鑰對證書和憑據變量類型。
在 片段生成器 的示例步驟中使用 withCredentials: Bind credentials to variables 選項時,隻有目前流水線項目有通路權限的憑據才可以從憑據字段中選擇。 雖然你可以為你的流水線手動編寫 步驟( 如上所示),但更建議使用 片段生成器 來防止指定超出該流水線通路範圍的證書,可以避免運作步驟時失敗。你也可以用 片段生成器 來生成處理 secret 文本,帶密碼的使用者名以及 secret 檔案的 步驟。但是,如果你隻需要處理這些類型的證書的話,為了提高你流水線代碼的可讀性,更建議你使用在上面一節中描述的相關過程。在 Groovy 中使用單引号而不是雙引号來定義腳本( 的隐式參數)。單引号将使 secret 被 shell 作為環境變量展開。雙引号可能不太安全,因為這個 secret 是由 Groovy 插入的,是以一般作業系統的程序清單(以及 Blue Ocean 和經典 UI 中的流水線步驟樹)會意外地暴露它: |
---|
在一個步驟中組合使用憑據
使用 片段生成器,你可以在單個
withCredentials( ... ) { ... }
步驟中提供多個可用憑據,操作如下:
- 從 Jenkins 的首頁中(即 Jenkins 的經典 UI 工作台)點選流水線項目的名稱。
- 在左側,點選 流水線文法 確定片段生成器連結在左上加粗顯示(如果沒有,點選該連結)。
- 從 示例步驟 字段,選擇 withCredentials: Bind credentials to variables。
- 點選 綁定 下的 新增。
- 從下拉清單中選擇要添加到
步驟的憑據類型。withCredentials( ... ) { ... }
- 指定憑據綁定的細節。請在操作過程中閱讀其他憑據類型。
- 重複“點選 新增 …”将每個(組)憑據添加到
步驟。withCredentials( ... ) { ... }
- 點選 生成流水線腳本 生成最終的
步驟片段。withCredentials( ... ) { ... }
處理參數
聲明式流水線支援參數開箱即用,允許流水線在運作時通過parameters 指令接受使用者指定的參數。配置腳本式流水線的參數是通過
properties
步驟實作的,可以在代碼生成器中找到。
如果你使用 Build with Parameters 選項将流水線配置為接受參數,這些參數将作為
params
變量的成員被通路。
假設在
Jenkinsfile
中配置了名為 “Greeting” 的字元串參數,它可以通過
${params.Greeting}
通路該參數:
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
parameters {
string(name: 'Greeting', defaultValue: 'Hello', description: 'How should I greet the world?')
}
stages {
stage('Example') {
steps {
echo "${params.Greeting} World!"
}
}
}
}
Toggle Scripted Pipeline (Advanced)
處理故障
聲明式流水線預設通過 post 節段支援強大的故障處理,它允許聲明許多不同的 “post 條件”,比如:
always
、
unstable
、
success
、
failure
和
changed
。流水線文法 提供了關于如何使用各種 post 條件的更多細節。
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Test') {
steps {
sh 'make check'
}
}
}
post {
always {
junit '**/target/*.xml'
}
failure {
mail to: [email protected], subject: 'The Pipeline failed :('
}
}
}
Toggle Scripted Pipeline (Advanced)
然而腳本化的流水線依賴于 Groovy 的内置的
try
/
catch
/
finally
語義來處理流水線運作期間的故障。
在上面的測試示例中,
sh
步驟被修改為永遠不會傳回非零的退出碼(
sh 'make check || true'
)。雖然這種方法合法,但意味着接下來的階段需要檢查
currentBuild.result
來了解測試是否失敗。
該問題的另一種處理方式是使用一系列的
try
/
finally
塊,它保留了流水線中前面的失敗退出的行為,但仍然給了
junit
捕獲測試報告的機會。
使用多個代理
在之前所有的示例中都隻使用了一個代理。這意味着 Jenkins 會配置設定一個可用的執行者而無論該執行者是如何打标簽或配置的。流水線不僅可以覆寫這種行為,還允許在 Jenkins 環境中使用 同一個
Jenkinsfile
中的多個代理,這将有助于更進階的用例,例如跨多個平台的執行建構/測試。
在下面的示例中,“Build” 階段将會在一個代理中執行,并且建構結果将會在後續的 “Test” 階段被兩個分别标記為 “linux” 和 “windows” 的代理重用。
Jenkinsfile (Declarative Pipeline)
pipeline {
agent none
stages {
stage('Build') {
agent any
steps {
checkout scm
sh 'make'
stash includes: '**/target/*.jar', name: 'app' 1
}
}
stage('Test on Linux') {
agent { 2
label 'linux'
}
steps {
unstash 'app' 3
sh 'make check'
}
post {
always {
junit '**/target/*.xml'
}
}
}
stage('Test on Windows') {
agent {
label 'windows'
}
steps {
unstash 'app'
bat 'make check' 4
}
post {
always {
junit '**/target/*.xml'
}
}
}
}
}
Toggle Scripted Pipeline (Advanced)
1 | 步驟允許捕獲與包含模式( )比對的檔案,以便在同一個流水線中重用。一旦流水線執行完成,就會從 Jenkins master 中删除暫存檔案。 |
---|---|
2 | / 中的參數允許使用任何可用的 Jenkins 标簽表達式。參考 流水線文法 部分了解更多資訊。 |
3 | 将會從 Jenkins master 中取回命名的 “stash” 到流水線的目前工作區中。 |
4 | 腳本允許在基于 Windows 的平台上執行批處理腳本。 |
可選的步驟參數
流水線遵循 Groovy 語言允許在方法周圍省略括号的慣例。
許多流水線步驟也使用命名參數文法作為在 Groovy 中建立的 Map(使用文法
[key1: value1, key2: value2]
)的簡寫 。下面的語句有着相同的功能:
git url: 'git://example.com/amazing-project.git', branch: 'master'
git([url: 'git://example.com/amazing-project.git', branch: 'master'])
為了友善,當調用隻有一個參數的步驟時(或僅一個強制參數),參數名稱可以省略,例如:
sh 'echo hello' /* short form */
sh([script: 'echo hello']) /* long form */
進階腳本式流水線
腳本式流水線是一種基于 Groovy 的領域特定語言 [3] ,大多數 Groovy 文法都可以無需修改,直接在腳本式流水線中使用。
并行執行
上面這節中的示例跨兩個不同的平台串聯地運作測試。在實踐中,如果執行
make check
需要30分鐘來完成,那麼 “Test” 階段就需要 60 分鐘來完成!
幸運的是,流水線有一個内置的并行執行部分腳本式流水線的功能,通過貼切的名為
parallel
的步驟實作。
使用
parallel
步驟重構上面的示例:
Jenkinsfile (Scripted Pipeline)
stage('Build') {
/* .. snip .. */
}
stage('Test') {
parallel linux: {
node('linux') {
checkout scm
try {
unstash 'app'
sh 'make check'
}
finally {
junit '**/target/*.xml'
}
}
},
windows: {
node('windows') {
/* .. snip .. */
}
}
}
測試不再在标記為 “linux” 和 “windows” 節點中串聯地執行,而是并行執行。