3. Jenkins pipeline 語法
3.1 pipeline 組成
? ? [作者:Surpassme]Jenkins pipeline 是基于Groovy語言實作的一種DSL(領域特定語言),用于描述整條流水線是如何進行的,流水線的主要內容包括原始碼拉取、構建、打包、部署、測驗、生成報告等步驟,
? ? 從原始碼管理倉庫到生成測驗報告這些程序中,可以根據需要分成若干階段,而每個階段僅處理一件事情,而每個階段也可以通過多個步驟來完成,因此我們可以基于這些階段和步驟些進行抽象,形成工程化的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都會報錯
官方參考檔案:https://www.jenkins.io/doc/pipeline/steps/
3.2 pipeline 支持的命令
? ? [作者:Surpassme]基本的pipeline結構是無法滿足日常現實多變的需求,因此,Jenkins pipeline可以通過各種指令來擴展豐富自己,以下為Jenkins pipeline支持的命令,
3.2.1 environment
? ? [作者:Surpassme]environment主要用于設定環境變數,可以定義在stage和pipeline部分,環境變數可以分為:Jenkins內置變數和自定義環境變數,
3.2.1.1 Jenkins 內置環境變數
? ? [作者:Surpassme]在執行pipeline時,可以通過env命令來獲取Jenkins的全部內置環境變數,其主要使用方法如下所示:
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中的所有環境變數都可以直接在pipeline中使用,因此上面三種方法都可以使用,但
不推薦第三種方法,因為在出現變數名沖突時,排查問題非常難,
? ? 如果需要查看env所有可用的環境變數,可以通過以下方式進行訪問,http://jenkins-master-address/pipeline-syntax/globals,示例如下所示:
http://192.168.188.133:9090/pipeline-syntax/globals
? ? Jenkins 內置環境變數如下所示:

? ? 以下為日常經常使用到的內置環境變數簡介,如下所示:
- BRANCH_NAME
? ? 多分支piple 專案支持,可根據不同的分支執行不同的陳述句,例如當分支為release時,部署到生產環境,分支為test時,部署至測驗環境,
- BUILD_NUMBER
? ? 構建號,同一個專案中,持續累加的數字,
- BUILD_URL
? ? 當前構建的URL地址,點擊該URL,可以快速跳轉至構建頁面
- WORKSPACE
? ? 構建的作業空間,為絕對路徑
? ? 在除錯pipeline時,也可以在pipeline 的開始階段使用以下代碼片斷,列印所有env的環境變數,來進行排查問題,如下所示:
sh "printenv"
3.2.1.2 自定義環境變數
? ? [作者:Surpassme]當內置環境變數無法滿足要求時,我們也可以定義自己的環境變數,這個時候就需要使用environment命令來自定義環境變數,示例如下所示:
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}"
}
}
}
}
? ? [作者:Surpassme]environment 可以在pipeline中定義,屬于全域環境變數,代表整個pipeline均可以使用該環境變數,也可以在stage中定義,屬于區域環境變數,僅限于該階段內部有效,外部無法使用,
? ? 除了以上幾中自定義環境變數,還可以通過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}"
}
}
}
}
? ? 在自定義環境變數,需要注意的地方如下所示:
- 1.環境變數是不能跨pipeline進行訪問的,即
不同的pipeline間不能共享環境變數 - 2.如果用戶自定義的環境變數與env環境變數重名,則被重命名的環境將被
覆寫
3.2.1.3 自定義全域環境變數
? ? [作者:Surpassme]env中的環境變數都是內置的,用戶自定義的環境變數是與具體的pipeline相關的,如果需要定義全域并且跨pipeline自定義環境變數,可以這樣設定,
Manage Jenkins->Configure System-> Global properties,勾選 Environment variables,添加對應的環境變數即可,

? ? 以上自定義的全域環境變數,會被加入env環境變數串列中,后續使用時可以使用${env.SURPASS_NAME}和${env.SURPASS_AGE}來獲取,
3.2.2 tools
? ? [作者:Surpassme]可定義在pipeline或stage部分,在運行時,會自動下載并安裝指定的工具和加入PATH變數中,但在agent none時,會失效
基于在線自動安裝,受限于網路不可達、網路速度、網路策略等因素,一般還是建議,還是提前下載到本地,然后在Jenkins進行配置好之后,在pipeline中直接使用即可,
3.2.2.1 Go 語言環境搭建
? ? 其操作步驟如下所示:
-
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"
}
}
}
}
? ? 運行結果如下所示:

3.2.2.2 Python 語言環境搭建
? ? [作者:Surpassme]Python 環境很容易產生版本沖突和第三方庫沖突等問題,因此Python通過會進行工程級別的環境隔離,在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')\""
}
}
}
}
}
? ? 運行結果如下所示:

