Jenkins中外掛 pipeline 中宣告式流水線的語法
阿新 • • 發佈:2021-07-07
- 宣告式流水線
- 指令碼化流水線
pipeline { agent any stages { stage('Example') { steps { echo 'Hello World' } } } }
指令碼化流水線
node { stage('Example') { if (env.BRANCH_NAME == 'master') { echo 'I only execute on the master branch' } else { echo 'I execute elsewhere' } } }
node('slave001') { 最外層必須是node節點,這裡單獨制定執行的jenkins節點,通常不用指定,由jenkins master分配任務即可。這種寫法屬於Scripted Pipeline。 stage('Prepare') {} stage是一個階段的語法,括號裡階段名稱。指令碼從node開始,按順序向下執行。遇到的第一個stage就是第一個階段。 使用echo xxxx來輸出文字,給出進度資訊。 checkout scm 是Jenkins固定獲取程式碼的方法,會輸出Check out from version control。 pom = readMavenPom file: 'location/pom.xml' 是讀取workspace下相對目錄的pom檔案。這個需要Jenkins 安裝Pipeline Utility Steps外掛。通過${pom.groupId}-${pom.artifactId}來獲取pom資訊. 我的pom在子module location裡。 docker_host = "docker.ryan-miao.com" 宣告一個全域性的變數,如果只想在方法體 {}中使用,可以加def。 ${docker_host} 變數可以通過這樣類似shell的方式獲取。 build_tag = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim() 用來獲取git的commit id Build階段執行docker命令打包,把我們的變數傳遞到Dockerfile. 我的Dockerfile同樣在子module location下。 withCredentials可以呼叫儲存在Jenkins裡的憑證。這個需要安裝Credentials Binding Plugin. input會產生一個互動式的按鈕,需要手動點選通過才會繼續,否則暫停。這個只是暫停下一步,執行緒還在執行。所以,需要單獨提出node之外,再新增一個超時設定。參見“input” step blocks executor stash暫存檔案,參見官方文件. 主要用來把這次build過程中的某個檔案給暫存,只在本次build有效。本次不需要。 timeout 主要用來設定超時,參見官方文件, 時間單位有: NANOSECONDS, MICROSECONDS, MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS。這裡等待使用者確認是否繼續,若超過10分鐘還沒有確認,則停止。
宣告性Pipeline
- Pipeline的頂層必須是塊,具體來說是:pipeline { }
- 沒有分號作為語句分隔符。每個宣告必須在自己的一行
- 塊只能包含章節, 指令,步驟或賦值語句。
- 屬性引用語句被視為無引數方法呼叫。所以例如,輸入被視為input()
Sections
宣告性Pipeline中的Sections通常包含一個或多個指令或步驟。代理 agent
agent指定整個Pipeline或特定stage將在Jenkins環境中執行的位置,具體取決於該agent 部分的位置。該部分必須在pipeline塊內的頂層定義,stage塊內的agent是可選的 。是否必填 | 是 |
引數 | 如下面所描述的 |
允許出現在 | 在頂級pipeline塊和每個stage塊中。 |
引數
為了支援Pipeline作者可能擁有的各種使用場景,agent部分支援幾種不同型別的引數。這些引數可以應用於pipeline塊的頂層,也可以應用在每個stage指令內。- any -在任何可用的代理上執行Pipeline或stage。例如:agent any
- none -當在pipeline塊的頂層應用時,將不會為整個Pipeline執行分配全域性代理,並且每個stage部分將需要包含其自己的agent部分。例如:agent none
- label -使用提供的標籤在Jenkins環境中可用的代理上執行Pipeline或stage性執行。例如:agent { label 'my-defined-label' }
- node -agent { node { label 'labelName' } }行為和 agent { label 'labelName' }相同,但node允許其他選項(如customWorkspace)。
- docker -用給定的容器執行Pipeline,或stage,將被動態地提供一個預先配置成基於Docker-based Pipelines的節點,或和label引數匹配的任選節點。 docker還可以接受一個args引數,可以直接將引數傳遞給docker run命令。例如:agent { docker 'maven:3-alpine' }或
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' } }。您可以使用additionalBuildArgs選項將其他引數傳遞給docker build ...命令,如agent { dockerfile { additionalBuildArgs '--build-arg foo=bar' } }。
常用選項
下面是可以用於兩個或多個agent的常用選項。在沒有明確說明的情況下選項是可選的。 label -一個字串。在這些標籤上執行Pipeline或每個stage。此選項可用於node,docker和dockerfile,並且 對於node是必需的。 customWorkspace -一個字串。執行Pipeline或每個stage, 在這個agent的自定義的工作空間內,而不是預設的。它可以是相對路徑,在這種情況下,自定義工作區將位於節點上的工作空間根目錄下,也可以是絕對路徑。例如: agent { node { label 'my-defined-label' customWorkspace '/some/other/path' } } reuseNode -一個布林值,預設為false。如果為true,則在同一工作空間中,而不是完全在新節點上執行Pipeline頂層指定的節點上的容器。此選項適用於docker和dockerfile,並且僅在agent的每個stage內才有效果。 Jenkinsfile (Declarative Pipeline) pipeline { agent { docker 'maven:3-alpine' } stages { stage('Example Build') { steps { sh 'mvn -B clean verify' } } } }釋出 post
post定義將在Pipeline執行或stage結束時執行的操作。一些條件後的塊的內支援post: always,changed,failure,success,unstable,和aborted。這些塊允許在Pipeline執行或stage結束時執行步驟,具體取決於Pipeline的狀態。是否必填 | 否 |
引數 | 沒有 |
允許出現在 | 在頂級pipeline塊和每個stage塊中。 |
條件
Always -無論Pipeline執行的完成狀態如何都會執行。 changed -只有當前Pipeline執行的狀態與先前完成的Pipeline的狀態不同時,才能執行。 Failure -僅噹噹前Pipeline處於“失敗”狀態時才執行,通常在Web UI中用紅色指示表示。 success -僅噹噹前Pipeline具有“成功”狀態時才執行,通常在具有藍色或綠色指示的Web UI中表示。 Unstable -只有當前Pipeline具有“不穩定”狀態,通常由測試失敗,程式碼違例等引起,才能執行。通常在具有黃色指示的Web UI中表示。 Aborted -只有當前Pipeline處於“中止”狀態時,才會執行,通常是由於Pipeline被手動中止。通常在具有灰色指示的Web UI中表示。 Cleanup -無論管道或stage的狀態如何,在跑完所有其他的post條件後執行此條件下 的post步驟。Jenkinsfile (Declarative Pipeline) pipeline { agent any stages { stage('Example') { steps { echo 'Hello World' } } } post { always { echo 'I will always say Hello again!' } } }
- 通常,該post部分應放在Pipeline末端
- post條件塊包含的步驟和steps中的步驟用法相同
stage stages
包含一個或多個stage指令的序列,該stages部分是Pipeline 描述的大部分“工作”所在的位置。建議stages至少為持續交付流程的每個獨立部分包含至少一個stage指令,例如構建,測試和部署。是否必填 | 是 |
引數 | 沒有 |
允許出現在 | 在pipeline內只有一次。 |
pipeline { agent any stages { stage('Example') { steps { echo 'Hello World' } } } }
步驟 steps
steps部分定義了在給定stage指令中執行的一系列一個或多個步驟。是否必填 | 是 |
引數 | 沒有 |
允許出現在 | 每個stage塊內 |
例如
Jenkinsfile (Declarative Pipeline) pipeline { agent any stages { stage('Example') { steps { echo 'Hello World' } } } }
指令 Directives
環境 environment
environment指令指定一系列鍵值對,這些鍵值對將被定義為所有step或特定stage的step的環境變數,具體取決於environment指令位於Pipeline中的位置。 該指令支援一種特殊的助手方法credentials(),可以通過Jenkins環境中的識別符號來訪問預定義的憑據。對於型別為“Secret Text”的憑據,該 credentials()方法將確保環境變數中包含該Secret Text內容。對於“標準使用者名稱和密碼”型別的憑證,指定的環境變數將被設定為username:password並且將自動定義兩個附加的環境變數:MYVARNAME_USR和MYVARNAME_PSW。是否必填 | 否 |
引數 | 沒有 |
允許出現在 | 在pipeline塊內或stage內 |
例如:
Jenkinsfile (Declarative Pipeline) pipeline { agent any environment { CC = 'clang' } stages { stage('Example') { environment { AN_ACCESS_KEY = credentials('my-prefined-secret-text') } steps { sh 'printenv' } } } }
- environment頂級pipeline塊中使用的指令將適用於Pipeline中的所有步驟
- 在一個stage中定義的environment指令只將給定的環境變數應用於該stage中的步驟
- environment具有一個幫助方法credentials(),可用於在Jenkins環境中通過其識別符號訪問預定義的憑據
選項 options
options指令允許在Pipeline內配置Pipeline專用選項。Pipeline提供了許多這些選項,例如buildDiscarder,但它們也可能由外掛提供,例如 timestamps。是否必填 | 否 |
引數 | 沒有 |
允許出現在 | 在pipeline塊內,只有一次 |
可用選項
- buildDiscarder 持久化工件和控制檯輸出,用於儲存Pipeline最近幾次執行的資料。例如:options { buildDiscarder(logRotator(numToKeepStr: '1')) }
- checkoutToSubdirectory 在工作區的子目錄中執行原始碼檢出。例如:options { checkoutToSubdirectory('foo') }
- disableConcurrentBuilds 不允許並行執行Pipeline。可用於防止同時訪問共享資源等。例如:options { disableConcurrentBuilds() }
- preserveStashes 保留已完成構建的儲存,用於stage重新啟動。例如:options { preserveStashes() }儲存最近完成的構建中的stash,或者options { preserveStashes(5) }保留最近五個完成的構建中的stash。
- quietPeriod 設定管道的靜默期(以秒為單位),覆蓋全域性預設值。例如:options { quietPeriod(30) }
- retry 如果失敗,請按指定的次數重試整個管道。例如:options { retry(3) }
- skipDefaultCheckout 在agent指令中預設跳過原始碼檢出。例如:options { skipDefaultCheckout() }
- skipStagesAfterUnstable 一旦構建狀態進入了“不穩定”狀態,就跳過stage。例如:options { skipStagesAfterUnstable() }
- timeout 設定Pipeline執行的超時時間,之後Jenkins應該中止Pipeline。例如:options { timeout(time: 1, unit: 'HOURS') }
- timestamps 當執行時,預處理由Pipeline生成的所有控制檯輸出執行時間。例如:options { timestamps() }
例如:指定一個小時的全域性執行超時,之後Jenkins將中止Pipeline執行
Jenkinsfile (Declarative Pipeline) pipeline { agent any options { timeout(time: 1, unit: 'HOURS') } stages { stage('Example') { steps { echo 'Hello World' } } } }
stage選項 stage的options指令類似於Pipeline根目錄中的options指令。但是,stage的 options只能包含與stage相關的步驟,如retry,timeout或timestamps,或宣告性選項,如skipDefaultCheckout。 在stage內,options在進入agent或檢查任何when條件之前呼叫指令中的步驟。 可用的stage選項
- skipDefaultCheckout 預設情況下,在agent指令中跳過檢查原始碼管理中的程式碼。例如:options { skipDefaultCheckout() }
- timeout 設定此stage的超時時間,之後Jenkins應該中止該stage。例如:options { timeout(time: 1, unit: 'HOURS') }
- retry 如果失敗,請重試此stage指定次數。例如:options { retry(3) }
- timestamps 當執行時,預處理由Pipeline生成的所有控制檯輸出執行時間。例如:options { timestamps() }
- 例如:為stageExample指定一小時的執行超時,之後Jenkins將中止Pipeline執行。
pipeline { agent any stages { stage('Example') { options { timeout(time: 1, unit: 'HOURS') } steps { echo 'Hello World' } } } }
引數 parameters
parameters指令提供使用者在觸發Pipeline時應提供的引數列表。這些使用者指定的引數的值通過該params物件可用於Pipeline步驟,具體用法見示例。是否必填 | 否 |
引數 | 沒有 |
允許出現在 | 在pipeline塊內,只有一次 |
可用引數
- string 字串型別的引數,例如: parameters { string(name: 'DEPLOY_ENV', defaultValue: 'staging', description: '') }
- 文字 一個text引數,可以包含多行,例如: parameters { text(name: 'DEPLOY_TEXT', defaultValue: 'One\nTwo\nThree\n', description: '') }
- booleanParam 一個布林引數,例如: parameters { booleanParam(name: 'DEBUG_BUILD', defaultValue: true, description: '') }
- choice 選擇引數,例如: parameters { choice(name: 'CHOICES', choices: ['one', 'two', 'three'], description: '') }
- file 一個檔案引數,指定使用者在計劃構建時要提交的檔案,例如: parameters { file(name: 'FILE', description: 'Some file to upload') }
- password 密碼引數,例如: parameters { password(name: 'PASSWORD', defaultValue: 'SECRET', description: 'A secret password') }
Jenkinsfile (Declarative Pipeline) pipeline { agent any parameters { string(name: 'PERSON', defaultValue: 'Mr Jenkins', description: 'Who should I say hello to?') text(name: 'BIOGRAPHY', defaultValue: '', description: 'Enter some information about the person') booleanParam(name: 'TOGGLE', defaultValue: true, description: 'Toggle this value') choice(name: 'CHOICE', choices: ['One', 'Two', 'Three'], description: 'Pick something') password(name: 'PASSWORD', defaultValue: 'SECRET', description: 'Enter a password') file(name: "FILE", description: "Choose a file to upload") } stages { stage('Example') { steps { echo "Hello ${params.PERSON}" echo "Biography: ${params.BIOGRAPHY}" echo "Toggle: ${params.TOGGLE}" echo "Choice: ${params.CHOICE}" echo "Password: ${params.PASSWORD}" } } } }
觸發器 triggers
triggers指令定義了Pipeline應重新觸發的自動化方式。對於與原始碼整合的Pipeline,如GitHub或BitBucket,triggers可能不需要基於webhook的整合可能已經存在。目前只有兩個可用的觸發器是cron和pollSCM。需要 | 沒有 |
引數 | 沒有 |
允許 | 只有一次,在pipeline塊內。 |
- cron 接受一個cron風格的字串來定義Pipeline應重新觸發的常規間隔,例如: triggers { cron('H 4/* 0 0 1-5') }
- pollSCM 接受一個cron風格的字串來定義Jenkins應該檢查新的源更改的常規間隔。如果存在新的更改,則Pipeline將被重新觸發。例如:triggers { pollSCM('H 4/* 0 0 1-5') }
Jenkinsfile (Declarative Pipeline) pipeline { agent any triggers { cron('H 4/* 0 0 1-5') } stages { stage('Example') { steps { echo 'Hello World' } } } }
Jenkins cron 語法
Jenkins cron語法遵循cron實用程式的語法 (略有不同)。具體來說,每行包含由TAB或空格分隔的5個欄位:分鐘 | 小時 | DOM | 月 | DOW |
一小時內的分鐘數(0-59) | 一天中的小時(0-23) | 每月的某一天(1-31) | 月(1-12) | 星期幾(0-7),其中0和7是星期日。 |
- * 指定所有有效值
- M-N 指定一系列值
- M-N/X或者按照指定範圍或整個有效範圍的*/X間隔步長X
- A,B,…,Z 列舉多個值
階段 stage
stage指令在stages部分中,應包含步驟部分,可選agent部分或其他特定於stage的指令。實際上,Pipeline完成的所有實際工作都將包含在一個或多個stage指令中。是否必填 | 至少一個 |
引數 | 一個必填引數,一個用於stage名稱的字串 |
允許出現在 | 在stages內 |
例如:Jenkinsfile (Declarative Pipeline)
pipeline { agent any stages { stage('Example') { steps { echo 'Hello World' } } } }
工具 tools
定義自動安裝和放置工具的部分PATH。如果指定agent none,這將被忽略。是否必填 | 否 |
引數 | 沒有 |
允許出現在 | 在pipeline塊或stage塊內 |
支援的工具
- maven
- jdk
- gradle
Jenkinsfile (Declarative Pipeline) pipeline { agent any tools { maven 'apache-maven-3.0.1' } stages { stage('Example') { steps { sh 'mvn --version' } } } }
輸入 input
stage的input指令允許您使用input步驟提示輸入 。在進入stage的agent或評估其when狀態之前,stage將處於暫停狀態。如果input 獲得批准,stage則將繼續。作為input提供的任何引數將在stage的剩下部分的環境中可用 。配置選項
- message 必填。這將在使用者提交input時呈現給使用者。
- id 這是一個可選的識別符號input。預設為stage名稱。
- ok input表單上“ok”按鈕的可選文字。
- submitter 允許提交此input選項的使用者或外部組名列表,用逗號分隔。預設允許任何使用者。
- submitterParameter 要使用submitter名稱設定的環境變數的名稱,可選(如果存在)。
- 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指令允許Pipeline根據給定的條件確定是否執行該stage。when指令必須至少包含一個條件。如果when指令包含多個條件,則所有子條件必須都返回true,stage將會執行。這與子條件巢狀在一個allOf條件中相同(見下面的例子)。 更復雜的條件結構可使用巢狀條件建:not,allOf或anyOf。巢狀條件可以巢狀到任意深度。是否必填 | 否 |
引數 | 沒有 |
允許出現在 | 在stage指令內 |
內建條件
- branch 當正在構建的分支與給出的分支模式匹配時執行stage,例如:when { branch 'master' }。請注意,這僅適用於多分支Pipeline。
- environment 當指定的環境變數設定為給定值時執行stage,例如: when { environment name: 'DEPLOY_TO', value: 'production' }
- expression 當指定的Groovy表示式求值為true時執行stage,例如: when { expression { return params.DEBUG_BUILD } }
- not 當巢狀條件為false時執行stage。必須包含一個條件。例如:when { not { branch 'master' } }
- allOf 當所有巢狀條件都為真時,執行舞臺。必須至少包含一個條件。例如:when { allOf { branch 'master'; environment name: 'DEPLOY_TO', value: 'production' } }
- anyOf 當至少一個巢狀條件為真時執行舞臺。必須至少包含一個條件。例如:when { anyOf { branch 'master'; branch 'staging' } }
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' } } } }
順序執行的stage(Sequential Stages)
宣告性Pipeline中的stage可以按順序宣告待執行的stage列表。需要注意的是一個stage有且只能有一個 steps,parallel或者stages,stages是順序執行的。stage內的stage無法進一步含有parallel或stages ,但他們允許使用stage的所有其他功能,包括 agent,tools,when等等。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(Parallel)
宣告性Parallel中的stage可以在parallel塊中宣告多個巢狀stage,這些stage將並行執行。需要注意的是一個stage有且只能有一個steps,stages或parallel。巢狀的stages本身不能包含其他parallelstage,但在其他方面的行為與stage相同,包括順序執行的stage列表stages。任何包含parallel的stage都不能包含agent或者tools,因為那些和steps沒有關係。 此外,您可以通過新增failFast true到包含parallel的stage中,使得其中一個失敗時中止所有parallel內的stage。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" } } stage('Branch C') { agent { label "for-branch-c" } 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" } } } } } } } }
步驟 Steps
宣告性Pipeline可以使用“ Pipeline步驟”引用中記錄的所有可用步驟 ,其中包含一個完整的步驟列表,並附加以下列出的步驟,僅在宣告性Pipeline中支援。指令碼 script
script步驟需要一個script Pipeline,並在宣告性Pipeline中執行。對於大多數場景,宣告Pipeline中的script步驟不是必須的,但它可以提供一個有用的“escape hatch”。量大的或者複雜的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" } } } } } }
Scripted Pipeline
Scripted Pipeline,如宣告式Pipeline,構建在底層Pipeline子系統之上。不像宣告式Pipeline,Scripted Pipeline是一個基於Groovy構建的,通用、高效的DSL。由Groovy語言提供的大多數功能都提供給Scripted Pipeline的使用者,這意味著它是一個非常富有表現力和靈活性的工具,可以通過這些工具來建立持續構建的Pipeline。Flow Control
Scripted Pipeline從頂部順序執行,與Jenkinsfile Groovy或其他語言中的大多數傳統Scripted一樣。因此,提供流量控制取決於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' } } }可以管理Scripted 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 } } }
Steps
如“ 入門指南 ”所述,Pipeline最基本的部分是“步驟”。從根本上說,步驟告訴Jenkins 要做什麼,並且作為Declarative和Scripted Pipeline語法的基本構建塊。 Scripted Pipeline並沒有介紹這是專門針對它的語法的任何步驟; Pipeline步驟參考 ,其中包含Pipeline和外掛提供的完整步驟列表。與Groovy的區別
為了提供永續性(執行中的Pipeline可以在重新啟動Jenkins主站後保留),Scripted Pipeline必須將資料序列化到master節點。由於這個設計要求,一些Groovy語法如collection.each { item -> /* perform operation */ }沒有完全支援。有關 更多資訊,請參見 JENKINS-27421和 JENKINS-26481。語法比較
當Jenkins Pipeline首次建立時,Groovy被選為執行引擎。Jenkins已經使用嵌入式Groovy引擎很長時間,為管理員和使用者提供高階指令碼功能。此外,Jenkins Pipeline的實現者發現Groovy是建立“Scripted Pipeline”DSL的堅實基礎。 由於它是一個功能齊全的程式設計環境,Scripted Pipeline為Jenkins使用者提供了極大的靈活性和可擴充套件性。Groovy學習曲線通常不適用於給定團隊的所有成員,因此,建立宣告性Pipeline是為了創作Jenkins Pipeline提供一個更簡單和更有見解的語法。 兩者基本上是底層相同的Pipeline 子系統。它們都是“Pipeline程式碼”的持久實現。他們都能夠使用Pipeline內建的外掛或外掛提供的步驟。兩者都可以利用共享庫 不同之處在於語法和靈活性。宣告性限制了使用者具有更嚴格和預定義結構的可用性,使其成為更簡單連續輸送Pipeline的理想選擇。指令碼化提供了極少的限制,因為Groovy本身只能對結構和語法進行限制,而不是任何Pipeline專用系統,使其成為高階使用者和具有更復雜要求的使用者的理想選擇。顧名思義,Declarative Pipeline鼓勵宣告式程式設計模型。 儘管Scripted Pipeline遵循更命令性的程式設計模型。Pipeline stages中的stage含有stages 認真看,可以看到這些特點。 所有的stage,都會內嵌在最外層的stages{…} 一個stage{…}下可以內嵌有且只有一個stages{…} 多層巢狀只支援在最後一個stage{…}裡面 巢狀越多越複雜,最簡單就是觀察每一個stage的大括號的範圍 原則上,我們儘量少寫巢狀的stage{…},寫了巢狀就意味很難維護。但是有時候,由於業務邏輯需要,和stage{…}組織結構好看,我們會寫巢狀,巢狀裡面可能存在順序和平行的stage{…} 前面我們演示的demo都是順序,也就是一個接著一個執行
pipeline { agent none stages { stage('11111111') { steps { echo "11111111" } } stage('22222') { stages { stage('222222aaaaa1') { steps { echo "222222aaaaa1" } } stage('In 222222aaaa2') { steps { echo "222222aaaa2" } } } } stage('33333') { steps { echo "33333" } } } }並行stage{…}需要用到指令paraller, 有一個paraller{…} 裡面包含多個stage{…},最後一個stage{…}內部支援巢狀多個stages{…}。在paraller{…}如果要設定只要裡面有一個stage{…}執行失敗就強制停止,可以使用表示式failFast true 來條件控制。 並行stage{…}舉例:
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" } } } } } } } } 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,跑一下就可以幫助你瞭解。 並行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控制語句來展開接下來我們要實戰的練習。
pipeline { agent any stages { stage('flow control') { steps { script { if ( 10 == 10) { println "pass" }else { println "failed" } } } } } }
------------------------- A little Progress a day makes you a big success... ----------------------------