Jenkins 2.0的到來,pipline進入了視野,jenkins2.0的核心特性. 也是最適合持續交付的feature。html
簡單的來講,就是把Jenkins1.0版本中,Project中的相關配置信息,如SVN/Git的配置,Parameter的配置等都變成Code,即Pipeline as Code。java
隨着pipeline交付流水線在團隊中的推廣,使用pipeline腳本的job也迅速增長。node
優點:web
Pipeline最基本的部分是「step」。基本上,step告訴Jenkins 要作什麼,而且做爲Declarative Pipeline和Scripted Pipeline語法的基本構建塊。
Pipeline支持兩種語法:Declarative Pipeline(在Pipeline 2.5中引入,結構化方式)和Scripted Pipeline,二者都支持創建連續輸送的Pipeline。chrome
最開始的Pipeline plugin,支持的只有一種腳本類型,就是Scripted Pipeline;
Declarative Pipeline爲Pipeline plugin在2.5版本以後新增的一種腳本類型,與原先的Scripted Pipeline同樣,均可以用來編寫腳本。docker
相關資料:shell
https://stackoverflow.com/questions/43484979/jenkins-scripted-pipeline-or-declarative-pipeline
http://jenkins-ci.361315.n4.nabble.com/Declarative-pipelines-vs-scripted-td4891792.htmlexpress
從檢索的資料來看,Declarative Pipeline 是後續Open Blue Ocean所支持的類型。相對而言,Declarative Pipeline比較簡單,Declarative Pipeline中,也是能夠內嵌Scripted Pipeline代碼的。apache
爲與BlueOcean腳本編輯器兼容,一般建議使用Declarative Pipeline的方式進行編寫,從jenkins社區的動向來看,很明顯這種語法結構也會是將來的趨勢。maven
Declarative Pipeline是Jenkins Pipeline 的一個相對較新的補充, 它在Pipeline子系統之上提出了一種更爲簡化和有意義的語法。
全部有效的Declarative Pipeline必須包含在一個pipeline塊內,例如:
pipeline { /* insert Declarative Pipeline here */ }
Declarative Pipeline中的基本語句和表達式遵循與Groovy語法相同的規則 ,但有如下例外:
Declarative Pipeline裏的Sections一般包含一個或多個Directives或 Steps
agent部分指定整個Pipeline或特定階段將在Jenkins環境中執行的位置,具體取決於該agent 部分的放置位置。該部分必須在pipeline塊內的頂層定義 ,但stage級使用是可選的。
在任何可用的agent 上執行Pipeline或stage。例如:agent any
none
當在pipeline塊的頂層使用none時,將不會爲整個Pipeline運行分配全局agent ,每一個stage部分將須要包含其本身的agent部分。
label
使用提供的label標籤,在Jenkins環境中可用的代理上執行Pipeline或stage。例如:agent { label 'my-defined-label' }
node
agent { node { label 'labelName' } },等同於 agent { label 'labelName' },但node容許其餘選項(如customWorkspace)。
docker
定義此參數時,執行Pipeline或stage時會動態供應一個docker節點去接受Docker-based的Pipelines。 docker還能夠接受一個args,直接傳遞給docker run調用。例如:agent { docker 'maven:3-alpine' }或
docker agent { docker { image 'maven:3-alpine' label 'my-defined-label' args '-v /tmp:/tmp' } }
dockerfile
使用從Dockerfile源存儲庫中包含的容器來構建執行Pipeline或stage 。爲了使用此選項,Jenkinsfile必須從Multibranch Pipeline或「Pipeline from SCM"加載。
默認是在Dockerfile源庫的根目錄:agent { dockerfile true }。若是Dockerfile需在另外一個目錄中創建,請使用如下dir選項:agent { dockerfile { dir 'someSubDir' } }。您能夠經過docker build ...使用additionalBuildArgs選項,如agent { dockerfile { additionalBuildArgs '--build-arg foo=bar' } }。
參數
any
在任何可用的agent 上執行Pipeline或stage。例如:agent any
none
當在pipeline塊的頂層使用none時,將不會爲整個Pipeline運行分配全局agent ,每一個stage部分將須要包含其本身的agent部分。
label
使用提供的label標籤,在Jenkins環境中可用的代理上執行Pipeline或stage。例如:agent { label 'my-defined-label' }
node
agent { node { label 'labelName' } },等同於 agent { label 'labelName' },但node容許其餘選項(如customWorkspace)。
docker
定義此參數時,執行Pipeline或stage時會動態供應一個docker節點去接受Docker-based的Pipelines。 docker還能夠接受一個args,直接傳遞給docker run調用。例如:agent { docker 'maven:3-alpine' }或
docker agent { docker { image 'maven:3-alpine' label 'my-defined-label' args '-v /tmp:/tmp' } }
dockerfile
使用從Dockerfile源存儲庫中包含的容器來構建執行Pipeline或stage 。爲了使用此選項,Jenkinsfile必須從Multibranch Pipeline或「Pipeline from SCM"加載。
默認是在Dockerfile源庫的根目錄:agent { dockerfile true }。若是Dockerfile需在另外一個目錄中創建,請使用如下dir選項:agent { dockerfile { dir 'someSubDir' } }。您能夠經過docker build ...使用additionalBuildArgs選項,如agent { dockerfile { additionalBuildArgs '--build-arg foo=bar' } }。
這些是能夠應用於兩個或多個agent的選項。除非明肯定義,不然不須要。
label
一個字符串。標記在哪裏運行pipeline或stage
此選項適用於node,docker和dockerfile,而且 node是必需的。
customWorkspace
一個字符串。自定義運行的工做空間內。它能夠是相對路徑,在這種狀況下,自定義工做區將位於節點上的工做空間根目錄下,也能夠是絕對路徑。例如:
agent { node { label 'my-defined-label' customWorkspace '/some/other/path' } }
reuseNode
一個布爾值,默認爲false。若是爲true,則在同一工做空間中。
此選項適用於docker和dockerfile,而且僅在 individual stage中使用agent纔有效。
pipeline { //Execute all the steps defined in this Pipeline within a newly created container of the given name and tag (maven:3-alpine). agent { docker 'maven:3-alpine' } stages { stage('Example Build') { steps { sh 'mvn -B clean verify' } } } }
pipeline { agent none stages { stage('Example Build') { agent { docker 'maven:3-alpine' } steps { echo 'Hello, Maven' sh 'mvn --version' } } stage('Example Test') { agent { docker 'openjdk:8-jre' } steps { echo 'Hello, JDK' sh 'java -version' } } } }
定義Pipeline或stage運行結束時的操做。post-condition塊支持post部件:always,changed,failure,success,unstable,和aborted。這些塊容許在Pipeline或stage運行結束時執行步驟,具體取決於Pipeline的狀態。
conditions項:
always
運行,不管Pipeline運行的完成狀態如何。
changed
只有當前Pipeline運行的狀態與先前完成的Pipeline的狀態不一樣時,才能運行。
failure
僅噹噹前Pipeline處於「失敗」狀態時才運行,一般在Web UI中用紅色指示表示。
success
僅噹噹前Pipeline具備「成功」狀態時才運行,一般在具備藍色或綠色指示的Web UI中表示。
unstable
只有當前Pipeline具備「不穩定」狀態,一般由測試失敗,代碼違例等引發,才能運行。一般在具備黃色指示的Web UI中表示。
aborted
只有當前Pipeline處於「停止」狀態時,纔會運行,一般是因爲Pipeline被手動停止。一般在具備灰色指示的Web UI中表示。
pipeline { agent any stages { stage('Example') { steps { echo 'Hello World' } } } post { always { echo 'I will always say Hello again!' } } }
包含一個或多個stage的序列,Pipeline的大部分工做在此執行。建議stages至少包含至少一個stage指令,用於鏈接各個交付過程,如構建,測試和部署等。
steps包含一個或多個在stage塊中執行的step序列。
pipeline { agent any stages { stage('Example') { steps { echo 'Hello World' } } } }
environment指令指定一系列鍵值對,這些鍵值對將被定義爲全部step或stage-specific step的環境變量,具體取決於environment指令在Pipeline中的位置。
該指令支持一種特殊的方法credentials(),能夠經過其在Jenkins環境中的標識符來訪問預約義的憑據。
對於類型爲「Secret Text」的憑據,該 credentials()方法將確保指定的環境變量包含Secret Text內容;對於「標準用戶名和密碼」類型的憑證,指定的環境變量將被設置爲username:password。
pipeline { agent any environment { CC = 'clang' } stages { stage('Example') { environment { AN_ACCESS_KEY = credentials('my-prefined-secret-text') } steps { sh 'printenv' } } } }
options指令容許在Pipeline自己內配置Pipeline專用選項。Pipeline自己提供了許多選項,例如buildDiscarder,但它們也可能由插件提供,例如 timestamps。
buildDiscarder
pipeline保持構建的最大個數。例如:options { buildDiscarder(logRotator(numToKeepStr: '1')) }
disableConcurrentBuilds
不容許並行執行Pipeline,可用於防止同時訪問共享資源等。例如:options { disableConcurrentBuilds() }
skipDefaultCheckout
默認跳過來自源代碼控制的代碼。例如:options { skipDefaultCheckout() }
skipStagesAfterUnstable
一旦構建狀態進入了「Unstable」狀態,就跳過此stage。例如:options { skipStagesAfterUnstable() }
timeout
設置Pipeline運行的超時時間。例如:options { timeout(time: 1, unit: 'HOURS') }
retry
失敗後,重試整個Pipeline的次數。例如:options { retry(3) }
timestamps
預約義由Pipeline生成的全部控制檯輸出時間。例如:options { timestamps() }
pipeline { agent any options { timeout(time: 1, unit: 'HOURS') } stages { stage('Example') { steps { echo 'Hello World' } } } }
parameters指令提供用戶在觸發Pipeline時的參數列表。這些參數值經過該params對象可用於Pipeline步驟,具體用法以下
可用參數
string
A parameter of a string type, for example: parameters { string(name: 'DEPLOY_ENV', defaultValue: 'staging', description: '') }
booleanParam
A boolean parameter, for example: parameters { booleanParam(name: 'DEBUG_BUILD', defaultValue: true, description: '') }
目前只支持[booleanParam, choice, credentials, file, text, password, run, string]這幾種參數類型,其餘高級參數化類型還需等待社區支持。
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}" } } } }
triggers指令定義了Pipeline自動化觸發的方式。對於與源代碼集成的Pipeline,如GitHub或BitBucket,triggers可能不須要基於webhook的集成也已經存在。目前只有兩個可用的觸發器:cron和pollSCM。
pipeline { agent any triggers { cron('H 4/* 0 0 1-5') } stages { stage('Example') { steps { echo 'Hello World' } } } }
stage指令在stages部分中,應包含stop部分,可選agent部分或其餘特定於stage的指令。實際上,Pipeline完成的全部實際工做都將包含在一個或多個stage指令中。
pipeline { agent any stages { stage('Example') { steps { echo 'Hello World' } } } }
經過tools可自動安裝工具,並放置環境變量到PATH。若是agent none,這將被忽略。
pipeline { agent any tools { //工具名稱必須在Jenkins 管理Jenkins → 全局工具配置中預配置。 maven 'apache-maven-3.0.1' } stages { stage('Example') { steps { sh 'mvn --version' } } } }
when指令容許Pipeline根據給定的條件肯定是否執行該階段。該when指令必須至少包含一個條件。若是when指令包含多個條件,則全部子條件必須爲stage執行返回true。這與子條件嵌套在一個allOf條件中相同(見下面的例子)。
更復雜的條件結構可以使用嵌套條件建:not,allOf或anyOf。嵌套條件能夠嵌套到任意深度。
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' } } } }
Declarative Pipeline近期新增了對並行嵌套stage的支持,對耗時長,相互不存在依賴的stage可使用此方式提高運行效率。除了parallel stage,單個parallel裏的多個step也可使用並行的方式運行。
pipeline { agent any stages { stage('Non-Parallel Stage') { steps { echo 'This stage will be executed first.' } } stage('Parallel Stage') { when { branch 'master' } 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" } } } } } }
Declarative Pipeline可使用 Pipeline Steps reference中的全部可用步驟 ,並附加如下僅在Declarative Pipeline中支持的步驟。
script步驟須要一個script Pipeline,並在Declarative Pipeline中執行。對於大多數用例,script在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" } } } } } }
Groovy腳本不必定適合全部使用者,所以jenkins建立了Declarative pipeline,爲編寫Jenkins管道提供了一種更簡單、更有主見的語法。可是不能否認,因爲腳本化的pipeline是基於groovy的一種DSL語言,因此與Declarative pipeline相比爲jenkins用戶提供了更巨大的靈活性和可擴展性。
pipeline腳本同其它腳本語言同樣,從上至下順序執行,它的流程控制取決於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' } } }
pipeline腳本流程控制的另外一種方式是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 } } }
pipeline最核心和基本的部分就是「step」,從根本上來講,steps做爲Declarative pipeline和Scripted pipeline語法的最基本的語句構建塊來告訴jenkins應該執行什麼操做。
Scripted pipeline沒有專門將steps做爲它的語法的一部分來介紹,可是在Pipeline Steps reference這篇文檔中對pipeline及其插件涉及的steps作了很詳細的介紹。若有須要可參考jenkins官網對該部分的介紹Pipeline Steps reference
因爲pipeline的一些個性化需求,好比在從新啓動jenkins後要求pipeline腳本仍然能夠運行,那麼pipeline腳本必須將相關數據作序列化,然而這一點 Groovy並不能完美的支持,例如collection.each { item -> /* perform operation */ }
共同點: 二者都是pipeline代碼的持久實現,都可以使用pipeline內置的插件或者插件提供的steps,二者均可以利用共享庫擴展。區別: 二者不一樣之處在於語法和靈活性。Declarative pipeline對用戶來講,語法更嚴格,有固定的組織結構,更容易生成代碼段,使其成爲用戶更理想的選擇。可是Scripted pipeline更加靈活,由於Groovy自己只能對結構和語法進行限制,對於更復雜的pipeline來講,用戶能夠根據本身的業務進行靈活的實現和擴展。