Jenkins實踐指南-05-Jenkins pipeline 語法01

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都會報錯

官方參考文檔:https://www.jenkins.io/doc/pipeline/steps/

3.2 pipeline 支持的命令

? ? 基本的pipeline結(jié)構(gòu)是無法滿足日尘园現(xiàn)實多變的需求。因此凡恍,Jenkins pipeline可以通過各種指令來擴展豐富自己志秃。以下為Jenkins pipeline支持的命令。

3.2.1 environment

? ? environment主要用于設(shè)置環(huán)境變量嚼酝「』梗可以定義在stagepipeline部分。環(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播掷。示例如下所示:

http://192.168.188.133:9090/pipeline-syntax/globals

? ? Jenkins 內(nèi)置環(huán)境變量如下所示:

0301 Jenkins內(nèi)置環(huán)境變量.png

? ? 以下為日常經(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)境變量即可。

0302 自定義全局環(huán)境變量.png

? ? 以上自定義的全局環(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

0303 添加go tools.png
  • 4.編寫pipeline 腳本
pipeline{
    agent any
    tools {
        go "go-1.19"
    }
    stages{
        stage("tools demo"){
            steps{
                sh "go version"
                sh "go env"
            }
        }
    }
}

? ? 運行結(jié)果如下所示:

0304 tools 運行結(jié)果.png

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é)果如下所示:

0305 pyenv demo.png

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)一個浮層 稽煤,以供選擇核芽。示意圖如下所示:

0306 input簡易用法.gif

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é)果如下所示:

0307 inpu復雜用法.gif

3.2.4 options

? ? 用于配置pipeline本身的選項,可以定義在pipelinestage中察藐。常用的配置項如下所示:

  • 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時間單位有SECONDSMINUTES晕换、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 塊本身不允許包含agenttools
  • 默認情況下夷家,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
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市扎瓶,隨后出現(xiàn)的幾起案子概荷,更是在濱河造成了極大的恐慌秕岛,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件误证,死亡現(xiàn)場離奇詭異继薛,居然都是意外死亡,警方通過查閱死者的電腦和手機愈捅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進店門遏考,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蓝谨,你說我怎么就攤上這事灌具∏嗤牛” “怎么了?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵咖楣,是天一觀的道長督笆。 經(jīng)常有香客問我,道長诱贿,這世上最難降的妖魔是什么娃肿? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮珠十,結(jié)果婚禮上料扰,老公的妹妹穿的比我還像新娘。我一直安慰自己焙蹭,他們只是感情好晒杈,可當我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著壳嚎,像睡著了一般桐智。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上烟馅,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天,我揣著相機與錄音然磷,去河邊找鬼郑趁。 笑死,一個胖子當著我的面吹牛姿搜,可吹牛的內(nèi)容都是我干的寡润。 我是一名探鬼主播,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼舅柜,長吁一口氣:“原來是場噩夢啊……” “哼梭纹!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起致份,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤变抽,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后氮块,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體绍载,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年滔蝉,在試婚紗的時候發(fā)現(xiàn)自己被綠了击儡。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡蝠引,死狀恐怖阳谍,靈堂內(nèi)的尸體忽然破棺而出蛀柴,到底是詐尸還是另有隱情,我是刑警寧澤矫夯,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布名扛,位于F島的核電站,受9級特大地震影響茧痒,放射性物質(zhì)發(fā)生泄漏肮韧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一旺订、第九天 我趴在偏房一處隱蔽的房頂上張望弄企。 院中可真熱鬧,春花似錦区拳、人聲如沸拘领。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽约素。三九已至,卻和暖如春笆凌,著一層夾襖步出監(jiān)牢的瞬間圣猎,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工乞而, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留送悔,地道東北人。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓爪模,卻偏偏與公主長得像欠啤,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子屋灌,可洞房花燭夜當晚...
    茶點故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內(nèi)容