3.2.2.3 利用作用域實作多版本編譯
? ? [作者:Surpassme]在實際專案中,同一份原始碼可能會存在多個版本的編譯構建等,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
? ? [作者:Surpassme]input 命令可以實作pipeline中的互動操作,利用input命令,我們可以一些簡單的場景,
- 實作簡易的審核流程
在部署環境前,由相應負責人員進行確認
- 排查定位問題
因為pipeline在遇到input命令時,會暫停執行,因此,我們可以利用這個特性,使運行某個階段前,暫停執行pipeline
3.2.3.1 常用引數
? ? input 命令的常用引數如下所示:
- message
? ? 該引數為必選引數,input命令的訊息提示框訊息,
- id
? ? 該引數為可選引數, input命令識別符號,默認為stage的名稱
- submitter
? ? 該引數為可選引數,型別為字串型別,可以進行操作的用戶ID或用戶組名稱,使用,分隔,在,左右不允許有空格,可以用來做權限控制,
- submitterParameter
? ? 該引數為可選引數,型別為字串型別,保存input命令的實際操作者的用戶名的變數名
- ok
? ? 該引數為可選引數,自定義確定按鈕的文本
- parameters
? ? 該引數為可選引數,提供引數串列供input命令使用,
3.2.3.2 簡易用法
? ? 比如我們現在實作第一種簡易的審核流程,示例腳本如下所示:
pipeline{
agent any
stages{
stage("input simple use"){
steps{
input message:"Confirm or Cancle ?"
}
}
}
}
? ? 當執行到input simple use階段時,pipeline會暫停,當滑鼠移動到該階段虛線視圖上時,會出現一個浮層 ,以供選擇,示意圖如下所示:

3.2.3.3 復雜用法
? ? 示例腳本如下所示:
pipeline{
agent any
environment {
DEPLOY_ENV=""
}
stages{
stage("choose deploy nodes"){
steps{
script{
DEPLOY_ENV=input(
message: "準備部署到哪個節點?",
parameters:[choice(
name:'chooseNode',
choices:["node-1","node-2","node-3"],
description:"選擇部署節點")
],
ok:"確定",
submitter:"admin,Surpass",
submitterParameter:"approvers"
)
}
}
}
stage("deply"){
steps{
echo "操作人員:${DEPLOY_ENV['approvers']}"
echo "部署節點:${DEPLOY_ENV['chooseNode']}"
}
}
}
}
因為input回傳的值需要跨階段,因此需要將input的回傳值定義為全域變數,
? ? input 命令回傳值型別取決于回傳的值個數,詳情如下所示:
- 僅回傳一個值,回傳值型別就是這個值的型別
- 回傳多個值,則回傳值型別為Map型別
? ? 運行結果如下所示:

3.2.4 options
? ? [作者:Surpassme]用于配置pipeline本身的選項,可以定義在pipeline和stage中,常用的配置項如下所示:
- buildDiscarder
? ? [作者:Surpassme]用于配置保存最近歷史構建記錄的數量,示例如下所示:
options{
buildDiscarder(logRotator(numToKeepStr:'5'))
}
此選項只能在pipeline下的 options 中使用
- checkoutToSubdirectory
? ? [作者:Surpassme]Jenkins 從版本控制庫中拉取原始碼時,默認會存放到作業空間目錄中,此選項可以指定檢出到作業空間的子目錄中,示例如下所示:
options{
checkoutToSubdirectory('subdir')
}
- disableConcurrentBuilds
? ? [作者:Surpassme]同一個pipeline,Jenkins默認是可以同時執行的,而此選項則是禁止多個pipeline并行執行,示例如下所示:
options {
disableConcurrentBuilds()
}
- retry
? ? [作者:Surpassme]當發生失敗時進行重試,可以指定整個pipeline的重試次數,示例如下所示:
options{
retry(3)
}
需要注意的是這里的重試次數是指總次數,即包含第一次失敗,當使用retry選項時,options可以放在stage中
- timeout
? ? [作者:Surpassme]若pipeline執行時間過長,超出了設定的超時時間之后,則Jenkins將中止pipeline,示例如下所示:
options{
timeout(time:1,unit:'SECONDS')
}
1.timeout時間單位有SECONDS、MINUTES、HOURS,
2.當使用timeout選項時,options可以放在stage塊中
- timestamps
? ? [作者:Surpassme]為控制臺輸出時間戳,示例如下所示:
options {
timestamps()
}
3.2.5 parallel
? ? [作者:Surpassme]在pipeline中使用parallel可以很方便的實作并行構建,
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塊下所有的階段都運行完成,才能確定運行結果,若希望所有并行階段中某個階段失敗后,就即將中止所有階段,則需要在parallel同級位置加入
failFast true
failFast true 簡單來講就是表示,只要有一個并行階段運行失敗,則立即退出,
3.2.5.2 步驟并行
? ? [作者:Surpassme]示例如下所示:
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"
}
)
}
}
}
}
? ? [作者:Surpassme]階段并行和步驟并行的主要區別如下所示:
- 寫法區別:在階段并行時,使用的是
大括號,而步驟并行時,使用的是括號 - 運行區別:階段并行是運行在不同的executor,而步驟并行,則是運行在同一個executorr
原文地址:https://www.jianshu.com/p/f2895e38a824
本文同步在微信訂閱號上發布,如各位小伙伴們喜歡我的文章,也可以關注我的微信訂閱號:woaitest,或掃描下面的二維碼添加關注:

作者: Surpassme
來源: http://www.jianshu.com/u/28161b7c9995/
http://www.cnblogs.com/surpassme/
宣告:本文著作權歸作者所有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出 原文鏈接 ,否則保留追究法律責任的權利,如有問題,可發送郵件 聯系,讓我們尊重原創者著作權,共同營造良好的IT朋友圈,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/539854.html
標籤:其他
上一篇:java服裝經銷系統服裝進銷系統
