設置環境變量
在 Jenkins 流水線中,取決于使用的是聲明式還是腳本式流水線,設置環境變量的方法不同。
聲明式流水線支持 environment 指令,而腳本式流水線的使用者必須使用 withEnv 步驟。
pipeline {agent anyenvironment { CC = 'clang'}stages {stage('Example') {environment { DEBUG_FLAGS = '-g'}steps {sh 'printenv'}}}
}
|
用在最高層的 pipeline 塊的 environment 指令適用于流水線的所有步驟。 |
---|
定義在 stage 中的 environment 指令只適用于 stage 中的步驟。 |
---|
憑據部分
憑據使用
node {withCredentials([string(credentialsId: 'mytoken', variable: 'TOKEN')]) {sh /* 錯誤! */ """set +xcurl -H 'Token: $TOKEN' https://some.api/"""sh /* 正確 */ '''set +xcurl -H 'Token: $TOKEN' https://some.api/'''}
}
處理參數
(構建化參數的作用)
聲明式流水線支持參數開箱即用,允許流水線在運行時通過parameters 指令接受用戶指定的參數。配置腳本式流水線的參數是通過 properties 步驟實現的,可以在代碼生成器中找到。
如果你使用 Build with Parameters 選項將流水線配置為接受參數,這些參數將作為 params 變量的成員被訪問。
假設在 Jenkinsfile 中配置了名為 “Greeting” 的字符串參數,它可以通過 ${params.Greeting} 訪問該參數:
string
字符串類型的參數, 例如: parameters { string(name: ‘DEPLOY_ENV’, defaultValue: ‘staging’, description: ‘’) }
booleanParam
布爾參數, 例如: parameters { booleanParam(name: ‘DEBUG_BUILD’, defaultValue: true, description: ‘’) }
還有更多其它類型
pipeline {agent anyparameters {// build with parameter時候也可以用界面輸入string(name: 'Greeting', defaultValue: 'Hello', description: 'How should I greet the world?')}stages {stage('Example') {steps {echo "${params.Greeting} World!"}}}
}
可選的步驟參數
流水線遵循 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 */
多個代理
在之前所有的示例中都只使用了一個代理。這意味著 Jenkins 會分配一個可用的執行者而無論該執行者是如何打標簽或配置的。流水線不僅可以覆蓋這種行為,還允許在 Jenkins 環境中使用 同一個 Jenkinsfile 中的多個代理,這將有助于更高級的用例,例如跨多個平臺的執行構建/測試。
在下面的示例中,“Build” 階段將會在一個代理中執行,并且構建結果將會在后續的 “Test” 階段被兩個分別標記為 “linux” 和 “windows” 的代理重用。
Jenkinsfile (Declarative Pipeline)
pipeline {agent nonestages {stage('Build') {agent anysteps {checkout scmsh 'make'stash includes: '**/target/*.jar', name: 'app' }}stage('Test on Linux') {agent { label 'linux'}steps {unstash 'app' sh 'make check'}post {always {junit '**/target/*.xml'}}}stage('Test on Windows') {agent {label 'windows'}steps {unstash 'app'bat 'make check' }post {always {junit '**/target/*.xml'}}}}
}
stash 步驟允許捕獲與包含模式(\**/target/*.jar)匹配的文件,以便在_同一個_流水線中重用。一旦流水線執行完成,就會從 Jenkins master 中刪除暫存文件。 |
---|
agent/node 中的參數允許使用任何可用的 Jenkins 標簽表達式。參考 流水線語法 |
部分了解更多信息。 |
unstash 將會從 Jenkins master 中取回命名的 “stash” 到流水線的當前工作區中。 |
bat 腳本允許在基于 Windows 的平臺上執行批處理腳本。 |
高級腳本式流水線
腳本式流水線是一種基于 Groovy 的領域特定語言 [3] ,大多數 Groovy 語法都可以無需修改,直接在腳本式流水線中使用。
并行執行
上面這節中的示例跨兩個不同的平臺串聯地運行測試。在實踐中,如果執行 make check 需要30分鐘來完成,那么 “Test” 階段就需要 60 分鐘來完成!
幸運的是,流水線有一個內置的并行執行部分腳本式流水線的功能,通過貼切的名為 parallel 的步驟實現。
使用 parallel 步驟重構上面的示例:
Jenkinsfile (Scripted Pipeline)
stage('Build') {/* .. snip .. */
}stage('Test') {parallel linux: {node('linux') {checkout scmtry {unstash 'app'sh 'make check'}finally {junit '**/target/*.xml'}}},windows: {node('windows') {/* .. snip .. */}}
}
測試不再在標記為 “linux” 和 “windows” 節點中串聯地執行,而是并行執行。
在流水線中使用Docker
設計流水線的目的是更方便地使用 Docker鏡像作為單個 Stage或整個流水線的執行環境。 這意味著用戶可以定義流水線需要的工具,而無需手動配置代理。 實際上,只需對 Jenkinsfile
進行少量編輯,任何 packaged in a Docker container的工具, 都可輕松使用。
Jenkinsfile (Declarative Pipeline)
pipeline {agent {docker { image 'node:7-alpine' }}stages {stage('Test') {steps {sh 'node --version'}}}
}
使用多個容器
代碼庫依賴于多種不同的技術變得越來越容易。比如, 一個倉庫既有基于Java的后端API 實現 and 有基于JavaScript的前端實現。 Docker和流水線的結合允許 Jenkinsfile 通過將 agent {} 指令和不同的階段結合使用 multiple 技術類型。
Jenkinsfile (Declarative Pipeline)
pipeline {agent nonestages {stage('Back-end') {agent {docker { image 'maven:3-alpine' }}steps {sh 'mvn --version'}}stage('Front-end') {agent {docker { image 'node:7-alpine' }}steps {sh 'node --version'}}}
}
使用Dockerfile
對于更需要自定義執行環境的項目, 流水線還支持從源倉庫的Dockerfile
中構建和運行容器。 與使用"現成" 容器的 previous approach 不同的是 , 使用 agent { dockerfile true } 語法從 Dockerfile 中構建一個新的鏡像而不是從 Docker Hub中拉取一個。
重復使用上面的示例, 使用一個更加自定義的 Dockerfile:
Dockerfile
FROM node:7-alpineRUN apk add -U subversion
通過提交它到源倉庫的根目錄下, 可以更改 Jenkinsfile 文件,來構建一個基于該 Dockerfile 文件的容器然后使用該容器運行已定義的步驟:
Jenkinsfile (Declarative Pipeline)
pipeline {agent { dockerfile true }stages {stage('Test') {steps {sh 'node --version'sh 'svn --version'}}}
}
agent { dockerfile true } 語法支持大量的其它選項,這些選項的更詳細的描述請參考 流水線語法 部分。
environment
environment 指令制定一個 鍵-值對序列,該序列將被定義為所有步驟的環境變量,或者是特定于階段的步驟, 這取決于 environment 指令在流水線內的位置。
該指令支持一個特殊的助手方法 credentials() ,該方法可用于在Jenkins環境中通過標識符訪問預定義的憑證。對于類型為 "Secret Text"的憑證, credentials() 將確保指定的環境變量包含秘密文本內容。對于類型為 "SStandard username and password"的憑證, 指定的環境變量指定為 username:password ,并且兩個額外的環境變量將被自動定義 :分別為 MYVARNAME_USR 和 MYVARNAME_PSW 。
示例
Jenkinsfile (Declarative Pipeline)
pipeline {agent anyenvironment { CC = 'clang'}stages {stage('Example') {environment { AN_ACCESS_KEY = credentials('my-prefined-secret-text') }steps {sh 'printenv'}}}
}
頂層流水線塊中使用的 environment 指令將適用于流水線中的所有步驟。 | |
---|---|
在一個 stage 中定義的 environment 指令只會將給定的環境變量應用于 stage 中的步驟。 | |
environment 塊有一個 助手方法 credentials() 定義,該方法可以在 Jenkins 環境中用于通過標識符訪問預定義的憑證。 |
觸發器
triggers 指令定義了流水線被重新觸發的自動化方法。對于集成了源( 比如 GitHub 或 BitBucket)的流水線, 可能不需要 triggers ,因為基于 web 的集成很肯能已經存在。 當前可用的觸發器是 cron, pollSCM 和 upstream。
Required | No |
---|---|
Parameters | None |
Allowed | Only once, inside the pipeline 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) }
pollSCM 只在Jenkins 2.22 及以上版本中可用。 |
---|
示例
Jenkinsfile (Declarative Pipeline)
pipeline {agent anytriggers {cron('H */4 * * 1-5')}stages {stage('Example') {steps {echo 'Hello World'}}}
}
when
when 指令允許流水線根據給定的條件決定是否應該執行階段。 when 指令必須包含至少一個條件。 如果 when 指令包含多個條件, 所有的子條件必須返回True,階段才能執行。 這與子條件在 allOf 條件下嵌套的情況相同 (參見下面的示例)。
使用諸如 not, allOf, 或 anyOf 的嵌套條件可以構建更復雜的條件結構 can be built 嵌套條件可以嵌套到任意深度。
Required | No |
---|---|
Parameters | None |
Allowed | Inside a stage 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 后該 stage 的 when 條件將會被評估。但是, 可以通過在 when 塊中指定 beforeAgent 選項來更改此選項。 如果 beforeAgent 被設置為 true, 那么就會首先對 when 條件進行評估 , 并且只有在 when 條件驗證為真時才會進入 agent 。
示例
Jenkinsfile (Declarative Pipeline)
pipeline {agent anystages {stage('Example Build') {steps {echo 'Hello World'}}stage('Example Deploy') {when {branch 'production'}steps {echo 'Deploying'}}}
}
并行
聲明式流水線的階段可以在他們內部聲明多隔嵌套階段, 它們將并行執行。 注意,一個階段必須只有一個 steps 或 parallel 的階段。 嵌套階段本身不能包含進一步的 parallel 階段, 但是其他的階段的行為與任何其他 stage 相同。任何包含 parallel 的階段不能包含 agent 或 tools 階段, 因為他們沒有相關 steps。
另外, 通過添加 failFast true 到包含 parallel的
stage 中, 當其中一個進程失敗時,你可以強制所有的 parallel 階段都被終止。
示例
pipeline {agent anystages {stage('Non-Parallel Stage') {steps {echo 'This stage will be executed first.'}}stage('Parallel Stage') {when {branch 'master'}failFast trueparallel {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"}}}}}
}