Jenkins 2權(quán)威指南(完整版)_第1頁(yè)
Jenkins 2權(quán)威指南(完整版)_第2頁(yè)
Jenkins 2權(quán)威指南(完整版)_第3頁(yè)
Jenkins 2權(quán)威指南(完整版)_第4頁(yè)
Jenkins 2權(quán)威指南(完整版)_第5頁(yè)
已閱讀5頁(yè),還剩91頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

Jenkins2權(quán)威指南注:因內(nèi)容過(guò)長(zhǎng)上傳受限制,本文檔只顯示部分內(nèi)容,完整版文檔請(qǐng)下載此文檔后留言謝謝。目錄TOC\h\h第1章Jenkins2簡(jiǎn)介\hJenkins2是什么\h做出轉(zhuǎn)變的原因\h迎接挑戰(zhàn)\h兼容性\h總結(jié)\h第2章基礎(chǔ)知識(shí)\h語(yǔ)法:腳本式流水線和聲明式流水線\h系統(tǒng)(system):主節(jié)點(diǎn)(master)、節(jié)點(diǎn)(node)、代理節(jié)點(diǎn)(agent)和執(zhí)行器(executor)\h結(jié)構(gòu):使用JenkinsDSL\h支持環(huán)境:開(kāi)發(fā)一個(gè)流水線腳本\h總結(jié)\h第3章流水線執(zhí)行流程\h觸發(fā)任務(wù)\h用戶輸入\h流程控制選項(xiàng)\h處理并發(fā)\h有條件的執(zhí)行功能\h構(gòu)建后處理\h總結(jié)\h第4章通知與報(bào)告\h通知\h報(bào)告\h總結(jié)\h第5章訪問(wèn)與安全\h安全加固Jenkins\hJenkins中的憑證\h管理憑證\h創(chuàng)建和管理憑證\h高級(jí)憑證:基于角色的訪問(wèn)權(quán)限\h在流水線中使用憑證\h控制腳本安全性\hGroovy沙箱\hJenkins憑證與Vault配合使用\h總結(jié)\h第6章擴(kuò)展你的流水線\h可信庫(kù)和不可信庫(kù)\h內(nèi)部庫(kù)與外部庫(kù)\h從代碼倉(cāng)庫(kù)獲取庫(kù)\h在流水線腳本中使用庫(kù)\hJenkins項(xiàng)目中的庫(kù)范圍\h庫(kù)結(jié)構(gòu)\h樣本庫(kù)例程\h使用第三方庫(kù)\h直接加載代碼\h從外部SCM加載代碼\h回放外部代碼和庫(kù)\h深入研究可信與不可信代碼\h總結(jié)\h第7章聲明式流水線\h動(dòng)機(jī)\h結(jié)構(gòu)\h構(gòu)建代碼塊\h處理非聲明式的代碼\h在一個(gè)階段中使用parallel\h腳本檢查與錯(cuò)誤報(bào)告\h聲明式流水線與BlueOcean接口\h總結(jié)\h第8章理解項(xiàng)目類(lèi)型\h通用項(xiàng)目選項(xiàng)\h項(xiàng)目類(lèi)型\h總結(jié)\h第9章BlueOcean用戶界面\h第一部分:管理已有的流水線\h第二部分:使用BlueOcean編輯器\h總結(jié)\h第10章轉(zhuǎn)換\h通用的準(zhǔn)備\h將自由風(fēng)格類(lèi)型的流水線轉(zhuǎn)換為腳本式流水線\h從Jenkins流水線項(xiàng)目轉(zhuǎn)換為Jenkinsfile\h從腳本式流水線轉(zhuǎn)換為聲明式流水線\h可用于轉(zhuǎn)換的通用指南\h總結(jié)\h第11章操作系統(tǒng)環(huán)境集成(shell、工作空間、環(huán)境和文件)\h使用shell的步驟\h使用環(huán)境變量\h使用工作空間\h文件和目錄步驟\h總結(jié)\h第12章集成分析工具\(yùn)hSonarQube調(diào)查\h將SonarQube與Jenkins一起使用\h代碼覆蓋率:與JaCoCo集成\h總結(jié)\h第13章集成制品管理\h發(fā)布和獲取制品\h安裝和全局配置\h在腳本式流水線中使用Artifactory\h執(zhí)行其他任務(wù)\h聲明式流水線集成\hArtifactory與Jenkins輸出集成\h制品歸檔和指紋\h總結(jié)\h第14章集成容器\h配置成一個(gè)云\h在聲明式流水線中動(dòng)態(tài)創(chuàng)建的代理節(jié)點(diǎn)\hDocker流水線全局變量\h通過(guò)shell運(yùn)行Docker\h總結(jié)\h第15章其他接口\h使用命令行接口\h使用JenkinsRESTAPI\h使用腳本控制臺(tái)\h總結(jié)\h第16章故障處理\h深入流水線步驟\h處理序列化錯(cuò)誤\h識(shí)別引發(fā)錯(cuò)誤的腳本行\(zhòng)h處理流水線異常\h在聲明式流水線中使用非聲明式代碼\h未授權(quán)代碼(腳本和方法授權(quán))\h不支持的操作\h系統(tǒng)日志\h時(shí)間戳\h流水線耐用性設(shè)置\h總結(jié)第1章Jenkins2簡(jiǎn)介歡迎來(lái)到《Jenkins2權(quán)威指南》,無(wú)論你是構(gòu)建管理員、開(kāi)發(fā)人員、測(cè)試人員,還是其他任何角色,本書(shū)都是你學(xué)習(xí)Jenkins演變的最佳選擇。通過(guò)本書(shū),你可以輕松地使用Jenkins2的新特性來(lái)設(shè)計(jì)、實(shí)現(xiàn)和執(zhí)行流水線,在靈活性、管控和易于維護(hù)等方面的提升都是之前版本的Jenkins所無(wú)法想象的。同時(shí),無(wú)論身處何種角色,你都能快速地從這些新特性中受益。如果你是開(kāi)發(fā)人員,編寫(xiě)流水線即代碼(pipeline-as-code)會(huì)更加舒適和自然。如果你是DevOps專(zhuān)家,維護(hù)流水線將變得更加簡(jiǎn)單,因?yàn)榱魉€和其他任何類(lèi)型的代碼一樣可以驅(qū)動(dòng)核心流程。如果你是測(cè)試人員,并行任務(wù)等新特性同樣可以讓你受益匪淺,減輕工作負(fù)擔(dān)。如果你是管理者,你可以像對(duì)待源碼一樣來(lái)確保流水線的質(zhì)量。如果你是Jenkins用戶,你可以顯著地提升技能,并且為流水線即代碼的進(jìn)化做好準(zhǔn)備。為了實(shí)現(xiàn)這些目標(biāo),需要理解和規(guī)劃已有功能向新特性過(guò)渡。Jenkins2對(duì)于傳統(tǒng)的基于表單的Jenkins版本而言,有明顯的改變。而伴隨這種改變引入了大量需要學(xué)習(xí)的知識(shí)點(diǎn),好在這些都在可控范圍內(nèi)。作為即將邁出的第一步,我們需要對(duì)Jenkins2的基本原理(Jenkins2是什么?哪些是最核心的功能?)打下堅(jiān)實(shí)的基礎(chǔ),其中包括新特性、工作空間的變化點(diǎn)以及一些全新的概念。這些正是本章和第2章的內(nèi)容。其中的部分內(nèi)容你可能已經(jīng)耳熟能詳,這樣的話就太棒啦。不過(guò)我還是建議你快速瀏覽一下這些熟悉的章節(jié),因?yàn)槠渲袝?huì)有一些全新和有變化的內(nèi)容值得你了解。在本章中,我們會(huì)從頂層設(shè)計(jì)探尋是什么讓Jenkins2變得與眾不同,它又是如何契合我們所熟識(shí)的領(lǐng)域的。我們將關(guān)注如下3個(gè)關(guān)鍵領(lǐng)域?!enkins2是什么,新版本帶來(lái)了哪些重要的新特性和功能點(diǎn)?·是什么原因(理念和動(dòng)機(jī))讓Jenkins發(fā)生改變?·Jenkins2如何兼容以前的版本,有哪些兼容性方面需要關(guān)注?下面讓我們先來(lái)看看Jenkins2和傳統(tǒng)的Jenkins相比有哪些不同之處。Jenkins2是什么在本書(shū)中,Jenkins2的概念比較寬泛。在特定的上下文環(huán)境中,它用來(lái)泛指支持流水線即代碼及其他類(lèi)似Jenkinsfile等新特性的新版Jenkins,這些新特性將始終貫穿本書(shū)。其中的部分特性在Jenkins1.X版本中已經(jīng)通過(guò)插件的方式實(shí)現(xiàn)(確切地講,Jenkins2也是通過(guò)對(duì)已有插件的重點(diǎn)升級(jí)和新插件的引入來(lái)獲得新功能的)。但是Jenkins2則更進(jìn)一步,它將這些特性視為一種同Jenkins交互的核心方式,并且也是Jenkins推薦的方式。相比之前用戶只能通過(guò)Web界面進(jìn)行配置的方式來(lái)定義Jenkins任務(wù),現(xiàn)在通過(guò)使用JenkinsDSL和Groovy語(yǔ)言編寫(xiě)程序,用戶可以定義流水線并執(zhí)行各種任務(wù)。這里提到的DSL代表領(lǐng)域特定語(yǔ)言(Domain-SpecificLanguage),可以理解為一種適用于Jenkins的“編程語(yǔ)言”。DSL基于Groovy實(shí)現(xiàn),并通過(guò)概念和結(jié)構(gòu)封裝了Jenkins的特定功能。舉例來(lái)說(shuō),關(guān)鍵字node表示以編程方式來(lái)選擇節(jié)點(diǎn)(也就是主節(jié)點(diǎn)和從節(jié)點(diǎn)),并且程序中的這部分功能將在該節(jié)點(diǎn)上執(zhí)行。Jenkins和GroovyJenkins在很早之前就內(nèi)建了Groovy引擎,并且通過(guò)這種方式允許高級(jí)腳本操作,提供Web界面上不可見(jiàn)的功能和訪問(wèn)權(quán)限。DSL是Jenkins2的核心組件,作為構(gòu)建模塊讓其他核心的用戶導(dǎo)向特性成為可能。讓我們來(lái)大致看下這些特性如何使Jenkins2區(qū)別于傳統(tǒng)版本的Jenkins。我們會(huì)快速體驗(yàn)一種全新的方式,將原本寫(xiě)在Jenkins中的代碼提取到一個(gè)Jenkinsfile文件中,以一種更加結(jié)構(gòu)化的方法來(lái)創(chuàng)建工作流——聲明式流水線,同時(shí)還有一個(gè)更加令人興奮的全新用戶界面——BlueOcean。Jenkinsfile在Jenkins2中,流水線配置可以從Jenkins中分離出來(lái)。在以前版本的Jenkins中,任務(wù)配置都是以配置文件的形式保存在Jenkins的主目錄中的。這就意味著所有的配置變更都依賴于Jenkins可以識(shí)別和管理這些文件(除非你想直接修改XML文件,但這是非常有挑戰(zhàn)性的事情)。在Jenkins2中,你可以在Web可視化界面的文本區(qū)中以DSL腳本來(lái)編寫(xiě)流水線配置。當(dāng)然,你同樣可以將這些文本形式的DSL代碼和其他保存源碼的文本文件一起保存在外部的版本控制系統(tǒng)中。這使得你可以像管理其他源碼一樣通過(guò)文件的形式來(lái)管理Jenkins任務(wù),支持歷史追溯、差異對(duì)比等功能。JobConfigHistory插件基于完備性的角度,我應(yīng)該提到Jenkins中有一個(gè)叫作JobConfigHistory的插件,這個(gè)插件可以追溯XML配置的歷史版本信息,并且允許你查看每次變更的內(nèi)容。關(guān)于這個(gè)插件的信息,在Jenkins的Wiki中有更加詳細(xì)的描述。Jenkins2推薦使用名為Jenkinsfile的文件保存任務(wù)配置和流水線信息。不同的項(xiàng)目和分支都會(huì)有自己的Jenkinsfile,其內(nèi)容各不相同。你可以將全部代碼寫(xiě)在一個(gè)Jenkinsfile中,也可以通過(guò)共享庫(kù)的方式調(diào)用外部代碼。另外,DSL語(yǔ)句也允許在腳本中加載外部代碼(關(guān)于此部分的更多信息,請(qǐng)參考第6章)。Jenkinsfile可以起到標(biāo)記文件(markerfile)的作用,這意味著只要Jenkins發(fā)現(xiàn)你的工程源碼中包含了Jenkinsfile文件,那么這個(gè)項(xiàng)目或分支就可以被Jenkins自動(dòng)解析和運(yùn)行。Jenkins同樣可以識(shí)別出需要用到的源碼版本控制管理(SCM)項(xiàng)目和分支,并加載和執(zhí)行Jenkinsfile中的代碼。如果你熟悉Gradle構(gòu)建工具,這個(gè)理念與應(yīng)用中定義的build.gradle文件類(lèi)似。我會(huì)在本書(shū)中對(duì)Jenkinsfile進(jìn)行更加詳細(xì)的描述。圖1-1展示了一個(gè)用于源碼版本控制的Jenkinsfile的例子。圖1-1一個(gè)用于源碼版本控制的Jenkinsfile的例子聲明式流水線在以前版本的Jenkins中,流水線即代碼大體就是Groovy腳本,其中插入了部分針對(duì)Jenkins的DSL步驟。這種方式幾乎沒(méi)有結(jié)構(gòu)上的約束,程序流程也基于Groovy語(yǔ)法結(jié)構(gòu)實(shí)現(xiàn)。錯(cuò)誤報(bào)告和檢查同樣基于Groovy程序的執(zhí)行,而非從期望通過(guò)Jenkins實(shí)現(xiàn)功能的角度來(lái)檢查。這種模式現(xiàn)在被稱為腳本式流水線。然而,流水線的DSL語(yǔ)言也在不斷進(jìn)化。在腳本式流水線中,DSL支持為數(shù)眾多的任務(wù)步驟,但是仍然缺失了部分面向Jenkins任務(wù)的核心特性,比如,構(gòu)建后處理、流水線結(jié)構(gòu)錯(cuò)誤檢查以及基于不同執(zhí)行狀態(tài)發(fā)送通知的功能。當(dāng)然大多數(shù)功能都可以通過(guò)Groovy編程機(jī)制來(lái)模擬實(shí)現(xiàn),比如trycatch-finally語(yǔ)法。但是這在面向Jenkins編程的基礎(chǔ)上對(duì)Groovy語(yǔ)言的技能提出了更高的要求。圖1-1中的Jenkinsfile展示了帶有try-catch的做通知處理的腳本式流水線樣例。在2016年和2017年間,作為Jenkins主要貢獻(xiàn)者的企業(yè)級(jí)公司CloudBees引入了一種高級(jí)流水線即代碼的編程語(yǔ)法,這就是聲明式流水線。這種語(yǔ)法為流水線帶來(lái)了一種清晰、可預(yù)期的結(jié)構(gòu),以及更強(qiáng)大的DSL元素和結(jié)構(gòu)體。這種方式更加接近通過(guò)Web界面構(gòu)建流水線的工作方法(即自由風(fēng)格類(lèi)型項(xiàng)目)。這里有一個(gè)構(gòu)建后過(guò)程的示例,現(xiàn)在我們可以使用內(nèi)建的DSL機(jī)制,通過(guò)簡(jiǎn)單定義就能實(shí)現(xiàn)基于構(gòu)建狀態(tài)發(fā)送通知的功能。這減少了使用Groovy代碼提供流水線定義來(lái)模擬傳統(tǒng)Jenkins特性的需求。聲明式流水線更加嚴(yán)謹(jǐn)?shù)慕Y(jié)構(gòu)同樣有助于錯(cuò)誤檢查。于是我們不再需要在發(fā)生錯(cuò)誤時(shí)查看Groovy的調(diào)試信息(traceback),而是將錯(cuò)誤信息以更加直觀、簡(jiǎn)單的方式展現(xiàn)給用戶,在大多數(shù)情況下可以直接定位到具體的錯(cuò)誤。圖1-2給出了具有增強(qiáng)錯(cuò)誤檢查功能的聲明式流水線所輸出的代碼片段:圖1-2具有增強(qiáng)錯(cuò)誤檢查功能的聲明式流水線BlueOcean界面聲明式流水線的結(jié)構(gòu)同時(shí)也是Jenkins2的另一項(xiàng)創(chuàng)新——BlueOcean,全新Jenkins可視化界面——的基礎(chǔ)。BlueOcean為流水線的每個(gè)階段添加了圖形化展示,可以顯示成功/失敗和進(jìn)展等標(biāo)識(shí),并對(duì)每個(gè)任務(wù)都提供了點(diǎn)選式日志查看功能。BlueOcean還提供了一個(gè)簡(jiǎn)單的可視化編輯器。圖1-3展示了一個(gè)在BlueOcean中成功運(yùn)行的流水線及其日志顯示的例子。第9章將會(huì)詳細(xì)介紹BlueOcean的全新界面。圖1-3BlueOcean界面里的一個(gè)運(yùn)行成功和查看日志的例子Jenkins2的全新任務(wù)類(lèi)型Jenkins2增加了一些新的任務(wù)類(lèi)型,主要是圍繞利用流水線即代碼和Jenkinsfile等關(guān)鍵功能來(lái)設(shè)計(jì)的。這些類(lèi)型比以往任何時(shí)候都更容易自動(dòng)化任務(wù)、流水線創(chuàng)建以及組織項(xiàng)目。每個(gè)新任務(wù)/工作項(xiàng)/項(xiàng)目的創(chuàng)建都以相同的方式開(kāi)始。新的任務(wù)類(lèi)型和插件這里需要說(shuō)明一下,只有安裝了相關(guān)插件,才能擁有這些新的任務(wù)類(lèi)型。如果你在Jenkins2初始化安裝向?qū)е羞x擇了安裝系統(tǒng)推薦的插件,才可以使用這里討論的任務(wù)類(lèi)型。一旦安裝了Jenkins2并登錄成功,就可以像以前一樣創(chuàng)建新的任務(wù)。如圖1-4所示,歡迎來(lái)到Jenkins!歡迎標(biāo)語(yǔ)下面有一個(gè)建議用戶新建任務(wù)的鏈接,這個(gè)鏈接對(duì)應(yīng)菜單欄里面的新建工作項(xiàng)。在絕大多數(shù)情況下新建工作項(xiàng)就是指項(xiàng)目。在本書(shū)中將交替使用“任務(wù)”、“工作項(xiàng)”和“項(xiàng)目”這幾個(gè)術(shù)語(yǔ)。圖1-4Jenkins歡迎頁(yè):新建任務(wù)、工作項(xiàng)和項(xiàng)目的入口當(dāng)選擇在Jenkins2中創(chuàng)建一個(gè)新的工作項(xiàng)時(shí),屏幕中會(huì)提示選擇新建任務(wù)的類(lèi)型(見(jiàn)圖1-5)。你會(huì)看到一些熟悉的類(lèi)型,比如,自由風(fēng)格類(lèi)型項(xiàng)目,同時(shí)還有一些你以前沒(méi)見(jiàn)過(guò)的類(lèi)型。在這里先簡(jiǎn)要羅列一下新的任務(wù)類(lèi)型,然后會(huì)在第8章中進(jìn)行詳細(xì)的解釋。圖1-5Jenkins2的項(xiàng)目選項(xiàng)流水線顧名思義,流水線類(lèi)型的項(xiàng)目旨在創(chuàng)建流水線。這是通過(guò)JenkinsDSL編寫(xiě)代碼來(lái)實(shí)現(xiàn)的。流水線項(xiàng)目是我們?cè)诒緯?shū)中主要討論的項(xiàng)目類(lèi)型。正如已經(jīng)指出的,流水線既可以用“腳本式”語(yǔ)法風(fēng)格編寫(xiě),也可以用“聲明式”語(yǔ)法風(fēng)格編寫(xiě)。這種項(xiàng)目類(lèi)型的流水線可以很容易地轉(zhuǎn)換成Jenkinsfile。文件夾這是一種可以把多個(gè)項(xiàng)目歸類(lèi)到一起的方式,而不是項(xiàng)目本身的類(lèi)型。請(qǐng)注意,這并不像Jenkins儀表板上傳統(tǒng)的“視圖”選項(xiàng)卡那樣,讓你按照項(xiàng)目列表篩選。更確切地說(shuō),它就像操作系統(tǒng)中的目錄文件夾。文件夾名稱是項(xiàng)目路徑的一部分。組織有些源碼版本控制平臺(tái)提供了將多個(gè)代碼庫(kù)聚合成“組織”的機(jī)制。Jenkins集成允許將Jenkins流水線腳本存儲(chǔ)為組織內(nèi)代碼庫(kù)中的Jenkinsfile文件,并基于這些庫(kù)執(zhí)行。目前已經(jīng)支持GitHub和Bitbucket平臺(tái)的組織功能,未來(lái)將會(huì)逐步支持其他的平臺(tái)。為簡(jiǎn)單起見(jiàn),在本書(shū)中主要以GitHub的組織項(xiàng)目作為例子。假設(shè)有足夠的訪問(wèn)權(quán)限,Jenkins可以在代碼托管側(cè)自動(dòng)建立一個(gè)組織的webhook(來(lái)自網(wǎng)站的通知),從而任何代碼庫(kù)中的變更都會(huì)通知Jenkins實(shí)例。當(dāng)Jenkins收到通知時(shí),它會(huì)檢測(cè)代碼庫(kù)中作為一種標(biāo)記而使用的Jenkinsfile文件,并執(zhí)行其中的命令來(lái)運(yùn)行流水線。多分支流水線在這種類(lèi)型的項(xiàng)目中,Jenkins再次使用Jenkinsfile作為標(biāo)記的功能。在一個(gè)有Jenkinsfile的項(xiàng)目中,如果創(chuàng)建了一個(gè)新的分支,Jenkins將自動(dòng)基于這個(gè)新分支創(chuàng)建一個(gè)新項(xiàng)目。此類(lèi)型項(xiàng)目可應(yīng)用于任何Git或SVN代碼庫(kù)。在本書(shū)的第8章中,我們將詳細(xì)介紹每一個(gè)新的項(xiàng)目類(lèi)型。然而,值得注意的是,Jenkins仍然支持之前的自由風(fēng)格類(lèi)型項(xiàng)目,仍然可以使用基于Web的表單創(chuàng)建任務(wù),并像以前一樣執(zhí)行它們。但Jenkins2更加關(guān)注的是流水線任務(wù)。很容易看出,相對(duì)于傳統(tǒng)的Jenkins模式,Jenkins2發(fā)生了重大轉(zhuǎn)變。因此,值得花幾分鐘來(lái)討論轉(zhuǎn)變的原因。做出轉(zhuǎn)變的原因毫無(wú)疑問(wèn),Jenkins成為使用最廣泛的工作流或流水線管理工具已有很多年了。那么,是什么驅(qū)使了在Jenkins2中做出轉(zhuǎn)變的需求呢?讓我們一起看幾個(gè)潛在的原因。對(duì)Jenkins來(lái)說(shuō),既有外部因素,也有內(nèi)部因素。DevOps理念的轉(zhuǎn)變持續(xù)集成、持續(xù)交付和持續(xù)部署背后的理論思想已經(jīng)存在很多年了。但在最開(kāi)始,它們更多地被當(dāng)作最終目標(biāo)而不是起點(diǎn)。隨著最近幾年對(duì)DevOps的關(guān)注度越來(lái)越高,用戶和企業(yè)已經(jīng)開(kāi)始期望有一個(gè)創(chuàng)造性的工具可以幫助他們實(shí)現(xiàn)DevOps和持續(xù)的實(shí)踐活動(dòng)(或者至少不會(huì)把它變得更困難)。基于Jenkins在工作流自動(dòng)化領(lǐng)域的地位,在某種程度上,它會(huì)被期望(也許是必需的)能夠通過(guò)自身能力的進(jìn)一步提升來(lái)支持這些工業(yè)上的驅(qū)動(dòng)。裝配流水線創(chuàng)建任何一個(gè)自由風(fēng)格類(lèi)型接口的Jenkins任務(wù)不會(huì)有太大的問(wèn)題。但是,試圖將多個(gè)任務(wù)組裝成連續(xù)的軟件交付流水線,比如,編寫(xiě)代碼來(lái)完成從提交到部署的過(guò)程,通常是一個(gè)挑戰(zhàn)。Jenkins的核心功能雖然允許一個(gè)任務(wù)運(yùn)行結(jié)束后啟動(dòng)另一個(gè)指定的任務(wù),但是在多個(gè)任務(wù)之間共享數(shù)據(jù),比如工作空間、參數(shù)等,會(huì)經(jīng)常出問(wèn)題,也有可能需要特定的插件或技巧來(lái)幫助完成。可恢復(fù)性Jenkins2功能里的一個(gè)關(guān)鍵部分取決于流水線的持久性。換句話說(shuō)就是,即使主節(jié)點(diǎn)重啟了,任務(wù)依舊可以繼續(xù)在代理節(jié)點(diǎn)上運(yùn)行或者獲取它們離開(kāi)時(shí)的位置。事實(shí)上,一個(gè)插件能與Jenkins2兼容的要求之一就是有能夠序列化狀態(tài)的能力,以便在遇到主節(jié)點(diǎn)重啟事件時(shí),它們可以恢復(fù)這些狀態(tài)。以前版本的Jenkins并不適用于這個(gè)場(chǎng)景,用戶和進(jìn)程通常會(huì)被置于一個(gè)尷尬的境地,要么通過(guò)日志弄清楚還剩下哪些東西,要么選擇從頭開(kāi)始執(zhí)行這些進(jìn)程??膳渲眯杂捎诨赪eb的界面在很大程度上限制了用戶,使用傳統(tǒng)的Jenkins通常需要在屏幕上找到正確的位置,找出按鈕和字段,并且在輸入數(shù)據(jù)時(shí)盡量不要出錯(cuò)。更改工作流(例如,在任務(wù)中重新排序步驟或更改任務(wù)執(zhí)行的順序)會(huì)需要多次點(diǎn)擊、拖動(dòng)和鍵入等交互動(dòng)作,而不是在文本編輯器界面做更簡(jiǎn)單的可用更新。在工具接口使用了GUI元素的情況下,通過(guò)Jenkins接口向工具發(fā)送特定命令的方式就不再可用了。Jenkins中常用的基于Web表單的形式更有助于做出簡(jiǎn)單、結(jié)構(gòu)化的選擇,但對(duì)基于迭代或基于決策的流控制來(lái)說(shuō),效果不太好。共享工作空間在傳統(tǒng)的Jenkins使用過(guò)程中,每個(gè)任務(wù)都有自己的工作空間來(lái)下載源碼、進(jìn)行構(gòu)建,或者做其他需要的處理。這對(duì)于在不同任務(wù)之間進(jìn)行環(huán)境隔離和防止跨域?qū)懭霐?shù)據(jù)是有效果的。然而,當(dāng)將這些任務(wù)鏈接在一起時(shí),可能導(dǎo)致一個(gè)無(wú)效的過(guò)程,克服這個(gè)困難將是一個(gè)挑戰(zhàn)。例如,如果流水線中的多個(gè)任務(wù)都要基于同一個(gè)構(gòu)建好的構(gòu)建物執(zhí)行進(jìn)程,就不得不每次都重新構(gòu)建這個(gè)構(gòu)建物,這是非常低效的。在執(zhí)行這些任務(wù)的過(guò)程中,想要存儲(chǔ)構(gòu)建物到倉(cāng)庫(kù)和從倉(cāng)庫(kù)獲取這些構(gòu)建物,就需要向每個(gè)任務(wù)都添加多個(gè)步驟和配置。一種更有效的策略是,在任務(wù)間共享工作空間——但在傳統(tǒng)的Jenkins中做到這一點(diǎn)并不容易。相反,用戶需要自定義工作空間并使用指向工作空間的參數(shù),或者使用特殊的插件使其工作。專(zhuān)業(yè)知識(shí)正如前面對(duì)共享工作空間的討論所示,用戶通常需要知道在傳統(tǒng)的Jenkins系統(tǒng)中實(shí)現(xiàn)某些東西的“技巧”,而這些在典型的程序或腳本(數(shù)據(jù)傳輸、流控制、外部調(diào)用等)中很容易做到。訪問(wèn)邏輯傳統(tǒng)的Jenkins通常依賴Web表單來(lái)輸入數(shù)據(jù),并將其存儲(chǔ)在主目錄中的XML格式的配置文件中?;谶@種實(shí)現(xiàn),沒(méi)有簡(jiǎn)單的方法可以一目了然地看到執(zhí)行多個(gè)任務(wù)所涉及的邏輯關(guān)聯(lián)。對(duì)于不熟悉它的用戶,要想理解Jenkins設(shè)置或任務(wù)定義,可能需要相當(dāng)多的滾動(dòng)屏幕操作、在表單中查看值、在全局配置之間來(lái)回切換等。這使得需要完成更廣泛的支持、多個(gè)用戶之間的協(xié)作及對(duì)多任務(wù)流水線挑戰(zhàn)的理解,尤其是在需要做大量的更改、審批或調(diào)試的時(shí)候。流水線源管理如前一節(jié)所強(qiáng)調(diào)的,傳統(tǒng)Jenkins的“源”是XML文件。在不使用Web界面的時(shí)候,這不僅難以閱讀,還難以做更改和獲取。配置未被設(shè)計(jì)為與源碼位于同一位置。配置和源碼是兩個(gè)獨(dú)立的實(shí)體,以兩種不同的方式進(jìn)行管理。一個(gè)必然的結(jié)果就是缺乏可審計(jì)性。雖然有插件可以幫助隨時(shí)追蹤變化,但這并不像簡(jiǎn)單地追蹤源文件更改那樣方便,仍然需要Jenkins應(yīng)用程序本身能夠追蹤任務(wù)中的更改。競(jìng)爭(zhēng)一個(gè)額外的因素?zé)o疑在這里發(fā)揮了作用,即使其他應(yīng)用程序支持建立流水線即代碼。有各種例子,例如,Pivotal公司的Concourse使用容器化構(gòu)建任務(wù),并允許在YAML文件中描述流水線。迎接挑戰(zhàn)那么Jenkins2是如何應(yīng)對(duì)這些挑戰(zhàn)的呢?我已經(jīng)提到了一些方法,但是在這里有幾個(gè)值得強(qiáng)調(diào)的點(diǎn)?!ち魉€被視為“一等公民”。這意味著流水線在應(yīng)用程序中是作為實(shí)體被設(shè)計(jì)和支持的,而不是通過(guò)在Jenkins中連接一堆任務(wù)而形成流水線。·流水線可以通過(guò)編碼編程,而不是僅僅通過(guò)配置接口來(lái)描述。這就允許使用額外的邏輯和工作流,以及在傳統(tǒng)Jenkins中不可用或不存在的編程架構(gòu)?!び袑?zhuān)門(mén)用于流水線編程的結(jié)構(gòu)化DSL?!ち魉€可以直接作為一個(gè)腳本在任務(wù)中創(chuàng)建,而不需要任何大量的Web表單交互。此外,它們可以完全在Jenkinsfile中單獨(dú)創(chuàng)建?!ご鎯?chǔ)為Jenkinsfile的流水線現(xiàn)在可獨(dú)立于Jenkins和源碼存儲(chǔ)在一起?!SL有在工作空間中輕松共享文件的功能。·有更先進(jìn)的、內(nèi)置的使用Docker容器的支持。所有這些特性使得維護(hù)和測(cè)試更容易,同時(shí)也具有更大的彈性。我們可以處理具有典型構(gòu)造的異常情況和經(jīng)歷重新啟動(dòng)等事件。在我們進(jìn)一步深入研究Jenkins2的特征之前,我們不妨花點(diǎn)時(shí)間談?wù)勑屡f事物之間的兼容性。兼容性對(duì)于絕大多數(shù)工作項(xiàng),都有相應(yīng)的方法通過(guò)流水線獲得與傳統(tǒng)的Web界面和自由風(fēng)格類(lèi)型任務(wù)相同的功能。事實(shí)上,可能有多種方式,有些是內(nèi)置的,有些是人為的。我們最好通過(guò)簡(jiǎn)短的討論來(lái)描述Jenkins支持創(chuàng)建流水線的兩種不同的語(yǔ)法風(fēng)格。流水線兼容性如前所述,Jenkins2現(xiàn)在支持兩種流水線風(fēng)格——腳本式的和聲明式的——每種都有自己的語(yǔ)法和結(jié)構(gòu)。在接下來(lái)的幾章中,我們將深入研究這兩種類(lèi)型,但現(xiàn)在讓我們來(lái)看一個(gè)具體的例子:在傳統(tǒng)的自由風(fēng)格類(lèi)型的結(jié)構(gòu)中的構(gòu)建后通知以及在腳本式和聲明式流水線中的對(duì)應(yīng)功能。圖1-6顯示了在一個(gè)傳統(tǒng)的自由風(fēng)格類(lèi)型項(xiàng)目中發(fā)送電子郵件通知的典型構(gòu)建后配置操作。在自由風(fēng)格類(lèi)型項(xiàng)目中,有一個(gè)特定的Web元素允許填寫(xiě)字段來(lái)完成配置。圖1-6自由風(fēng)格類(lèi)型項(xiàng)目中的構(gòu)建后操作在腳本式流水線的語(yǔ)法中,我們沒(méi)有一種內(nèi)置的方式來(lái)執(zhí)行這種構(gòu)建后操作。我們被限定于添加通過(guò)Groovy編碼完成一些事情的DSL步驟中。因此,要在構(gòu)建之后總是發(fā)送電子郵件,則需要求助于編碼,如這里所示:假設(shè)我們的電子郵件設(shè)置已經(jīng)在Jenkins中進(jìn)行了全局配置,我們可以使用DSLmail語(yǔ)句發(fā)送電子郵件。因?yàn)樵谀_本語(yǔ)法中沒(méi)有流水線語(yǔ)句/特性來(lái)總是做一些構(gòu)建后操作,所以我們回到Groovy的try-catch-finally語(yǔ)法。這里著重介紹了在使用比如Jenkins的構(gòu)建后操作的功能時(shí)會(huì)遇到的一些兼容性異常情況。DSL結(jié)構(gòu)可能不能處理這種情況。在這些情況下,你可能不得不求助于使用Groovy結(jié)構(gòu)來(lái)模仿Jenkins所要做的處理(這一部分在第3章中會(huì)有更詳細(xì)的說(shuō)明)。如果你選用的是聲明式的流水線結(jié)構(gòu),那么很有可能會(huì)有可用于處理大多數(shù)常見(jiàn)Jenkins功能的結(jié)構(gòu)。例如,在聲明式流水線語(yǔ)法中,有一個(gè)post部分可以用來(lái)定義處理構(gòu)建后操作的步驟,類(lèi)似于傳統(tǒng)的構(gòu)建后進(jìn)程或通知(我們?cè)诘?章中將對(duì)此進(jìn)行更詳細(xì)的說(shuō)明):兼容性問(wèn)題并不只會(huì)在實(shí)際編碼中出現(xiàn)。另一個(gè)值得一提的領(lǐng)域就是插件兼容性。插件兼容性與傳統(tǒng)的Jenkins一樣,Jenkins2的大部分功能是通過(guò)與插件的集成來(lái)提供的。Jenkins2的出現(xiàn)對(duì)插件兼容性有了新的要求。我們大致可以將需求分為兩類(lèi):它們必須能夠在重啟之后繼續(xù)運(yùn)行并提供可用于流水線腳本的高級(jí)API。重啟Jenkins2流水線的特征/需求之一是,它們必須能夠容忍節(jié)點(diǎn)的重新啟動(dòng)。為了支持這一點(diǎn),一個(gè)主要的標(biāo)準(zhǔn)就是,插件中有狀態(tài)的對(duì)象需要被序列化——即能夠記錄它們的狀態(tài)。這在Java或Groovy的很多結(jié)構(gòu)中不是默認(rèn)實(shí)現(xiàn),所以插件可能需要做大量的改動(dòng)來(lái)使其符合這一需求。編寫(xiě)支持重新啟動(dòng)的流水線腳本如果有一段代碼不能被序列化,那么在某些情況下,會(huì)有一些方法可以繞過(guò)它。請(qǐng)參閱第16章關(guān)于如何解決這類(lèi)問(wèn)題的一些建議。提供腳本化的API為了能和編寫(xiě)的流水線腳本兼容,那些之前通過(guò)填寫(xiě)JenkinsWeb表單來(lái)完成的步驟,現(xiàn)在不得不表示為使用可兼容Groovy語(yǔ)法的流水線步驟。在許多情況下,術(shù)語(yǔ)和概念可能接近于表單中使用的內(nèi)容。例如,在基于表單的插件中,F(xiàn)oo是一個(gè)用于文本輸入框的標(biāo)簽,那么現(xiàn)在可能就會(huì)有一個(gè)DSL調(diào)用,其中Foo作為一個(gè)帶值的命名參數(shù)。舉一個(gè)例子,我們將會(huì)用到Artifactory的配置和操作,它是一個(gè)二進(jìn)制構(gòu)建物管理器。圖1-7展示了我們?nèi)绾螢橐粋€(gè)自由風(fēng)格類(lèi)型的Jenkins任務(wù)配置構(gòu)建環(huán)境,以便能夠訪問(wèn)Artifactory倉(cāng)庫(kù)。圖1-7在自由風(fēng)格類(lèi)型任務(wù)中配置Artifactory服務(wù)器下面的代碼是我們?nèi)绾卧诹魉€腳本中做類(lèi)似的配置:除了配置外,我們還有實(shí)際操作需要做。在自由風(fēng)格類(lèi)型任務(wù)中,我們有復(fù)選框和Web表單來(lái)再次告訴Jenkins該怎么做(見(jiàn)圖1-8)。圖1-8在自由風(fēng)格類(lèi)型任務(wù)中指定Artifactory操作而且,在流水線腳本的上下文中,如果插件是流水線兼容的,那么我們可能會(huì)有類(lèi)似的DSL語(yǔ)句來(lái)執(zhí)行API調(diào)用,以提供相同的功能。下面展示了與前面Artifactory自由風(fēng)格類(lèi)型示例相對(duì)應(yīng)的流水線腳本示例:在某些情況下,流水線腳本也可以利用傳統(tǒng)Jenkins接口中已經(jīng)配置了的工作項(xiàng),例如全局性工具。下一個(gè)示例是使用Gradle的示例。在第一個(gè)圖(見(jiàn)圖1-9)中,我們會(huì)看一看Gradle實(shí)例的全局工具配置,然后會(huì)看看它在自由風(fēng)格類(lèi)型項(xiàng)目(見(jiàn)圖1-10)中的使用方法,最后會(huì)看一看它在流水線項(xiàng)目中怎樣通過(guò)一個(gè)被稱為tool的特殊DSL步驟來(lái)調(diào)用,我們能根據(jù)已提供的name參數(shù)返回全局配置。圖1-9Gradle的全局工具配置圖1-10在自由風(fēng)格類(lèi)型項(xiàng)目中使用全局工具Gradle版本聲明式流水線也有一個(gè)tool指令,在該類(lèi)型的流水線中可以具有相同的功能(第7章詳細(xì)討論了聲明式流水線)。全局配置在以前版本的Jenkins中,大多數(shù)的全局配置都是通過(guò)管理Jenkins界面中的配置系統(tǒng)頁(yè)來(lái)設(shè)置的。在當(dāng)前版本的Jenkins中,全局配置分成了系統(tǒng)配置頁(yè)和全局工具配置頁(yè)。開(kāi)始你可能會(huì)有一些疑惑,因?yàn)槟阋涀∧男┎糠中枰綄?duì)應(yīng)的哪個(gè)配置頁(yè)進(jìn)行配置。我使用的竅門(mén)是,把“系統(tǒng)”看作“服務(wù)器”(容易記住,因?yàn)樗鼈兌家浴癝”開(kāi)頭)。一般來(lái)說(shuō),任何類(lèi)型的服務(wù)器設(shè)置或類(lèi)似的任務(wù)都在配置系統(tǒng)頁(yè)完成。此外,如果你認(rèn)為工具通常是單獨(dú)的、可執(zhí)行的應(yīng)用程序(Git、Gradle等),那么這些工具的配置則屬于全局工具配置部分。顯然,這并不是精確的分類(lèi),但當(dāng)你第一次熟悉這種規(guī)則時(shí),它們可以作為一種方便的記憶方式。正如我們所看到的,提供API(也是插件能夠兼容流水線類(lèi)型任務(wù)的原因)是能夠在流水線中執(zhí)行傳統(tǒng)功能的核心點(diǎn)。最終,所有插件都需要做到流水線兼容,但到目前為止,仍然存在不兼容或不完全兼容的插件。不過(guò),也有一些可以讓用戶檢查兼容性的地方。檢查兼容性為了幫助用戶知道現(xiàn)有插件是否與Jenkins2中的流水線兼容,有幾個(gè)站點(diǎn)可用。請(qǐng)注意,這里的信息不保證是最新的,但這些網(wǎng)站可能提供了最好的摘要信息。其中一個(gè)站點(diǎn)就是GitHub,如圖1-11所示的頁(yè)面就是來(lái)自GitHub的示例。圖1-11用于Jenkins插件流水線兼容性的GitHub頁(yè)面另一個(gè)是在Jenkins.io站點(diǎn)上的流水線參考步驟,它列出了流水線兼容的插件。其中一些特別的插件和它們的使用步驟將會(huì)在本書(shū)后面章節(jié)中討論??偨Y(jié)本章對(duì)Jenkins2與傳統(tǒng)Jenkins的不同之處進(jìn)行了簡(jiǎn)要的總結(jié)。對(duì)流水線最核心的支持是,流水線既能作為任務(wù)本身,又能以與Jenkins區(qū)別的Jenkinsfile的形式存在。在為流水線編寫(xiě)代碼時(shí),你可以選擇傳統(tǒng)的、更靈活的腳本式流水線語(yǔ)法或更結(jié)構(gòu)化的聲明式流水線語(yǔ)法。Jenkins2還提供了一些新的項(xiàng)目類(lèi)型。文件夾類(lèi)型允許項(xiàng)目在共享命名空間和共享環(huán)境下組合。多分支流水線類(lèi)型為每個(gè)分支提供簡(jiǎn)單的自動(dòng)化任務(wù)創(chuàng)建和持續(xù)集成,所有這些都是由駐留在分支中的Jenkinsfile文件觸發(fā)的。組織項(xiàng)目類(lèi)型在GitHub或Bitbucket組織結(jié)構(gòu)下的所有項(xiàng)目上擴(kuò)展了多分支流水線類(lèi)型的功能。我們還研究了驅(qū)動(dòng)我們從傳統(tǒng)的Jenkins模型進(jìn)化到以流水線為中心的模型的原因。這些原因包括把流水線作為實(shí)體的需求的增長(zhǎng),也包括通過(guò)Jenkins把多個(gè)任務(wù)整合到一起的挑戰(zhàn)。另一個(gè)因素是傳統(tǒng)Jenkins配置流水線時(shí)與Jenkins應(yīng)用是緊耦合的。最后,我們討論了一些從經(jīng)典的Jenkins升級(jí)到Jenkins2時(shí)要注意的兼容性因素。我們將在本書(shū)中討論各種應(yīng)用程序的細(xì)節(jié),但是先熟悉一下這里所闡述的一般概念,將為你理解并開(kāi)始思考如何轉(zhuǎn)換現(xiàn)有流水線提供良好的基礎(chǔ)。說(shuō)到基礎(chǔ)知識(shí),在第2章中,我們將介紹更多關(guān)于在Jenkins2中使用流水線的基礎(chǔ)知識(shí)。這將有助于你更充分地掌握開(kāi)始使用流水線所需的基本知識(shí)。第2章基礎(chǔ)知識(shí)相信你已經(jīng)了解了構(gòu)成Jenkins2的核心思想,接下來(lái)我們會(huì)繼續(xù)探索Jenkins2是如何支持流水線即代碼的。首先要理解Jenkins為流水線所提供的開(kāi)發(fā)環(huán)境,這包括運(yùn)行流水線的系統(tǒng)以及用于創(chuàng)建、執(zhí)行和監(jiān)視流水線的接口。除此之外,你還需要了解一些關(guān)于流水線基礎(chǔ)結(jié)構(gòu)的知識(shí),以及它們之間是如何相互配合的。這些元素共同構(gòu)成了本書(shū)其余部分的堅(jiān)實(shí)基礎(chǔ)。我們會(huì)重點(diǎn)聚焦在4個(gè)基礎(chǔ)方面來(lái)進(jìn)行介紹?!ち魉€的兩種語(yǔ)法類(lèi)型?!ち魉€的運(yùn)行系統(tǒng)?!ち魉€的基本結(jié)構(gòu)?!enkins為流水線開(kāi)發(fā)和運(yùn)行提供的支持環(huán)境(以及相關(guān)工具)。我們會(huì)從定義和明確一些流水線的關(guān)鍵概念和術(shù)語(yǔ)入手,然后研究流水線所需的DSL結(jié)構(gòu)。在這個(gè)過(guò)程中,我們將學(xué)習(xí)如何使用內(nèi)置編輯器,以及如何使用Jenkins的新工具來(lái)識(shí)別流水線中的語(yǔ)法錯(cuò)誤。一旦你掌握了如何輸入流水線代碼,我們會(huì)執(zhí)行一條流水線并熟悉Jenkins提供的全新視圖。我們還會(huì)研究如何訪問(wèn)流水線日志。最后,我們將探索Jenkins提供的新功能,它允許在無(wú)須修改現(xiàn)有流水線版本的情況下,快速驗(yàn)證流水線的變更。讓我們先從Jenkins2支持的不同流水線語(yǔ)法類(lèi)型開(kāi)始入手。語(yǔ)法:腳本式流水線和聲明式流水線在第1章中,我們分析了Jenkins2對(duì)流水線即代碼進(jìn)行核心支持的動(dòng)因。當(dāng)我們?cè)贘enkins中編輯流水線時(shí),有兩種不同的語(yǔ)法樣式:腳本式語(yǔ)法(scriptedsyntax)和聲明式語(yǔ)法(declarativesyntax)。腳本式語(yǔ)法(scriptedsyntax)是Jenkins最開(kāi)始實(shí)現(xiàn)的流水線即代碼方式。這是一種命令式風(fēng)格,也就是在流水線腳本中定義邏輯和程序流程。它也更依賴于Groovy語(yǔ)言和結(jié)構(gòu),特別是對(duì)于錯(cuò)誤檢查和異常處理來(lái)說(shuō)。聲明式語(yǔ)法(declarativesyntax)是Jenkins提供的一種新的選擇。聲明式風(fēng)格的流水線代碼被編排在清晰的段落中,相對(duì)于只關(guān)注實(shí)現(xiàn)邏輯,這些流水線的主要區(qū)域描述(或“聲明”)了我們所期望的流水線的狀態(tài)和輸出。在下面的代碼示例中,上面是腳本式語(yǔ)法,下面是對(duì)應(yīng)的聲明式語(yǔ)法:你可以這樣理解:腳本式流水線更像是一種腳本或編程語(yǔ)言,像其他命令式語(yǔ)言一樣可以運(yùn)行程序和處理邏輯,而聲明式流水線則更像Jenkins的傳統(tǒng)實(shí)現(xiàn)方式,在Web表單的預(yù)定義字段中輸入關(guān)鍵信息,代表了特定目標(biāo)和預(yù)期行為。與傳統(tǒng)的Web表單類(lèi)似,當(dāng)執(zhí)行聲明式流水線時(shí),每一個(gè)段落定義了基于用戶輸入數(shù)據(jù)的執(zhí)行內(nèi)容和方式。如何選擇腳本式語(yǔ)法和聲明式語(yǔ)法有哪些因素會(huì)影響選擇腳本式語(yǔ)法或聲明式語(yǔ)法呢?和大多數(shù)事情一樣,這也不是一個(gè)嚴(yán)謹(jǐn)?shù)目茖W(xué)問(wèn)題。在特定的情況下,對(duì)比需求、實(shí)現(xiàn)的結(jié)構(gòu)和流程以及構(gòu)建流水線的人員技能和背景,二者可能各有千秋。我們可以通過(guò)分析每種類(lèi)型的優(yōu)缺點(diǎn),獲取普遍規(guī)律和一些參考指導(dǎo)。簡(jiǎn)而言之,腳本式流水線具有以下優(yōu)點(diǎn)?!じ俚拇a段落和弱規(guī)范要求。·更強(qiáng)大的程序代碼能力。·更像編寫(xiě)代碼程序?!鹘y(tǒng)的流水線即代碼模型,用戶熟悉并向后兼容性。·更靈活的自定義代碼操作?!つ軌驑?gòu)建更復(fù)雜的工作流和流水線。腳本式流水線具有以下缺點(diǎn)?!て毡橐蟾叩木幊趟??!ふZ(yǔ)法檢查受限于Groovy語(yǔ)言及環(huán)境?!ず蛡鹘y(tǒng)Jenkins模型有很大差異?!づc聲明式流水線的實(shí)現(xiàn)相比,同一工作流會(huì)更復(fù)雜。聲明式流水線具有以下優(yōu)點(diǎn)?!じY(jié)構(gòu)化,貼近傳統(tǒng)的JenkinsWeb表單形式。·更強(qiáng)大的聲明內(nèi)容能力,高可讀性?!た梢酝ㄟ^(guò)BlueOcean圖形化界面自動(dòng)生成。·段落可映射到常見(jiàn)的Jenkins概念,比如通知?!じ押玫恼Z(yǔ)法檢查和錯(cuò)誤識(shí)別?!ぬ嵘魉€間的一致性。聲明式流水線具有以下缺點(diǎn)?!?duì)迭代邏輯支持較弱(相比程序而言)?!と栽陂_(kāi)發(fā)完善中(對(duì)于傳統(tǒng)Jenkins中的部分功能缺乏支持)?!じ鼑?yán)格的結(jié)構(gòu)(更難實(shí)現(xiàn)自定義流水線代碼)?!つ壳皩?duì)于復(fù)雜的流水線和工作流難以勝任。簡(jiǎn)而言之,對(duì)于新用戶和那些希望流水線具備傳統(tǒng)Jenkins一樣可讀性的用戶來(lái)說(shuō),聲明式流水線更容易學(xué)習(xí)和維護(hù)。這是以靈活性為代價(jià)換取結(jié)構(gòu)不支持的功能。腳本式流水線更加靈活,提供了“超級(jí)用戶”的選項(xiàng),即允許用戶不受結(jié)構(gòu)約束實(shí)現(xiàn)更多功能。不過(guò),總的來(lái)說(shuō),任何一種流水線類(lèi)型對(duì)大多數(shù)場(chǎng)景而言都同樣適用。我們將在第7章中討論更多聲明式語(yǔ)法的細(xì)節(jié),以便更好地理解這個(gè)模型。在本書(shū)中,對(duì)于僅對(duì)特定概念提供的參考示例而言,無(wú)須擔(dān)心語(yǔ)法差異,當(dāng)涉及解釋更加復(fù)雜的結(jié)構(gòu)時(shí),我們會(huì)同時(shí)引入兩種語(yǔ)法的參考示例,以區(qū)分差異。那么現(xiàn)在讓我們繼續(xù)前進(jìn),探索Jenkins用于執(zhí)行流水線的系統(tǒng)。系統(tǒng)(system):主節(jié)點(diǎn)(master)、節(jié)點(diǎn)(node)、代理節(jié)點(diǎn)(agent)和執(zhí)行器(executor)不管我們使用腳本式語(yǔ)法還是聲明式語(yǔ)法,每條Jenkins流水線都必須具備一個(gè)或多個(gè)系統(tǒng)用于執(zhí)行代碼。術(shù)語(yǔ)系統(tǒng)(system)在這里作為一種通用方法描述了我們所有需要討論到的項(xiàng)目(item)。請(qǐng)記住,在任何給定的系統(tǒng)或機(jī)器上都可能運(yùn)行著多個(gè)Jenkins實(shí)例。在傳統(tǒng)Jenkins中只有兩類(lèi)節(jié)點(diǎn):主節(jié)點(diǎn)(master)和從節(jié)點(diǎn)(slave),你可能已經(jīng)非常熟悉這些概念了。下面是對(duì)一些相似概念的描述,主要為了對(duì)比突出差異點(diǎn)。主節(jié)點(diǎn)Jenkins主節(jié)點(diǎn)是一個(gè)Jenkins實(shí)例(instance)的主要控制系統(tǒng)。它能夠完全訪問(wèn)所有Jenkins配置選項(xiàng)和任務(wù)(job)列表。如果沒(méi)有指定其他系統(tǒng)(system),它也是默認(rèn)的任務(wù)執(zhí)行節(jié)點(diǎn)。不過(guò)并不推薦在主節(jié)點(diǎn)上執(zhí)行高負(fù)載任務(wù),任何需要大量處理的任務(wù)都應(yīng)該在主節(jié)點(diǎn)之外的系統(tǒng)上運(yùn)行。這樣做的另一個(gè)原因是,凡是在主節(jié)點(diǎn)上執(zhí)行的任務(wù),都有權(quán)限訪問(wèn)所有的數(shù)據(jù)、配置和操作,這會(huì)構(gòu)成潛在的安全風(fēng)險(xiǎn)。同樣值得注意的是,在主系統(tǒng)上不應(yīng)該執(zhí)行任何包含潛在阻塞的操作,因?yàn)橹飨到y(tǒng)需要持續(xù)響應(yīng)和管理各類(lèi)操作過(guò)程。節(jié)點(diǎn)在Jenkins2中,節(jié)點(diǎn)是一個(gè)基礎(chǔ)概念,代表了任何可以執(zhí)行Jenkins任務(wù)的系統(tǒng)。節(jié)點(diǎn)中包含主節(jié)點(diǎn)和代理節(jié)點(diǎn),有的時(shí)候也用于指代這些概念。此外,節(jié)點(diǎn)也可以是一個(gè)容器,比如Docker。在任何Jenkins實(shí)例中主節(jié)點(diǎn)都會(huì)存在,但是由于上述原因,我們并不推薦在主節(jié)點(diǎn)上執(zhí)行任務(wù)。在本章后面我們會(huì)詳細(xì)討論如何定義節(jié)點(diǎn)。代理節(jié)點(diǎn)在早先版本的Jenkins中,代理節(jié)點(diǎn)被稱為從節(jié)點(diǎn)(slave),其代表了所有非主節(jié)點(diǎn)的系統(tǒng)。這類(lèi)系統(tǒng)由主系統(tǒng)管理,按需分配或指定執(zhí)行特定的任務(wù)。例如,我們可以分配不同的代理節(jié)點(diǎn)針對(duì)不同的操作系統(tǒng)構(gòu)建任務(wù),或者可以分配多個(gè)代理節(jié)點(diǎn)并發(fā)地運(yùn)行測(cè)試任務(wù)。為了減少系統(tǒng)負(fù)載,降低安全風(fēng)險(xiǎn),通常在子系統(tǒng)上只會(huì)安裝一個(gè)輕量級(jí)的Jenkins客戶端應(yīng)用來(lái)處理任務(wù),這個(gè)客戶端應(yīng)用對(duì)資源訪問(wèn)是受限的。隨著代理節(jié)點(diǎn)和節(jié)點(diǎn)之間關(guān)系的演進(jìn),代理節(jié)點(diǎn)在節(jié)點(diǎn)上運(yùn)行。在腳本式流水線中,“節(jié)點(diǎn)”特指一個(gè)運(yùn)行代理節(jié)點(diǎn)的系統(tǒng),而在聲明式流水線中,其指代一個(gè)特定的代理節(jié)點(diǎn)來(lái)分配節(jié)點(diǎn)。指令與步驟根據(jù)節(jié)點(diǎn)和代理節(jié)點(diǎn)在聲明式語(yǔ)法和腳本式語(yǔ)法中的使用方式,我們可以得出這兩個(gè)概念之間的高層次的差異。node用于腳本式流水線,從技術(shù)層面上看它是一個(gè)步驟,代表可以用于流水線中執(zhí)行活動(dòng)的資源。它在一個(gè)運(yùn)行代理節(jié)點(diǎn)的節(jié)點(diǎn)上面分配一個(gè)執(zhí)行器,并進(jìn)一步在定義的代碼塊上運(yùn)行代碼。下面的代碼片段展示了一個(gè)指定node步驟的簡(jiǎn)單示例:而相對(duì)于聲明式流水線中的agent,它作為一個(gè)指令用來(lái)分配節(jié)點(diǎn),除非使用了特殊用法agentnone。下面是一個(gè)簡(jiǎn)單的agent聲明的示例:拋開(kāi)兩種不同的流水線語(yǔ)法規(guī)格,這兩個(gè)概念之間的區(qū)別并不明顯,甚至可以認(rèn)為它們就是一回事。只需要記住node用于腳本式流水線,而agent則用于聲明式流水線就夠了。執(zhí)行器執(zhí)行器同上述所有系統(tǒng)都有關(guān)系。讓我們來(lái)看看Jenkins如何定義這個(gè)術(shù)語(yǔ)。簡(jiǎn)單地說(shuō),執(zhí)行器只是節(jié)點(diǎn)/代理節(jié)點(diǎn)用于執(zhí)行任務(wù)的一個(gè)插槽。一個(gè)節(jié)點(diǎn)可以有任意多個(gè)執(zhí)行器。執(zhí)行器的數(shù)量定義了該節(jié)點(diǎn)可以執(zhí)行的并發(fā)任務(wù)數(shù)量。當(dāng)主節(jié)點(diǎn)將任務(wù)分配給特定節(jié)點(diǎn)時(shí),該節(jié)點(diǎn)上必須有可用的執(zhí)行器插槽來(lái)立即執(zhí)行該任務(wù),否則任務(wù)會(huì)一直處于等待狀態(tài),直到一個(gè)執(zhí)行器變?yōu)榭捎?。?zhí)行器的數(shù)量和其他參數(shù)可以在創(chuàng)建節(jié)點(diǎn)的時(shí)候進(jìn)行配置,后面會(huì)介紹這一主題。圖2-1展示了剛剛談到的各種不同的系統(tǒng)類(lèi)型。圖2-1Jenkins中執(zhí)行任務(wù)的各類(lèi)系統(tǒng)創(chuàng)建節(jié)點(diǎn)在傳統(tǒng)版本的Jenkins中,任務(wù)可以在主節(jié)點(diǎn)實(shí)例或者從節(jié)點(diǎn)實(shí)例上執(zhí)行。在Jenkins2的術(shù)語(yǔ)中,這些實(shí)例被統(tǒng)一成通用術(shù)語(yǔ)“節(jié)點(diǎn)”。建立新節(jié)點(diǎn)和過(guò)去添加從節(jié)點(diǎn)的方法是完全一樣的。下面是一個(gè)簡(jiǎn)單的示例。登錄Jenkins,訪問(wèn)管理Jenkins界面,點(diǎn)擊管理節(jié)點(diǎn)鏈接(見(jiàn)圖2-2)。圖2-2管理Jenkins界面中的管理節(jié)點(diǎn)選項(xiàng)在管理節(jié)點(diǎn)界面中,選擇新節(jié)點(diǎn)并填寫(xiě)表單,包括執(zhí)行器數(shù)量(見(jiàn)圖2-3和圖2-4)。圖2-3節(jié)點(diǎn)基礎(chǔ)配置:選擇節(jié)點(diǎn)的名稱和類(lèi)型圖2-4輸入節(jié)點(diǎn)參數(shù)如果你首先需要建立憑證,可以在第5章中找到更多信息。注意,在界面底部有環(huán)境變量和工具路徑兩個(gè)復(fù)選框。勾選這些復(fù)選框可以為該節(jié)點(diǎn)定義特殊變量和工具。只有當(dāng)你希望使用與主節(jié)點(diǎn)不同的配置時(shí),才會(huì)用到這些復(fù)選框。在標(biāo)簽配置中可以指定多個(gè)標(biāo)簽。標(biāo)簽名中如果包含空格,可以通過(guò)雙引號(hào)來(lái)標(biāo)注。節(jié)點(diǎn)標(biāo)簽的快速參考標(biāo)簽可以滿足系統(tǒng)和用戶的不同需求,比如可以用于以下場(chǎng)景?!ぷR(shí)別一個(gè)特定的節(jié)點(diǎn)(通過(guò)一個(gè)專(zhuān)有標(biāo)簽)?!?duì)一類(lèi)節(jié)點(diǎn)進(jìn)行分組(通過(guò)分配相同的標(biāo)簽)?!ぷR(shí)別節(jié)點(diǎn)的特征,方便使用(通過(guò)一個(gè)有意義的標(biāo)簽,比如“Windows”或者“WestCoast”)。上面的最后一個(gè)場(chǎng)景是推薦場(chǎng)景。標(biāo)簽可以被流水線直接引用,以定義代碼執(zhí)行的位置。具體參考第32頁(yè)“節(jié)點(diǎn)”一節(jié)的示例。更多關(guān)于不同啟動(dòng)方法和節(jié)點(diǎn)配置的信息,請(qǐng)查看Jenkins在線文檔。一旦節(jié)點(diǎn)準(zhǔn)備就緒,我們就可以專(zhuān)注于創(chuàng)建流水線了。我們將通過(guò)JenkinsDSL結(jié)構(gòu)化程序來(lái)實(shí)現(xiàn)這一點(diǎn)。結(jié)構(gòu):使用JenkinsDSL如之前所述,DSL代表領(lǐng)域特定語(yǔ)言(Domain-SpecificLanguage),這是一種針對(duì)特定上下文的程序語(yǔ)言。Jenkins中的上下文用于創(chuàng)建流水線。JenkinsDSL使用Groovy編程語(yǔ)言實(shí)現(xiàn)。相比于其他語(yǔ)言,利用Groovy提供的一些特性可以更加簡(jiǎn)單地創(chuàng)建DSL。然而,這也同樣導(dǎo)致過(guò)分地依賴Groovy語(yǔ)言(請(qǐng)參閱下面的擴(kuò)展內(nèi)容“JenkinsDSL和Groovy語(yǔ)言”)。在本節(jié)中,我們會(huì)介紹一些關(guān)于JenkinsDSL流水線的基本概念、結(jié)構(gòu)和功能。我們會(huì)使用腳本式流水線來(lái)說(shuō)明,這里不包含聲明式功能所添加的增強(qiáng)功能。在第7章中,我們會(huì)介紹兩種語(yǔ)法的差異,查看創(chuàng)建聲明式流水線的變化點(diǎn)。JenkinsDSL和Groovy語(yǔ)言Jenkins流水線的DSL基于Groovy語(yǔ)言實(shí)現(xiàn)。這意味著我們可以按照需求在流水線中使用Groovy語(yǔ)言的結(jié)構(gòu)和習(xí)慣用法。但在通常情況下,我們傾向于避免使用過(guò)于復(fù)雜的Groovy代碼,或者至少將其與主腳本分開(kāi)。這樣做的原因是,使用過(guò)多的Groovy代碼會(huì)降低腳本的可讀性和可維護(hù)性,尤其是對(duì)那些不了解Groovy的人來(lái)說(shuō)。聲明式流水線禁止使用定義結(jié)構(gòu)之外幾乎所有的Groovy代碼,并且還提供了更多類(lèi)似于傳統(tǒng)Jenkins特性的功能,因此你必須盡量減少使用自定義Groovy代碼。使用其他語(yǔ)言如果你需要訪問(wèn)/使用Groovy或其他語(yǔ)言編寫(xiě)的函數(shù),或者引入更加迭代性工作流的函數(shù),你可以讓它們成為共享庫(kù)的一部分,我們將在第6章中討論這部分內(nèi)容。在那里,這部分內(nèi)容將會(huì)從主流水線代碼中被抽象出來(lái)。下面是一個(gè)非常簡(jiǎn)單的JenkinsDSL流水線表達(dá)式:讓我們逐行解釋這部分代碼,說(shuō)明每一部分的作用。節(jié)點(diǎn)首先,我們有一個(gè)關(guān)鍵字node。如同在第27頁(yè)“節(jié)點(diǎn)”一節(jié)中所述的,我們可以將節(jié)點(diǎn)視為主節(jié)點(diǎn)或代理節(jié)點(diǎn)的一種新的表述方式。節(jié)點(diǎn)在管理Jenkins→管理節(jié)點(diǎn)界面中定義,操作方法和之前添加從節(jié)點(diǎn)的方法完全一致。每一個(gè)節(jié)點(diǎn)都會(huì)自動(dòng)安裝Jenkins代理節(jié)點(diǎn)來(lái)執(zhí)行任務(wù)(注意,這里假設(shè)在Jenkins實(shí)例中已經(jīng)添加了一個(gè)節(jié)點(diǎn),并打上了worker1標(biāo)簽)。節(jié)點(diǎn)和代理節(jié)點(diǎn)在之前的Jenkins術(shù)語(yǔ)部分,我們已經(jīng)介紹了節(jié)點(diǎn)和代理節(jié)點(diǎn)的區(qū)別。在這一部分中,代理節(jié)點(diǎn)特指在“非主節(jié)點(diǎn)”上運(yùn)行Jenkins代碼。這一行告訴Jenkins應(yīng)該在哪個(gè)節(jié)點(diǎn)上運(yùn)行這部分流水線。它將代碼與節(jié)點(diǎn)上運(yùn)行的Jenkins代理程序綁定起來(lái)。通過(guò)將定義的名稱作為參數(shù)(標(biāo)簽)傳遞進(jìn)來(lái)指定特定節(jié)點(diǎn)。這個(gè)節(jié)點(diǎn)或系統(tǒng)必須已被定義,并且Jenkins系統(tǒng)知曉它的存在。在這里你可以選擇不提供標(biāo)簽,但是如果忽略標(biāo)簽,則需要了解它的運(yùn)作機(jī)制?!と绻鹠aster被配置為默認(rèn)的執(zhí)行節(jié)點(diǎn),那么Jenkins會(huì)在master上執(zhí)行任務(wù)(可以配置master為不執(zhí)行任何任務(wù))?!し駝t,節(jié)點(diǎn)標(biāo)簽為空(或者在聲明式語(yǔ)法中使用agentany),Jenkins會(huì)在任意節(jié)點(diǎn)上找到第一個(gè)可用的執(zhí)行器來(lái)執(zhí)行任務(wù)。換言之,如果在這里指定多個(gè)名稱(使用邏輯運(yùn)算符)也是完全有效的,尤其當(dāng)你需要基于多個(gè)維度來(lái)選擇節(jié)點(diǎn)的時(shí)候(如地點(diǎn)、類(lèi)型等)很有意義。下面的擴(kuò)展內(nèi)容介紹了如何使用這項(xiàng)功能。為一個(gè)節(jié)點(diǎn)打多重標(biāo)簽在節(jié)點(diǎn)配置中,你可以在標(biāo)簽輸入框中指定多個(gè)標(biāo)簽,通常使用空格分隔。當(dāng)在流水線中指定一個(gè)節(jié)點(diǎn)來(lái)執(zhí)行任務(wù)的時(shí)候,你可以使用標(biāo)準(zhǔn)的邏輯運(yùn)算符來(lái)指定多個(gè)標(biāo)簽,比如,“||”表示或,“&&”表示與。為什么要這么做呢?假設(shè)你分別在美國(guó)的東西海岸擁有兩套Linux系統(tǒng)。基于某些特定的操作場(chǎng)景,你可能希望某些Jenkins任務(wù)被發(fā)送到東海岸,而另一些則在西海岸執(zhí)行。那么在這個(gè)場(chǎng)景中,你可以為所有節(jié)點(diǎn)添加Linux標(biāo)簽,同時(shí)附加一個(gè)新的標(biāo)簽來(lái)表示所在地域,如east或west。一旦標(biāo)簽就緒,你就可以通過(guò)操作符和標(biāo)簽的組合來(lái)指定節(jié)點(diǎn)。例如,一個(gè)任務(wù)需要在東海岸的Linux節(jié)點(diǎn)執(zhí)行,可以這樣描述:Jenkins也提供了更加復(fù)雜的運(yùn)算符,相關(guān)說(shuō)明可以在node步驟的說(shuō)明文檔中找到。這種大括號(hào)結(jié)構(gòu)({})被稱為Groovy閉包,標(biāo)記了流水線中與該節(jié)點(diǎn)關(guān)聯(lián)的代碼起止段落。閉包也類(lèi)似于程序中傳遞的實(shí)體,最后一個(gè)語(yǔ)句代表了返回值。(請(qǐng)參閱Groovy文檔以獲取更多關(guān)于閉包的信息。)當(dāng)這部分流水線被執(zhí)行時(shí),它會(huì)自動(dòng)連接到指定節(jié)點(diǎn)并為執(zhí)行代碼創(chuàng)建一個(gè)工作空間(工作目錄),當(dāng)執(zhí)行器空閑時(shí),就會(huì)在該目錄中執(zhí)行代碼。節(jié)點(diǎn)和映射除了定義節(jié)點(diǎn)來(lái)執(zhí)行指定階段任務(wù),節(jié)點(diǎn)還可以通過(guò)映射指定其他部分代碼的執(zhí)行位置,比如,下面是一個(gè)parallel結(jié)構(gòu)的示例:階段在節(jié)點(diǎn)的定義中,我們可以將個(gè)人設(shè)置、DSL命令和邏輯組合在一個(gè)stage閉包中。階段必須指定一個(gè)name,這提供了一種機(jī)制,可以用來(lái)描述這個(gè)階段的職責(zé)?,F(xiàn)有的階段實(shí)質(zhì)上并沒(méi)有在腳本中做什么事情,僅在運(yùn)行流水線時(shí)在輸出中標(biāo)識(shí)出這個(gè)階段的位置。研發(fā)人員可以決定在一個(gè)特定階段中包含多少流水線邏輯。然而,一個(gè)通用的實(shí)踐是創(chuàng)建階段來(lái)模仿傳統(tǒng)流水線中的任務(wù)片段。例如,我們可以設(shè)計(jì)一個(gè)階段來(lái)獲取源碼,一個(gè)階段來(lái)編譯源碼,一個(gè)階段來(lái)執(zhí)行單元測(cè)試,一個(gè)階段來(lái)執(zhí)行集成測(cè)試等。我們將使用這種結(jié)構(gòu)來(lái)演示本書(shū)中所有的示例流水線。步驟階段中包含了實(shí)際的JenkinsDSL命令,這在Jenkins術(shù)語(yǔ)中被稱為步驟(step)。一個(gè)步驟是DSL定義中最基本的功能。它雖然不是Groovy命令,但是可以和Groovy命令搭配使用。在以下示例中,我們通過(guò)初始步驟來(lái)獲取源碼:這種語(yǔ)法非常簡(jiǎn)單易懂,調(diào)用git指令并傳遞給它拉取代碼的地址參數(shù)(使用安全的HTTP協(xié)議)。對(duì)完整的步驟語(yǔ)法而言,這是一種縮寫(xiě)格式。當(dāng)在腳本中使用DSL時(shí),步驟的縮寫(xiě)格式和完整格式語(yǔ)法都會(huì)碰到,所以有必要花點(diǎn)時(shí)間來(lái)更好地理解語(yǔ)法模型的細(xì)節(jié)。理解步驟語(yǔ)法JenkinsDSL中的步驟總是期望映射(命名)參數(shù)。為了說(shuō)明這一點(diǎn),下面有另一個(gè)版本的git步驟的定義:請(qǐng)注意,在這里有兩個(gè)命名參數(shù),其映射到期望的值:branch等于'test',url等于實(shí)際上,這種語(yǔ)法本身是Groovy所使用的映射語(yǔ)法的一種簡(jiǎn)寫(xiě)形式。[命名參數(shù):value,命名參數(shù):value]等同于[key:value,key:value]的Groovy映射語(yǔ)法。其中命名參數(shù)函數(shù)作為映射的關(guān)鍵字。Groovy還允許跳過(guò)參數(shù)的圓括號(hào)。如果沒(méi)有這些快捷方式,較長(zhǎng)版本的步驟將是這樣的:另一個(gè)小技巧:如果只有一個(gè)必選參數(shù),同時(shí)只傳遞一個(gè)數(shù)值,那么參數(shù)名稱可以被省略。這就是我們?nèi)绾螌?shí)現(xiàn)簡(jiǎn)寫(xiě)版本的步驟的方法:在本例中只有url參數(shù)是必選參數(shù)。如果沒(méi)有命名參數(shù),那么默認(rèn)的參數(shù)就是script對(duì)象。下面的示例是一個(gè)bat步驟,在Windows系統(tǒng)上運(yùn)行批處理或shell腳本。按照標(biāo)準(zhǔn)完整版語(yǔ)法,命令類(lèi)似如下:這個(gè)命令可以簡(jiǎn)寫(xiě):圖2-5以圖形化的方式展示了節(jié)點(diǎn)、階段和步驟三者之間的關(guān)系。圖2-5節(jié)點(diǎn)、階段和步驟之間的關(guān)系現(xiàn)在我們已經(jīng)理解了腳本式流水線的基本結(jié)構(gòu),接下來(lái)讓我們創(chuàng)建一個(gè)Jenkins流水線任務(wù),并使用相關(guān)工具創(chuàng)建一個(gè)腳本。支持環(huán)境:開(kāi)發(fā)一個(gè)流水線腳本不管是哪個(gè)版本的Jenkins,我們都是通過(guò)新建一個(gè)指定類(lèi)型的項(xiàng)目來(lái)開(kāi)始一個(gè)新項(xiàng)目的。Jenkins2內(nèi)置了流水線類(lèi)型的項(xiàng)目支持。這種類(lèi)型的項(xiàng)目提供了編寫(xiě)代碼來(lái)定義流水線的環(huán)境。在剛開(kāi)始接觸這類(lèi)項(xiàng)目的時(shí)候,理解如何配置和使用環(huán)境創(chuàng)建、編輯、運(yùn)行和監(jiān)控流水線是很有幫助的。Jenkins的流水線腳本既可以在流水線類(lèi)型的Jenkins任務(wù)中創(chuàng)建,也可以定義在一個(gè)叫作Jenkinsfile的外部文件中。Jenkinsfile可以同代碼保存在一起。我們會(huì)采用在流水線任務(wù)中創(chuàng)建腳本的方式來(lái)學(xué)習(xí)創(chuàng)建DSL腳本。Jenkinsfile可以在任何文本編輯器中創(chuàng)建,當(dāng)然也可以從流水線任務(wù)中復(fù)制生成。然而,在調(diào)用外部資源等任務(wù)時(shí),流水線也需要進(jìn)行相關(guān)調(diào)整。我們會(huì)在第10章中詳細(xì)介紹Jenkinsfile時(shí)深入討論此類(lèi)問(wèn)題。創(chuàng)建一個(gè)流水線項(xiàng)目當(dāng)創(chuàng)建流水線類(lèi)型的項(xiàng)目時(shí),你會(huì)看到一個(gè)基于Web表單形式的新項(xiàng)目配置頁(yè)面。每個(gè)主要的配置部分都有一個(gè)對(duì)應(yīng)的選項(xiàng)卡。你可以從基礎(chǔ)設(shè)置(General)選項(xiàng)卡開(kāi)始入手(見(jiàn)圖2-6)。標(biāo)簽和導(dǎo)航部分標(biāo)簽可用于主要部分之間的快速跳轉(zhuǎn)。當(dāng)然你依然可以滾動(dòng)鼠標(biāo)找到對(duì)應(yīng)的部分。圖2-6一個(gè)新的流水線項(xiàng)目的基礎(chǔ)設(shè)置選項(xiàng)卡如果你使用過(guò)Jenkins,那么對(duì)基礎(chǔ)設(shè)置選項(xiàng)卡配置應(yīng)該并不陌生。你可以按需進(jìn)行選項(xiàng)卡配置,或者干脆使用默認(rèn)配置。對(duì)于新的流水線項(xiàng)目來(lái)說(shuō),我們會(huì)更加關(guān)心流水線選項(xiàng)卡。切換到這個(gè)選項(xiàng)卡,我們會(huì)看到一個(gè)文本框用于輸入流水線腳本代碼。圖2-7展示了一個(gè)簡(jiǎn)單的在該選項(xiàng)卡窗口中輸入流水線腳本的示例。圖2-7流水線選項(xiàng)卡以及一個(gè)簡(jiǎn)單的腳本示例在Jenkins內(nèi)置編輯器中輸入流水線代碼??梢暬庉嬈麟S著全新的BlueOcean界面和聲明式流水線的出現(xiàn),Jenkins提供了一個(gè)可視化流水線編輯器。關(guān)于BlueOcean界面和編輯器,我們將在第9章中介紹。編輯器使用編輯器之前需要熟悉一些有用的特性。語(yǔ)法檢查編輯器會(huì)嘗試檢查Groovy語(yǔ)法和引用的有效性。如圖2-8所示,所有的問(wèn)題都會(huì)在對(duì)應(yīng)代碼行前面通過(guò)紅色的“X”方框標(biāo)記提示出來(lái)。圖2-8流水線腳本窗口中的錯(cuò)誤提示然而,并非所有的錯(cuò)誤標(biāo)記都代表真正的錯(cuò)誤,在某些時(shí)候腳本可能無(wú)法解析依賴或最近創(chuàng)建的輸入,這是一個(gè)異常而非規(guī)則。擴(kuò)展錯(cuò)誤信息雖然X標(biāo)記提供了一個(gè)快速識(shí)別問(wèn)題行的方法,但是還缺少必要的錯(cuò)誤信息。你可以將鼠標(biāo)光標(biāo)懸停在X標(biāo)記上來(lái)查看更多信息。當(dāng)這樣操作時(shí),會(huì)在彈出框中顯示完整的錯(cuò)誤信息(見(jiàn)圖2-9)。圖2-9懸停顯示完整的錯(cuò)誤信息自動(dòng)補(bǔ)全編輯器同樣提供了自動(dòng)補(bǔ)全功能,比如自動(dòng)補(bǔ)全括號(hào)。當(dāng)輸入了一個(gè)左大括號(hào){時(shí),系統(tǒng)會(huì)相應(yīng)地補(bǔ)充一個(gè)右大括號(hào)}(見(jiàn)圖2-10)。雖然這是一個(gè)非常便利的特性,但你仍然需要一段時(shí)間來(lái)適應(yīng)。因?yàn)槿绻懔?xí)慣于手動(dòng)輸入右大括號(hào),而系統(tǒng)再補(bǔ)充一個(gè)的話,會(huì)導(dǎo)致一個(gè)額外的大括號(hào),且不參與編譯。圖2-10自動(dòng)補(bǔ)全大括號(hào)除編輯器外,還有一個(gè)工具可以幫助我們搞定正確的語(yǔ)法。這就是代碼片段生成器。使用代碼片段生成器從Web表單的任務(wù)配置切換到DSL流水線腳本有很多優(yōu)點(diǎn),但是必須了解每個(gè)步驟和任務(wù)的正確語(yǔ)法顯然不在其中。某些情況的語(yǔ)法和參數(shù)相對(duì)直觀,比如前面介紹過(guò)的簡(jiǎn)單的git步驟,但是對(duì)于其他情況,可能并非如此。為了簡(jiǎn)化尋找步驟的正確語(yǔ)義和語(yǔ)法,Jenkins2提供了一個(gè)流水線語(yǔ)法幫助向?qū)В簿褪墙酉聛?lái)要介紹的代碼片段生成器。代碼片段生成器內(nèi)容代碼片段生成器內(nèi)容基于流水線步驟的定義來(lái)生成和更新,這些定義來(lái)源于插件的支持。如果一個(gè)插件提供了流水線兼容步驟,它就會(huì)被包含在代碼片段生成器中。這也就意味著,在任意一臺(tái)Jenkins實(shí)例上的代碼片段生成器的內(nèi)容,實(shí)際上是由這個(gè)實(shí)例上安裝了哪些插件來(lái)決定的。代碼片段生成器提供了一種搜索可用的DSL步驟的方法,可以找出感興趣步驟的語(yǔ)義和語(yǔ)法。與此同時(shí),它還提供了在線幫助來(lái)解釋每一個(gè)步驟的意圖。但是它所提供的最有用的選項(xiàng)是一個(gè)基于Web表單的頁(yè)面,在這個(gè)頁(yè)面錄入要使用的參數(shù)數(shù)值,通過(guò)一鍵點(diǎn)擊來(lái)生成該步驟所需的GroovyDSL代碼,這樣就可以復(fù)制/粘貼代碼片段到程序中。這大大簡(jiǎn)化了使用特定步驟的嘗試。讓我們通過(guò)一個(gè)簡(jiǎn)單的示例來(lái)看看它是如何工作的。假設(shè)我們希望創(chuàng)建一個(gè)更早的步驟來(lái)獲取存放在Git倉(cāng)庫(kù)中的代碼。圖2-11展示了這個(gè)示例的初始狀態(tài)。圖2-11源碼拉取的代碼塊我們要使用Git,但并不確定相關(guān)語(yǔ)法,這時(shí)候可以點(diǎn)擊流水線選項(xiàng)卡窗口底部的流水線語(yǔ)法鏈接,如圖2-12所示,就會(huì)打開(kāi)代碼片段生成器界面。圖2-12代碼片段生成器在示例步驟下拉列表框中選擇git步驟,如圖2-13所示。代碼片段生成器會(huì)提供一些該步驟相關(guān)的參數(shù)輸入框。我們可以使用默認(rèn)的參數(shù)或者按需指定參數(shù)值,最后點(diǎn)擊按鈕生成流水線腳本,結(jié)果和我們之前看到的git步驟的示例是一樣的。圖2-13使用git步驟的默認(rèn)參數(shù)生成流水線代碼將生成的代碼片段添加到stage閉包中,可得到如下代碼:另外,如果我們希望覆蓋git步驟的默認(rèn)值,那么生成的代碼也會(huì)發(fā)生相應(yīng)的變化,在本例中可以通過(guò)取消勾選復(fù)選框來(lái)實(shí)現(xiàn)覆蓋(見(jiàn)圖2-14)。圖2-14覆蓋git步驟的默認(rèn)值如果要指定多個(gè)參數(shù),那么這些參數(shù)必須有對(duì)應(yīng)的名字。之前示例中的代碼片段可以直接復(fù)制/粘貼到一個(gè)腳本中使用。輪詢和變更日志選項(xiàng)將poll選項(xiàng)設(shè)置為false,意味著源碼控制倉(cāng)庫(kù)中的變更將無(wú)法自動(dòng)檢測(cè)和重新構(gòu)建。否則,如果輪詢功能打開(kāi),在第一次運(yùn)行完成后,源碼控制倉(cāng)庫(kù)中的變更將被自動(dòng)檢測(cè),并觸發(fā)另一次任務(wù)的執(zhí)行。將changelog選項(xiàng)設(shè)置成false,意味著Jenkins將不會(huì)自動(dòng)獲取變更記錄,也不會(huì)在任務(wù)輸出的Changes部分中顯示。這么做唯一的好處在于,它可以減輕對(duì)版本控制系統(tǒng)的壓力。運(yùn)行一條流水線在完成代碼輸入后,流水線已經(jīng)準(zhǔn)備就緒。流水線一般由多個(gè)階段組成,包括編譯、集成測(cè)試、代碼分析等。在傳統(tǒng)版本的Jenkins的典型場(chǎng)景中,我們可以將每個(gè)部分作為一個(gè)獨(dú)立的自由風(fēng)格類(lèi)型任務(wù),并將這些任務(wù)連接在一起,在一個(gè)任務(wù)執(zhí)行完畢后自動(dòng)觸發(fā)下一個(gè)任務(wù)。一直以來(lái),我們都是通過(guò)編寫(xiě)插件來(lái)實(shí)現(xiàn)各個(gè)階段任務(wù)流程的可視化的。其中一個(gè)常用的插件是構(gòu)建流水線(BuildPipeline)。這個(gè)插件可以創(chuàng)建一個(gè)特殊視圖來(lái)顯示一系列關(guān)聯(lián)的流水線任務(wù)。任務(wù)就像一組連接在一起的方塊,并根據(jù)當(dāng)前狀態(tài)使用顏色編碼:藍(lán)色表示尚未運(yùn)行,黃色表示正在運(yùn)行,綠色表示運(yùn)行成功,紅色表示運(yùn)行失敗。圖2-15展示了插件的效果。圖2-15原始的構(gòu)建流水線插件在Jenkins2中,全新的流水線項(xiàng)目類(lèi)型可用于編寫(xiě)整條流水線。比如,之前處理git命令的示例,我們可以使用stage{}代碼塊來(lái)表示流水線中的主要部分。為了進(jìn)一步說(shuō)明這一點(diǎn),讓我們?cè)诹魉€中添加一個(gè)新的階段。為了讓示例盡可能簡(jiǎn)單(因?yàn)槟壳斑€沒(méi)有涉及流水線的全局工具配置部分),在這里僅僅為構(gòu)建步驟添加一個(gè)占位符。為了實(shí)現(xiàn)這個(gè)需求,讓我們添加一個(gè)新的階段定義,并且插入一個(gè)sh步驟,這個(gè)步驟用于打印信息(sh表示shell,允許我們?cè)?nix系統(tǒng)中調(diào)用,對(duì)應(yīng)的Windows系統(tǒng)命令是bat):圖2-16顯示了流水線選項(xiàng)卡窗口中的腳本。圖2-16流水線選項(xiàng)卡窗口中的腳本當(dāng)?shù)谝淮伪4孢@條流水線時(shí),UI界面會(huì)提示流水線尚未執(zhí)行(見(jiàn)圖2-17),并顯示信息沒(méi)有可用數(shù)據(jù),流水線尚未執(zhí)行。請(qǐng)注意,提示信息上面的階段視圖(StageView),這是Jenkins2引入的一種全新的流水線默認(rèn)輸出視圖。圖2-17第一次運(yùn)行之前選擇左側(cè)菜單中的立即構(gòu)建菜單項(xiàng),Jenkins就會(huì)開(kāi)始運(yùn)行流水線構(gòu)建過(guò)程。在這個(gè)示例中,所有步驟都執(zhí)行成功。注意,任務(wù)執(zhí)行結(jié)果在階段視圖中以方塊的形式顯示,如圖2-18所示。綠色的方塊表示執(zhí)行成功,關(guān)于這個(gè)視圖的詳細(xì)解釋?zhuān)瑢?huì)在后面介紹。圖2-18第一次成功運(yùn)行每次構(gòu)建時(shí),Jenkins都會(huì)為流水線中的每個(gè)階段創(chuàng)建一個(gè)新的方塊。其中每一行代表了該項(xiàng)目的一次構(gòu)建,每一列代表了流水線中的各個(gè)階段。也就是說(shuō),每個(gè)方塊都代表了一個(gè)特定階段的一次執(zhí)行結(jié)果。注意,我們可以在每一列的頂部看到對(duì)應(yīng)stage步驟的參數(shù)(name),并且每個(gè)階段的執(zhí)行耗時(shí)也會(huì)在方塊內(nèi)部展示。正如我們剛才提到的,方塊的顏色非常重要。顏色代碼的一般含義如表2-1所示。表2-1顏色含義運(yùn)行中的顏色變化即便一個(gè)方塊在某一時(shí)間被標(biāo)記為綠色,如果下游階段執(zhí)行失敗,它仍然有可能會(huì)變?yōu)榧t色。查看日志在傳統(tǒng)的Jenkins中,你可以通過(guò)點(diǎn)擊控制臺(tái)輸出鏈接或者構(gòu)建歷史窗口中構(gòu)建旁邊的狀態(tài)球來(lái)查看控制臺(tái)輸出。階段視圖同樣提供了一種快捷方式來(lái)查看特定階段的執(zhí)行日志。你只需要在感興趣的階段和構(gòu)建方塊上懸停鼠標(biāo),然后點(diǎn)擊出現(xiàn)的日志按鈕,就可以在一個(gè)彈出窗口中查看該階段的執(zhí)行日志。圖2-19和圖2-20演示了這個(gè)步驟。圖2-19在方塊上懸停鼠標(biāo)獲得日志按鈕圖2-20點(diǎn)擊日志按鈕,在彈出窗口中獲取該階段的真實(shí)日志Jenkins彈出窗口和自動(dòng)刷新由于日志顯示在彈出窗口中,你可能需要關(guān)閉自動(dòng)刷新功能,即便打開(kāi)這個(gè)功能,也不會(huì)自動(dòng)關(guān)閉日志彈出窗口??梢渣c(diǎn)擊右上角的DISABLEAUTOREFRESH(關(guān)閉自動(dòng)刷新)來(lái)實(shí)現(xiàn)這個(gè)功能。運(yùn)行失敗的階段視圖接下來(lái)讓我們看看帶有錯(cuò)誤信息的階段視圖是什么樣的。假設(shè)在Windows而非Linux系統(tǒng)中運(yùn)行代碼,流水線需要有一處細(xì)節(jié)變更,也就是將替換為現(xiàn)在假設(shè)我們使用bat命令將代碼完全復(fù)制到Linux系統(tǒng)。當(dāng)嘗試構(gòu)建時(shí),就會(huì)得到如圖2-21所示的階段視圖。圖2-21運(yùn)行失敗的階段視圖注意,第二次運(yùn)行會(huì)在矩陣中添加一行,最新一次運(yùn)行顯示在頂部。頂部行中Build塊的紅色條紋顏色表明該階段失敗了(因此我們的運(yùn)行失敗了),而淺紅色的Source階段表明雖然它運(yùn)行成功,但是下游某個(gè)階段出現(xiàn)失敗。當(dāng)前置階段失敗時(shí)如果Source階段運(yùn)行失敗,那么Build階段就不會(huì)運(yùn)行。這時(shí)候,Source階段會(huì)被標(biāo)記為紅色條紋,而B(niǎo)uild階段則保持白色。我們可以采用相同的步驟來(lái)查看錯(cuò)誤信息,鼠標(biāo)懸停在失敗的方塊上,彈出窗口中會(huì)顯示日志鏈接,同時(shí)也會(huì)給出失敗的信息。在彈出窗口的頂端給出了如下提示——發(fā)生如下錯(cuò)誤,WindowsBashScriptBatch腳本只能在Windows節(jié)點(diǎn)上運(yùn)行。圖2-22顯示了這個(gè)情況。圖2-22查看階段的失敗信息Jenkins會(huì)嘗試在彈出窗口中給出有意義的錯(cuò)誤信息。我們同樣可以點(diǎn)擊日志按鈕來(lái)打開(kāi)日志,但是在這個(gè)示例中,因?yàn)樵撾A段中的第一條語(yǔ)句執(zhí)行失敗,所以日志中并沒(méi)有其他有用的運(yùn)行信息。至此,我們基本完成了Jenkins2的快速介紹,以及在編寫(xiě)流水線時(shí)需要了解的基礎(chǔ)特性。不過(guò),Jenkins還提供了一個(gè)特性,可以幫助我們?cè)跓o(wú)須改變已經(jīng)保存的流水線代碼的基礎(chǔ)上進(jìn)行試驗(yàn)和調(diào)試。我們將這個(gè)特性稱為回放(Replay)?;胤旁贘enkins中編寫(xiě)流水線代碼相對(duì)于傳統(tǒng)的Web表單形式在用戶交互方面有了大幅進(jìn)展。當(dāng)錯(cuò)誤發(fā)生時(shí),我們希望用一種臨時(shí)方法進(jìn)行重試,而不是每次都要修改并保存代碼,或者有時(shí)我們希望在正式提交代碼之前進(jìn)行一次變更的快速驗(yàn)證并查看效果。Jenkins2的回放功能正是針對(duì)這種情況而設(shè)計(jì)的?;胤殴δ芸梢宰屇阍谝淮芜\(yùn)行結(jié)果的基礎(chǔ)上修改代碼并再次觸發(fā)流水線。這會(huì)保存一次全新的構(gòu)建記錄,但原始代碼依然保持從前的狀態(tài)。下面讓我們來(lái)看看將這個(gè)特性用于當(dāng)前的失敗。假設(shè)我們認(rèn)為正確的步驟使用的是sh,但是希望先嘗試運(yùn)行一下再完成代碼變更。那么首先切換到任務(wù)的控制臺(tái)輸出頁(yè)面,然后選擇左側(cè)菜單中的回放菜單項(xiàng),如圖2-23所示。圖2-23回放菜單項(xiàng)的位置這時(shí)Jenkins會(huì)彈出一個(gè)同流水線項(xiàng)目的流水線選項(xiàng)卡一樣的編輯窗口(見(jiàn)圖2-24)。在這個(gè)窗口中,我們可以任意修改程序,并點(diǎn)擊運(yùn)行按鈕來(lái)驗(yàn)證變更效果(在這里將bat修改回sh)。圖2-24回放一次失敗的運(yùn)行過(guò)程Jenkins會(huì)嘗試在回放窗口中運(yùn)行編輯后的代碼。在本例中修改后的代碼運(yùn)行成功,同時(shí)創(chuàng)建了第3次執(zhí)行記錄(見(jiàn)圖2-25)。圖2-25一次成功的回放然而,如果我們?cè)谧髠?cè)的菜單中選擇配置并返回查看流水線選項(xiàng)卡窗口中的代碼,會(huì)發(fā)現(xiàn)代碼中依然使用了bat(見(jiàn)圖2-26)?;胤殴δ芸梢詭椭覀凃?yàn)證變更,但是依然需要手動(dòng)更新流水線任務(wù)的代碼來(lái)讓這次變更生效。圖2-26原始代碼沒(méi)有發(fā)生變化在命令行中進(jìn)行回放Jenkins提供了一個(gè)基于客戶端JAR包的命令行接口(CLI,command-lineinterface)(詳見(jiàn)第15章)。同時(shí)命令行接口也提供了一個(gè)replay-pipeline命令。下面是一個(gè)使用命令行接口方式從Jenkinsfile進(jìn)行回放的示例:回放和源碼的版本截至本書(shū)編寫(xiě)的時(shí)候,如果你在流水線代碼中使用了SCM步驟(比如git步驟),即便回放了一個(gè)早先的運(yùn)行,但是每次回放都會(huì)從配置管理倉(cāng)庫(kù)中拉取最新的代碼。如果在Jenkinsfile中使用了更加通用的checkoutscm步驟的代碼(將在第10章中討論),那么回放會(huì)拉取當(dāng)前時(shí)間節(jié)點(diǎn)的代碼。流水線測(cè)試框架無(wú)論對(duì)于新人還是經(jīng)驗(yàn)豐富的用戶,大家都會(huì)關(guān)心是否存在一個(gè)框架來(lái)測(cè)試流水線。在2017年年初,一項(xiàng)名為Jenkins流水線單元測(cè)試框架的工作就已啟動(dòng)。截至2017年秋季,這個(gè)框架已經(jīng)被納入Jenkins項(xiàng)目中。你可以在GitHub上找到其最新的代碼和文檔。那么它實(shí)現(xiàn)了哪些功能呢?在項(xiàng)目描述中提到,這個(gè)測(cè)試框架可以幫助你編寫(xiě)流水線代碼配置和邏輯判斷方面的單元測(cè)試,并提供一個(gè)模擬流水線執(zhí)行的功能。你可以模擬內(nèi)建的Jenkins命令、任務(wù)配置,查看整個(gè)執(zhí)行的堆棧,甚至追蹤回退。文檔頁(yè)面上的示例給出了針對(duì)流水線中包括共享庫(kù)在內(nèi)的功能的測(cè)試方法?;镜膱?zhí)行機(jī)制是將流水線單元類(lèi)導(dǎo)入Gradle或Maven項(xiàng)目中,并以類(lèi)似JUnit測(cè)試的方式執(zhí)行。基本的測(cè)試功能允許生成可通過(guò)程序搜索和比較的堆棧調(diào)用信息。這個(gè)項(xiàng)目擁有很好的前景,但就目前而言并不簡(jiǎn)單、易用。它需要將流水線代碼封裝在任務(wù)或者結(jié)構(gòu)中,來(lái)模擬外部例程加載和執(zhí)行的效果。值得注意的是,大多數(shù)流水線步驟都需要采用特殊的映射代碼方式來(lái)進(jìn)行模擬。當(dāng)前這個(gè)項(xiàng)目可作為一個(gè)有效的選項(xiàng),該框架的使用對(duì)于典型用戶來(lái)說(shuō)依然是一個(gè)挑戰(zhàn),但將不斷完善,所以我們?cè)谶@里不詳細(xì)展開(kāi)。展望未來(lái),既然項(xiàng)目的所有者已經(jīng)轉(zhuǎn)移到Jenkins社區(qū),我們有理由期待這個(gè)項(xiàng)目可以更加簡(jiǎn)單、易用,為流水線用戶創(chuàng)造更大的價(jià)值??偨Y(jié)在本章中,我們介紹了開(kāi)始使用Jenkins2所需要了解的基本概念。自頂向下地探索了兩種流水線語(yǔ)法模型的差異(腳本式流水線和聲明式流水線),澄清了流水線執(zhí)行中的不同系統(tǒng)類(lèi)型,檢查了腳本式流水線的核心結(jié)構(gòu),并且介紹了開(kāi)發(fā)流水線會(huì)用到的環(huán)境和工具。這部分內(nèi)容無(wú)論對(duì)于日常工作還是繼續(xù)學(xué)習(xí)本書(shū)剩余內(nèi)容而言都是一個(gè)堅(jiān)實(shí)的基礎(chǔ)。我們會(huì)在后續(xù)章節(jié)中深入更多的細(xì)節(jié),前提是你已經(jīng)充分掌握了本章中的知識(shí)。當(dāng)你開(kāi)始使用Jenkins2并創(chuàng)建自己的流水線即代碼時(shí),請(qǐng)隨時(shí)回過(guò)頭來(lái)參考本章的內(nèi)容。在第3章中,我們將從探索流水線結(jié)構(gòu)拓展到理解流水線的運(yùn)行流程,以及管控流水線運(yùn)行的多種方式。第3章流水線執(zhí)行流程使用傳統(tǒng)的JenkinsWeb界面和項(xiàng)目時(shí),比如自由風(fēng)格類(lèi)型的任務(wù),我們對(duì)處理流程的控制能力是有限的。所采用的典型形式是任務(wù)鏈——任務(wù)完成后觸發(fā)其他的任務(wù)?;蛘呶覀兛赡軙?huì)包含構(gòu)建后處理,不管任務(wù)成功完成與否,總是去做一些類(lèi)似發(fā)送通知的事情。除這些基本的功能外,我們還可以添加條件性構(gòu)建步驟插件(ConditionalBuildStepplugin),通過(guò)基于單個(gè)或者多個(gè)條件的構(gòu)建步驟來(lái)定義更加復(fù)雜的流程。但是即便如此,相比于我們編寫(xiě)程序時(shí)可以直接控制執(zhí)行流程的方法,條件性構(gòu)建步驟插件對(duì)流程的控制能力依然是有限的。在本章中,我們將探索Jenkins流水線DSL語(yǔ)言所提供的用于控制流水線執(zhí)行流程的不同的結(jié)構(gòu)。我們將從指定屬性值觸發(fā)任務(wù)以及如何接收用戶輸入開(kāi)始。然后,我們會(huì)著眼于如何靈活地使用一些結(jié)構(gòu),包括超時(shí)、重試,以及并行地運(yùn)行任務(wù)。我們還會(huì)探討如何使用現(xiàn)有的結(jié)構(gòu)把條件性構(gòu)建步驟插件的功能映射到流水線中。最后,我們將看到如何使用流水線方法效仿傳統(tǒng)Jenkins任務(wù)中的構(gòu)建后處理功能。同時(shí),我們也會(huì)看到腳本式流水線與聲明式流水線兩者的不同。讓我們從定義觸發(fā)任務(wù)的屬性開(kāi)始,開(kāi)啟流水線的探索之旅。觸發(fā)任務(wù)指定流水線代碼的觸發(fā)事件,有如下3種不同的方法。·如果Jenkins應(yīng)用的本身就是流水線類(lèi)型的任務(wù),可以使用傳統(tǒng)的方法通過(guò)Web界面在項(xiàng)目的基本配置部分指定觸發(fā)條件?!と绻莿?chuàng)建了一個(gè)腳本式流水線,可以在代碼中指定一個(gè)properties代碼塊(通常在流水線開(kāi)始之前)來(lái)定義觸發(fā)條件(注意,這個(gè)屬性部分將會(huì)和Web界面中定義的屬性合并處理,并且Web界面上定義的屬性優(yōu)先生效)?!と绻莿?chuàng)建了一個(gè)聲明式流水線,有一個(gè)特殊的triggers指令可以用來(lái)定義流水線的觸發(fā)類(lèi)型。我們將會(huì)簡(jiǎn)要地看一下傳統(tǒng)Jenkins界面上可用的觸發(fā)選項(xiàng),以及相應(yīng)的腳本式語(yǔ)法和聲明式語(yǔ)法(如果有的話)。特殊項(xiàng)目的其他觸發(fā)類(lèi)型注意,這里所討論的觸發(fā)器不適用于多分支流水線、GitHub組織,以及Bitbucket團(tuán)隊(duì)/項(xiàng)目類(lèi)型的任務(wù)。這些類(lèi)型的任務(wù)都需要有相應(yīng)的Jenkinsfile作為標(biāo)識(shí)。另外,當(dāng)代碼有改動(dòng)時(shí)可通過(guò)如webhook來(lái)通知Jenkins觸發(fā)任務(wù)。這些項(xiàng)目類(lèi)型在第8章中將會(huì)進(jìn)行更加詳細(xì)的介紹。在后面的章節(jié)中,我們將逐一介紹可用的構(gòu)建觸發(fā)的方法。在其他項(xiàng)目構(gòu)建后構(gòu)建正如標(biāo)題示意的一樣,選擇這種方法允許在一個(gè)或者多個(gè)其他項(xiàng)目之后開(kāi)始你的項(xiàng)目構(gòu)建。你可以選擇其他項(xiàng)目構(gòu)建的結(jié)束狀態(tài)(穩(wěn)定的、不穩(wěn)定的或者失敗的)。對(duì)于一個(gè)腳本式流水線,在任務(wù)Job1成功后構(gòu)建你的流水線,其語(yǔ)法如下所示:如果你需要列出多個(gè)任務(wù),可以使用逗號(hào)分隔。如果你需要指定一個(gè)任務(wù)的某個(gè)分支(例如,多分支任務(wù)),在任務(wù)名稱的后面添加斜線和分支名稱(如'Job1/master')。周期性構(gòu)建這種方法提供了一種cron類(lèi)型的功能,可以按照某個(gè)時(shí)間間隔啟動(dòng)任務(wù)。雖然這是構(gòu)建的一種方法,但是對(duì)于持續(xù)集成而言不是最佳選項(xiàng),持續(xù)集成要求基于探測(cè)代碼管理更新進(jìn)行構(gòu)建。

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論