3. Jenkins pipeline 語法
3.1 pipeline 組成
? ? Jenkins pipeline 是基于Groovy
語言實現(xiàn)的一種DSL
(領(lǐng)域特定語言)屉佳,用于描述整條流水線是如何進行的谷朝。流水線的主要內(nèi)容包括源碼拉取
、構(gòu)建
武花、打包
圆凰、部署
、測試
体箕、生成報告
等步驟专钉。
? ? 從源碼管理倉庫到生成測試報告這些過程中,可以根據(jù)需要分成若干階段累铅,而每個階段僅處理一件事情跃须,而每個階段也可以通過多個步驟來完成,因此我們可以基于這些階段和步驟些進行抽象争群,形成工程化的pipeline回怜,因此一個基本的pipeline示例如下所示:
pipeline{
agent any
stages{
stage("Sample stage"){
steps {
echo "Hi,Surpass.Welcome visit my blog:https://www.cnblogs.com/surpassme/"
}
}
}
}
? ? 以上示例詳細解釋如下所示:
- pipeline:代表整條流水線,包含
整條流水線的邏輯
- agent:指定流水線的
運行位置
流水線的中每個階段都必須在某個地方(例如物理機换薄、虛擬機或容器)運行玉雾,因此可能通過指定 agent部分來指定具體在哪里運行。
- stages:流水線中多個stage的容器轻要。該部分
至少包含一個stage
- stage:表示階段复旬,代表流水線的階段,每個階段必須有名稱
- steps:表示階段中的一個或多個具體步驟的容器
1.steps
至少
包含一個步驟
2.在一個stage中僅有一個steps
? ? 以上每一個部分都是必需
的冲泥,否則Jenkins都會報錯
3.2 pipeline 支持的命令
? ? 基本的pipeline結(jié)構(gòu)是無法滿足日尘园現(xiàn)實多變的需求。因此凡恍,Jenkins pipeline可以通過各種指令來擴展豐富自己志秃。以下為Jenkins pipeline支持的命令。
3.2.1 environment
? ? environment
主要用于設(shè)置環(huán)境變量
嚼酝「』梗可以定義在stage
和pipeline
部分。環(huán)境變量可以分為:Jenkins內(nèi)置變量
和自定義環(huán)境變量
闽巩。
3.2.1.1 Jenkins 內(nèi)置環(huán)境變量
? ? 在執(zhí)行pipeline時钧舌,可以通過env
命令來獲取Jenkins的全部內(nèi)置環(huán)境變量,其主要使用方法如下所示:
pipeline {
agent any
stages{
stage("PrintEnviroment"){
steps{
// method A
echo "Running ${env.BUILD_ID} on ${env.JENKINS_URL}"
// method B
echo "Running $env.BUILD_ID on $env.JENKINS_URL"
// method C
echo "Running ${BUILD_ID} on ${JENKINS_URL}"
}
}
}
}
默認情況下涎跨,env中的所有環(huán)境變量都可以直接在pipeline中使用洼冻。因此上面三種方法都可以使用,但
不推薦第三種方法
隅很,因為在出現(xiàn)變量名沖突時撞牢,排查問題非常難。
? ? 如果需要查看env所有可用的環(huán)境變量,可以通過以下方式進行訪問普泡。http://jenkins-master-address/pipeline-syntax/globals
播掷。示例如下所示:
? ? Jenkins 內(nèi)置環(huán)境變量如下所示:
? ? 以下為日常經(jīng)常使用到的內(nèi)置環(huán)境變量簡介审编。如下所示:
- BRANCH_NAME
? ? 多分支piple 項目支持撼班。可根據(jù)不同的分支執(zhí)行不同的語句垒酬。例如當分支為release時砰嘁,部署到生產(chǎn)環(huán)境,分支為test時勘究,部署至測試環(huán)境矮湘。
- BUILD_NUMBER
? ? 構(gòu)建號,同一個項目中口糕,持續(xù)累加的數(shù)字缅阳。
- BUILD_URL
? ? 當前構(gòu)建的URL地址,點擊該URL景描,可以快速跳轉(zhuǎn)至構(gòu)建頁面
- WORKSPACE
? ? 構(gòu)建的工作空間十办,為絕對路徑
? ? 在調(diào)試pipeline時,也可以在pipeline 的開始階段使用以下代碼片斷超棺,打印所有env的環(huán)境變量向族,來進行排查問題。如下所示:
sh "printenv"
3.2.1.2 自定義環(huán)境變量
? ? 當內(nèi)置環(huán)境變量無法滿足要求時棠绘,我們也可以定義自己的環(huán)境變量件相。這個時候就需要使用environment
命令來自定義環(huán)境變量。示例如下所示:
pipeline {
agent any
environment{
NAME="Surpass"
AGE="28"
}
stages{
stage("PrintGolbalEnviroment"){
steps{
echo "Global Enviroment is name is ${env.NAME} age is ${env.AGE}"
}
}
stage("PrintLocalEnviroment"){
environment{
CITY="Shanghai"
FROM="Wuhan"
}
steps{
echo "Global Enviroment is name is ${env.NAME} age is ${env.AGE}"
echo "Local Enviroment is city is ${env.CITY} from is ${env.FROM}"
}
}
}
}
? ? environment
可以在pipeline
中定義氧苍,屬于全局環(huán)境變量
夜矗,代表整個pipeline均可以使用該環(huán)境變量。也可以在stage
中定義让虐,屬于局部環(huán)境變量
紊撕,僅限于該階段內(nèi)部有效,外部無法使用澄干。
? ? 除了以上幾中自定義環(huán)境變量逛揩,還可以通過script
來定義全局變量
,示例如下所示:
pipeline {
agent any
environment{
NAME="Surpass"
AGE="28"
}
stages{
stage("Set environment by script"){
steps{
script{
env.SURPASS_NAME="Surpass"
env.SURPASS_AGE=28
}
}
}
stage("PrintGolbalEnvironment"){
steps{
echo "Global Enviroment is name is ${env.NAME} age is ${env.AGE}"
}
}
stage("PrintLocalEnvironment"){
environment{
CITY="Shanghai"
FROM="Wuhan"
}
steps{
echo "Global Enviroment is name is ${env.NAME} age is ${env.AGE}"
echo "Local Enviroment is city is ${env.CITY} from is ${env.FROM}"
}
}
stage("PrintSetEnvironment"){
steps{
echo "print global env by script ${env.SURPASS_NAME}"
echo "print global env by script ${env.SURPASS_AGE}"
}
}
}
}
? ? 在自定義環(huán)境變量麸俘,需要注意的地方如下所示:
- 1.環(huán)境變量是不能跨pipeline進行訪問的辩稽,即
不同的pipeline間不能共享環(huán)境變量
- 2.如果用戶自定義的環(huán)境變量與env環(huán)境變量重名,則被重命名的環(huán)境將被
覆蓋
3.2.1.3 自定義全局環(huán)境變量
? ? env中的環(huán)境變量都是內(nèi)置的从媚,用戶自定義的環(huán)境變量是與具體的pipeline相關(guān)的逞泄。如果需要定義全局并且跨pipeline
自定義環(huán)境變量,可以這樣設(shè)置。
Manage Jenkins->Configure System-> Global properties喷众,勾選 Environment variables各谚,添加對應的環(huán)境變量即可。
? ? 以上自定義的全局環(huán)境變量到千,會被加入env環(huán)境變量列表中昌渤,后續(xù)使用時可以使用${env.SURPASS_NAME}
和${env.SURPASS_AGE}
來獲取。
3.2.2 tools
? ? 可定義在pipeline或stage部分憔四。在運行時膀息,會自動下載
并安裝指定的工具和加入PATH變量
中。但在agent none時了赵,會失效
基于在線自動安裝潜支,受限于網(wǎng)絡(luò)不可達、網(wǎng)絡(luò)速度柿汛、網(wǎng)絡(luò)策略等因素冗酿,一般還是建議,還是提前下載到本地络断,然后在Jenkins進行配置好之后裁替,在pipeline中直接使用即可。
3.2.2.1 Go 語言環(huán)境搭建
? ? 其操作步驟如下所示:
1.下載golang SDK本地
2.在Jenkins 中安裝go插件
3.在Jenkins中進行配置
Manage Jenkins->Configure System-> Global Tool Configuration->GO
- 4.編寫pipeline 腳本
pipeline{
agent any
tools {
go "go-1.19"
}
stages{
stage("tools demo"){
steps{
sh "go version"
sh "go env"
}
}
}
}
? ? 運行結(jié)果如下所示:
3.2.2.2 Python 語言環(huán)境搭建
? ? Python 環(huán)境很容易產(chǎn)生版本沖突和第三方庫沖突等問題妓羊,因此Python通過會進行工程級別的環(huán)境隔離胯究。在Jenkins中,我們可以使用插件Pyenv Pipeline Plugin
(https://plugins.jenkins.io/pyenv-pipeline/)來解決此類問題躁绸。其操作步驟如下所示:
- 1.在Jenkins中安裝Python/pip/virtualenv
- 2.安裝插件Pyenv Pipeline Plugin
- 3.編寫pipeline 腳本
pipeline{
agent any
stages{
stage("python virtual env demo"){
steps{
withPythonEnv("/usr/local/bin/python3") {
// Uses the specific python3.5 executable located in /usr/bin
sh "python3 --version"
sh "python3 -c \"print('hello,Surpass')\""
}
}
}
}
}
? ? 運行結(jié)果如下所示:
3.2.2.3 利用作用域?qū)崿F(xiàn)多版本編譯
? ? 在實際項目中裕循,同一份源碼可能會存在多個版本的編譯構(gòu)建等。tools 除了支持pipeline域
也支持stage域
净刮。示例如下所示:
pipeline{
agent any
stages{
stage("build with go 1.19"){
tools {
go "go-1.15"
}
steps{
echo "use go 1.15 build"
}
}
stage("build with go 1.19"){
tools {
go "go-1.19"
}
steps{
echo "use go 1.19 build"
}
}
}
}
3.2.3 input
? ? input 命令可以實現(xiàn)pipeline中的交互操作
剥哑。利用input命令,我們可以一些簡單的場景淹父。
- 實現(xiàn)簡易的審核流程
在部署環(huán)境前株婴,由相應負責人員進行確認
- 排查定位問題
因為pipeline在遇到input命令時,會暫停執(zhí)行暑认。因此困介,我們可以利用這個特性,使運行某個階段前蘸际,暫停執(zhí)行pipeline
3.2.3.1 常用參數(shù)
? ? input 命令的常用參數(shù)如下所示:
- message
? ? 該參數(shù)為必選參數(shù)
座哩,input命令的消息提示框消息。
- id
? ? 該參數(shù)為可選參數(shù)
粮彤, input命令標識符根穷,默認為stage的名稱
- submitter
? ? 該參數(shù)為可選參數(shù)
姜骡,類型為字符串類型
,可以進行操作的用戶ID或用戶組名稱屿良,使用,
分隔圈澈,在,
左右不允許有空格
〕揪澹可以用來做權(quán)限控制康栈。
- submitterParameter
? ? 該參數(shù)為可選參數(shù)
,類型為字符串類型
褥伴,保存input命令的實際操作者的用戶名的變量名
- ok
? ? 該參數(shù)為可選參數(shù)
谅将,自定義確定按鈕的文本
- parameters
? ? 該參數(shù)為可選參數(shù)
漾狼,提供參數(shù)列表供input命令使用重慢。
3.2.3.2 簡易用法
? ? 比如我們現(xiàn)在實現(xiàn)第一種簡易的審核流程。示例腳本如下所示:
pipeline{
agent any
stages{
stage("input simple use"){
steps{
input message:"Confirm or Cancle ?"
}
}
}
}
? ? 當執(zhí)行到input simple use
階段時逊躁,pipeline會暫停似踱,當鼠標移動到該階段虛線視圖上時,會出現(xiàn)一個浮層 稽煤,以供選擇核芽。示意圖如下所示:
3.2.3.3 復雜用法
? ? 示例腳本如下所示:
pipeline{
agent any
environment {
DEPLOY_ENV=""
}
stages{
stage("choose deploy nodes"){
steps{
script{
DEPLOY_ENV=input(
message: "準備部署到哪個節(jié)點?",
parameters:[choice(
name:'chooseNode',
choices:["node-1","node-2","node-3"],
description:"選擇部署節(jié)點")
],
ok:"確定",
submitter:"admin,Surpass",
submitterParameter:"approvers"
)
}
}
}
stage("deply"){
steps{
echo "操作人員:${DEPLOY_ENV['approvers']}"
echo "部署節(jié)點:${DEPLOY_ENV['chooseNode']}"
}
}
}
}
因為input返回的值需要跨階段酵熙,因此需要將input的返回值定義為全局變量轧简。
? ? input 命令返回值類型取決于返回的值個數(shù)
,詳情如下所示:
- 僅返回一個值匾二,返回值類型就是這個值的類型
- 返回多個值哮独,則返回值類型為Map類型
? ? 運行結(jié)果如下所示:
3.2.4 options
? ? 用于配置pipeline本身
的選項,可以定義在pipeline
和stage
中察藐。常用的配置項如下所示:
- buildDiscarder
? ? 用于配置保存最近歷史構(gòu)建記錄的數(shù)量皮璧。示例如下所示:
options{
buildDiscarder(logRotator(numToKeepStr:'5'))
}
此選項只能在pipeline下的 options 中使用
- checkoutToSubdirectory
? ? Jenkins 從版本控制庫中拉取源碼時,默認會存放到工作空間目錄中分飞,此選項可以指定檢出到工作空間的子目錄中悴务,示例如下所示:
options{
checkoutToSubdirectory('subdir')
}
- disableConcurrentBuilds
? ? 同一個pipeline,Jenkins默認是可以同時執(zhí)行的,而此選項則是禁止多個pipeline并行執(zhí)行
譬猫,示例如下所示:
options {
disableConcurrentBuilds()
}
- retry
? ? 當發(fā)生失敗時進行重試讯檐,可以指定整個pipeline的重試次數(shù)。示例如下所示:
options{
retry(3)
}
需要注意的是這里的重試次數(shù)是指總次數(shù)染服,即包含第一次失敗别洪。當使用retry選項時,options可以放在stage中
- timeout
? ? 若pipeline執(zhí)行時間過長肌索,超出了設(shè)置的超時時間之后蕉拢,則Jenkins將中止pipeline特碳。示例如下所示:
options{
timeout(time:1,unit:'SECONDS')
}
1.timeout時間單位有SECONDS、MINUTES晕换、HOURS午乓。
2.當使用timeout選項時,options可以放在stage塊中
- timestamps
? ? 為控制臺輸出時間戳闸准。示例如下所示:
options {
timestamps()
}
3.2.5 parallel
? ? 在pipeline中使用parallel
可以很方便的實現(xiàn)并行構(gòu)建益愈。
3.2.5.1 階段并行
? ? 示例如下所示:
pipeline{
agent any
stages{
stage("Non Parallel stage"){
steps{
echo "This is non-parallel stage"
}
}
stage("Parallel stage"){
failFast true
parallel{
stage("Parallel A"){
steps{
echo "Parallel A"
}
}
stage("Parallel B"){
steps{
echo "Parallel B"
}
}
stage("Parallel C"){
steps{
echo "Parallel C"
}
}
}
}
}
}
? ? 在使用parallel
時,注意事項如下所示:
- parallel
塊本身不允許
包含agent
和tools
- 默認情況下夷家,pipeline要等parallel塊下所有的階段都運行完成蒸其,才能確定運行結(jié)果。若希望所有并行階段中某個階段失敗后库快,就即將中止所有階段摸袁,則需要在parallel同級位置加入
failFast true
failFast true 簡單來講就是表示,只要有一個并行階段運行失敗,則立即退出不瓶。
3.2.5.2 步驟并行
? ? 示例如下所示:
pipeline{
agent any
stages{
stage("Non-parallel steps"){
steps{
echo "Non-parallel steps"
}
}
stage("Parallel steps"){
steps{
parallel(
parallelA:{
echo "parallelA steps"
},
parallelB:{
echo "parallelB steps"
},
parallelC:{
echo "parallelC steps"
}
)
}
}
}
}
? ? 階段并行和步驟并行的主要區(qū)別如下所示:
- 寫法區(qū)別:在階段并行時,使用的是
大括號
,而步驟并行時,使用的是括號
- 運行區(qū)別:階段并行是運行在不同的executor踢星,而步驟并行隙咸,則是運行在同一個executorr