Pipeline As Code With Jenkins2.0

封面圖片:MBP With Touch Bar(Space Gray)

Jenkins2.0 Pipeline導入

Pipeline as Code是Jenkins 2.0版本的精華所在,是幫助Jenkins實現從CI到CD華麗轉身的關鍵工具署惯。

所謂Pipeline又官,簡單來說延刘,就是一套運行于Jenkins上的工作流框架,將原本獨立運行于單個或者多個節(jié)點的任務連接起來六敬,實現單個任務難以完成的復雜發(fā)布流程

Pipeline實現復雜發(fā)布流程

Pipeline的實現方式是一套Groovy DSL(類似Gradle)碘赖,任何發(fā)布流程都可以表述為一段Groovy腳本,并且Jenkins支持從代碼庫直接讀取腳本外构,從而實現了Pipeline as Code的理念普泡。

注: 本文原載于 My Personal Blog:CodeSheep · 程序羊 典勇!


為什么要使用Jenkins2.0 Pipeline

這里主要結合我自己對傳統Jenkins Job使用的一些痛點來說:

  • 傳統的Jenkins Job難以靈活高效地并行(Job間劫哼、節(jié)點間、任務間割笙、甚至任務內四個維度的并行)

  • 傳統的Jenkins Job日益失控的趨勢讓我們措手不及权烧,Job太多眯亦,CI腳本太離散,維護成本實在太高了般码,而且很危險妻率,一單Jenkins Server掛了,一切都Game Over了

  • 新拉分支的分支代碼CI部署太麻煩了

  • 傳統的Jenkins Job顯示真的是不太直觀啊

我想這些理由應該足以讓我們把目光轉向Jenkins2.0的Pipeline板祝!

Pipeline的功能和優(yōu)點:

  1. 持久性:在jenkins的master按計劃和非計劃的重啟后宫静,pipeline的job仍然能夠工作,不受影響券时。其實理解起來也很簡單孤里,jenkins的master和agent通過ssh連接,如果你知道nohup或disown的話橘洞,就可以理解為啥master的重啟不會影響agent上的job繼續(xù)運行捌袜。
  2. 可暫停性:pipeline基于groovy可以實現job的暫停和等待用戶的輸入或批準然后繼續(xù)執(zhí)行。
  3. 更靈活的并行執(zhí)行炸枣,更強的依賴控制虏等,通過groovy腳本可以實現step,stage間的并行執(zhí)行适肠,和更復雜的相互依賴關系霍衫。
  4. 可擴展性:通過groovy的編程更容易的擴展插件。
  5. 設計Pipeline = 設計代碼侯养,很優(yōu)雅
  6. As Code:集中管理CI腳本敦跌、用代碼庫來管理腳本、從代碼庫直接讀取腳本逛揩,從而可以將項目CI迅速拉起來峰髓!

Pipeline原理與流程

Pipeline為用戶設計了三個最最基本的概念:

  • Stage:一個Pipeline可以劃分為若干個Stage,每個Stage代表一組操作息尺。注意,Stage是一個邏輯分組的概念疾掰,可以跨多個Node搂誉。
  • Node:一個Node就是一個Jenkins節(jié)點,或者是Master静檬,或者是Agent炭懊,是執(zhí)行Step的具體運行期環(huán)境。
  • Step:Step是最基本的操作單元拂檩,小到創(chuàng)建一個目錄侮腹,大到構建一個Docker鏡像,由各類Jenkins Plugin提供稻励。

一個典型的Stage View如下圖所示:

典型的Stage View

從圖中可以十分方便地看到哪些Stage通過父阻,哪些Stage失敗愈涩,以及構建的時間。

Jenkins2.0的Pipeline搭建使用的是Groovy腳本加矛,通過Groovy腳本實現工作流管理的步驟如下:

  • 去Jenkins主界面建立Pipeline任務
建立PipeLine任務

實際上更常用的是MultiBranch Pipeline履婉,上面的圖中截圖沒有包含,但與普通Pipeline基本類似斟览。

  • 使用Groovy腳本自定義工作流
使用Groovy自定義工作流

上圖的實例腳本如下:

node { 
    stage('Checkout Code') { // for display purposes 
        // Get some code from a GitHub repository 
        git 'https://github.com/jglick/simple-maven-project-with-tests.git' 
    }
 
    stage('Build') { 
        // Run the maven build 
        if (isUnix()) { 
            sh "'${MAVEN_HOME}/bin/mvn' -Dmaven.test.failure.ignore clean package" 
        } else { 
            bat(/"${MAVEN_HOME}\bin\mvn" -Dmaven.test.failure.ignore clean package/) 
        } 
    } 
 
    stage('Unit test') { 
        junit '**/target/surefire-reports/TEST-UT.xml' 
        archive 'target/*.jar' 
    } 
} 
  • 開始執(zhí)行Pipeline

構建過程的stage View如下:

stage View

很明顯可以看出毁腿,這里顯示的和Groovy腳本中格式化的代碼是一致的,會實時顯示各個工作流的執(zhí)行進度和結果苛茂,直觀易懂已烤。鼠標移上去,能看到日志信息的縮略圖妓羊,單擊可以調到對應stage的console中胯究。

總而言之,一切都是那么地優(yōu)雅侍瑟!


Jenkins2.0 Pipeline關鍵DSL語法及示例

在這里總結一下Pipeline中的關鍵DSL語法唐片,利用Groovy對其進行組合可以完成任何一項復雜的CI/CD流程,熟悉它們大有裨益涨颜。

  • archiveArtifacts

歸檔文件费韭,舉例:

archiveArtifacts 'target/*.jar'
  • bat

執(zhí)行windows平臺下的批處理文件,如

bat "call example.bat"
  • build

觸發(fā)構建一個jenkins job庭瑰,如

build 'TEST_JOB'
  • checkout

從SCM系統中checkout repo星持,如:

checkout([$class: 'SubversionSCM', additionalCredentials: [], excludedCommitMessages: '', excludedRegions: '', excludedRevprop: '', excludedUsers: '', filterChangelog: false, ignoreDirPropChanges: false, includedRegions: '', locations: [[credentialsId: '30e6c1e5-1035-4bdd-8a44-05ba8f885158', depthOption: 'infinity', ignoreExternalsOption: true, local: '.', remote: 'svn://xxxxxx']], workspaceUpdater: [$class: 'UpdateUpdater']]) 
  • deleteDir()

從workspace中刪除當前目錄

  • dir

切換目錄,如

dir('/home/jenkins') { // 切換到/home/jenkins目錄中做一些事情
    // some block
}
  • echo

打印信息弹灭,如 echo 'hello world'

  • emailtext

利用Jenkins發(fā)送郵件督暂,內容、主題全都可以自定義穷吮,如

emailext body: 'Subject_test', subject: 'Subject_test', to: 'hansonwang99@163.com.cn'
// 郵件的正文body逻翁,主題subject,收件人to等可以進行自定義
  • error

拋出一個錯誤信號捡鱼,可以自行在代碼里拋出八回,如 error 'read_error'

  • fileExists

檢查工作空間某個路徑里是否存在某個file,舉例:

fileExists '/home/test.txt'  // 檢查是否存在test.txt
  • input

等待外界用戶的交互輸入驾诈,舉例:

input message: '', parameters: [string(defaultValue: '默認值', description: '版本號', name: 'version')] // 在某一步驟缠诅,等待用戶輸入version參數才能往下執(zhí)行
  • isUnix

用于判斷當前任務是否運行于Unix-like節(jié)點上,舉例:

def flag = isUnix()
if( flag == false ) { // 可以據此進行判斷
  echo "not run on a unix node !"
}
  • load

調用一個外部groovy腳本乍迄,舉例:

load 'D:\\jenkins\\workspace\\test.groovy'
  • node

分配節(jié)點給某個任務運行管引,舉例:

node('節(jié)點標簽') { // 在對應標簽的節(jié)點上運行某項任務
    Task()
}
  • parallel

并行地執(zhí)行任務,可以說是最實用高效的工具了闯两,舉例:

parallel(   //并行地執(zhí)行android unit tests和android e2e tests兩個任務
    'android unit tests': {
        runCmdOnDockerImage(androidImageName, 'bash /app/ContainerShip/scripts/run-android-docker-unit-tests.sh', '--privileged --rm')
    },
    'android e2e tests': {
    runCmdOnDockerImage(androidImageName, 'bash /app/ContainerShip/scripts/run-ci-e2e-tests.sh --android --js', '--rm')
    }
)
  • properties

設置Job的屬性褥伴,舉例:

properties([parameters([string(defaultValue: '1.0.0', description: '版本號', name: 'VERSION')]), pipelineTriggers([])]) // 為job設置了一個VERSION參數
  • pwd 顯示當前目錄

  • readFile

從工作空間中讀取文件谅将,舉例:

def editionName = readFile '/home/Test/exam.txt'
  • retry

重復body內代碼N次,舉例:

retry(10) {
    // some block
}
  • sh

執(zhí)行shell腳本噩翠,如:sh "sh test.sh"

  • sleep

延時戏自,如延時2小時:sleep time: 2, unit: 'HOURS'

  • stage

創(chuàng)建任務的stage,舉例:

stage('stage name') {
    // some block
}
  • stash

存放文件為后續(xù)構建使用伤锚,舉例:

dir('target') {
    stash name: 'war', includes: 'x.war'
}
  • unstash

將stash步驟中存放的文件在當前工作空間中重建擅笔,舉例:

def deploy(id) {
    unstash 'war'
    sh "cp x.war /tmp/${id}.war"
}
  • timeout

時間限制,舉例

timeout(time: 4, unit: 'SECONDS') {
    // some block
}
  • timestamps

用于在控制臺加時間戳屯援,舉例:

timestamps {
    // some block
}
  • touch

創(chuàng)建文件猛们,舉例:

touch file: 'TEST.txt', timestamp: 0
  • unzip

解壓文件,舉例:

unzip dir: '/home/workspace', glob: '', zipFile: 'TEST.zip'
  • validateDeclarativePipeline

檢查給定的文件是否包含一個有效的Declarative Pipeline狞洋,返回T或者F

validateDeclarativePipeline '/home/wospace'
  • waitUntil

等待弯淘,直到條件滿足

waitUntil {
    // some block
}
  • withCredentials

使用憑據

withCredentials([usernameColonPassword(credentialsId: 'mylogin', variable: 'USERPASS')]) {
    sh '''
      set +x
      curl -u $USERPASS https://private.server/ > output
    '''
}
  • withEnv

設置環(huán)境變量,注意近本次運行有效!

withEnv(['MYTOOL_HOME=/usr/local/mytool']) {
    sh '$MYTOOL_HOME/bin/start'
}
  • writeFile

寫文件到某個路徑

writeFile file: '/home/workspace', text: 'hello world'
  • writeJSON

寫JSON文件吉懊,用法基本同上

  • zip

創(chuàng)建zip文件

zip dir: '/home/workspace', glob: '', zipFile: 'TEST.zip'
  • ws

自定義工作空間庐橙,在其中做一些工作,效果類似于Dir命令借嗽,舉例:

ws('/home/jenkins_workspace') {
    // some block
}

后記

由于能力有限态鳖,若有錯誤或者不當之處,還請大家批評指正恶导,一起學習交流浆竭!



最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市惨寿,隨后出現的幾起案子邦泄,更是在濱河造成了極大的恐慌,老刑警劉巖裂垦,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件顺囊,死亡現場離奇詭異,居然都是意外死亡蕉拢,警方通過查閱死者的電腦和手機包蓝,發(fā)現死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來企量,“玉大人,你說我怎么就攤上這事亡电〗旃” “怎么了?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵份乒,是天一觀的道長恕汇。 經常有香客問我腕唧,道長,這世上最難降的妖魔是什么瘾英? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任枣接,我火速辦了婚禮,結果婚禮上缺谴,老公的妹妹穿的比我還像新娘但惶。我一直安慰自己,他們只是感情好湿蛔,可當我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布膀曾。 她就那樣靜靜地躺著,像睡著了一般阳啥。 火紅的嫁衣襯著肌膚如雪添谊。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天察迟,我揣著相機與錄音斩狱,去河邊找鬼。 笑死扎瓶,一個胖子當著我的面吹牛所踊,可吹牛的內容都是我干的。 我是一名探鬼主播栗弟,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼污筷,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了乍赫?” 一聲冷哼從身側響起瓣蛀,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎雷厂,沒想到半個月后惋增,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡改鲫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年诈皿,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片像棘。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡稽亏,死狀恐怖,靈堂內的尸體忽然破棺而出缕题,到底是詐尸還是另有隱情截歉,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布烟零,位于F島的核電站瘪松,受9級特大地震影響咸作,放射性物質發(fā)生泄漏。R本人自食惡果不足惜宵睦,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一记罚、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧壳嚎,春花似錦桐智、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至焙糟,卻和暖如春口渔,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背穿撮。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工缺脉, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人悦穿。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓攻礼,卻偏偏與公主長得像,于是被迫代替她去往敵國和親栗柒。 傳聞我的和親對象是個殘疾皇子礁扮,可洞房花燭夜當晚...
    茶點故事閱讀 45,435評論 2 359

推薦閱讀更多精彩內容