|
最近雷鎮(zhèn)同學(xué)將Martin Fowler先生的著名論文《持續(xù)集成》第二版翻譯成中文并發(fā)布出來,掀起了國內(nèi)對于持續(xù)集成理論和實(shí)踐討論的新的高潮。筆者在本文中將全面對比持續(xù)集成論文前后兩版的異同,分析并展示ThoughtWorks在持續(xù)集成領(lǐng)域的理論和實(shí)踐方面的研究成果,以圖對國內(nèi)企業(yè)實(shí)施持續(xù)集成起到參考和借鑒作用。需要說明的是,本文所介紹的內(nèi)容畢竟限于筆者的水平,并且主要是ThoughtWorks內(nèi)部開發(fā)和對外咨詢實(shí)踐的總結(jié),所以未必對讀者所遇到的情況是適用的,請自行甄別。
《持續(xù)集成》第二版雖然是最近才翻譯出來,但是實(shí)際上Martin Fowler先生完成此文是在5年前的事情。這五年恰好是ThoughtWorks中國公司快速成長的五年。在這五年內(nèi)ThoughtWorks中國在持續(xù)集成領(lǐng)域也有很多的發(fā)展,這包括:著名的持續(xù)集成工具Cruise主要是由中國公司負(fù)責(zé)開發(fā)1; 中國公司幫助國內(nèi)很多大中型企業(yè)完成持續(xù)集成實(shí)施和相關(guān)的流程改進(jìn);2009年中國公司的很多同事對于持續(xù)集成的度量進(jìn)行了深入的討論并且最終由胡凱將其實(shí)現(xiàn)為一款軟件iAnalysis;2010年至2011年成功的交付了從需求提供方到多個(gè)技術(shù)服務(wù)提供商的持續(xù)集成方案,以及企業(yè)級(jí)自動(dòng)化中心方案。所以,本文主要包括兩部分內(nèi)容,一部分是通過對比第一版與第二版的異同介紹2000年到2006年之間持續(xù)集成領(lǐng)域的主要發(fā)展,另一部分則是介紹第二版發(fā)表之后持續(xù)集成領(lǐng)域的新進(jìn)展。讀者如果之前沒有閱讀過《持續(xù)集成》論文的第二版,建議將本文第一部分一同閱讀,因?yàn)楸疚牟⒎菍φ撐牡闹厥觯院芏嗟胤竭€需要參考原文中的內(nèi)容。
第一部分 《持續(xù)集成》第一版與第二版
《持續(xù)集成》第一版由ThoughtWorks首席科學(xué)家Martin Fowler先生和Matthew Foemmel共同完成2,第二版由Martin Fowler先生更新。
《持續(xù)集成》的第一版中并沒有給出比較正式的定義,雖然作者在文中說是借鑒了XP實(shí)踐中的術(shù)語,但是目前能看到的XP實(shí)踐中對持續(xù)集成的定義實(shí)際上大多數(shù)都是指向了Martin的文章。那么我們還是來看看第二版中給出的定義。
持續(xù)集成是一種軟件開發(fā)實(shí)踐。在持續(xù)集成中,團(tuán)隊(duì)成員頻繁集成他們的工作成果,一般每人每天至少集成一次,也可以多次。每次集成會(huì)經(jīng)過自動(dòng)構(gòu)建(包括自動(dòng)測試)的驗(yàn)證,以盡快發(fā)現(xiàn)集成錯(cuò)誤。許多團(tuán)隊(duì)發(fā)現(xiàn)這種方法可以顯著減少集成引起的問題,并可以加快團(tuán)隊(duì)合作軟件開發(fā)的速度。3
第二版相對于第一版增加了不少內(nèi)容,其中最重要的幾點(diǎn)包括:
- 詳細(xì)介紹了使用持續(xù)集成進(jìn)行軟件開發(fā)的工作流程。
- 突出了配置管理在持續(xù)集成實(shí)踐中的作用。
- 提出分階段構(gòu)建的概念。
- 增加了持續(xù)集成報(bào)告的內(nèi)容。
- 增加了持續(xù)部署的內(nèi)容。
- 給出了引入持續(xù)集成的建議。
持續(xù)集成的流程
在持續(xù)集成領(lǐng)域,我們經(jīng)常會(huì)用到的一個(gè)術(shù)語就是“構(gòu)建(Build)”。很多人認(rèn)為“構(gòu)建=編譯+鏈接(Build=Compile+Link)”,Martin在第一版中指出一次成功構(gòu)建包括:
- 所有最新代碼從配置管理工具中取出(check out或者update)。
- 所有的代碼從干凈的狀態(tài)開始編譯。
- 將編譯結(jié)果鏈接并部署,以備執(zhí)行。
- 執(zhí)行部署的應(yīng)用并運(yùn)行測試套。
- 如果上述所有操作沒有任何錯(cuò)誤,沒有人工干預(yù),并通過了所有測試,我們認(rèn)為這才是一次成功的構(gòu)建。
實(shí)際上,目前很多團(tuán)隊(duì)對成功持續(xù)集成構(gòu)建的定義基本上是符合上述定義的。這個(gè)定義的特點(diǎn)在于它是相對獨(dú)立的,它是一個(gè)從干凈狀態(tài)的源代碼最終獲得可運(yùn)行的通過驗(yàn)證的軟件的過程。
Martin在第二版中則在成功構(gòu)建的基礎(chǔ)上給出了成功集成的定義。成功集成關(guān)注的不是一次“編譯+鏈接+部署+驗(yàn)證”的過程,而是從開發(fā)流程的角度介紹一次完整的在持續(xù)集成約束下的代碼提交過程4:
- 將已集成的源代碼復(fù)制一份到本地計(jì)算機(jī)。
- 修改產(chǎn)品代碼和添加修改自動(dòng)化測試。
- 在自己的計(jì)算機(jī)上啟動(dòng)一個(gè)自動(dòng)化構(gòu)建。
- 構(gòu)建成功后,把別人的修改更新到我的工作拷貝中。
- 再重新做構(gòu)建。
- 把修改提交到源碼倉庫。
- 在集成計(jì)算機(jī)上并基于主線的代碼再做一次構(gòu)建。
- 只有這次構(gòu)建成功了,才說明改動(dòng)被成功的集成了。
下圖展示了Martin對成功集成的定義:
當(dāng)然在第一版的“代碼提交”這一節(jié),Martin也提到了本地構(gòu)建的概念,只是不如第二版這么明確。
配置管理
Martin在第一版中有兩處提及配置管理,分別是:單一代碼源(Single Source Point)和代碼提交(Checking In)。第二版中則包括:通過持續(xù)集成構(gòu)建特性(Building a Feature with Continuous Integration)、只維護(hù)一個(gè)代碼倉庫(Maintain a Single Source Repository)、每人每天都要向主線提交代碼(Everyone Commits To The Mainline Every day)、每次提交都應(yīng)在集成計(jì)算機(jī)上重新構(gòu)建主線(Every Commit Should Build the Mainline on an Integration Machine)。不僅條目數(shù)量上增加明顯,作者提出的很多實(shí)踐都是基于配置管理來講的。
工具
配置管理是持續(xù)集成的輸入。在第一版中作者所推薦的配置管理工具是CVS,到第二版中作者推薦的配置管理工具已經(jīng)換成了SVN5(參見第二部分中的配置管理工具部分)。
分支策略
實(shí)現(xiàn)進(jìn)度與質(zhì)量的平衡是配置管理的重要目的。Martin在第二版中對濫用分支給出了警告:
盡量減少分支數(shù)量。典型的情況是保持一條主線,......,每個(gè)人都從這條主線開始自己的工作。(對之前發(fā)布版本進(jìn)行Bug修正或者臨時(shí)性的實(shí)驗(yàn)都是創(chuàng)建分支的正當(dāng)理由。)
但是這里給出的建議對于大型團(tuán)隊(duì)來說并不十分合適。我們將在第二部分對于配置管理的分支策略進(jìn)行詳細(xì)描述。
內(nèi)容
Martin在第一版中給出的原則是:
任何人都可以找到一臺(tái)干凈的機(jī)器,連上網(wǎng),通過一個(gè)命令就可以取得要構(gòu)建所開發(fā)的系統(tǒng)需要的所有源文件。
第二版中的原則增加了對構(gòu)建的支持6:
任何人都可以找到一臺(tái)干凈的機(jī)器,做一次取出(checkout)動(dòng)作,然后對系統(tǒng)執(zhí)行一次完整的構(gòu)建。
分階段構(gòu)建(Staged Build)
分階段構(gòu)建是Cruise(已經(jīng)更名為Go)引入的重要概念。其主要的意義在于:
- 分離關(guān)注度不同的驗(yàn)證階段,比如Commit Build和Regression Tests,團(tuán)隊(duì)會(huì)對不同的驗(yàn)證階段采取不同的策略
- 構(gòu)建流程可視化
- 通過分階段并發(fā)構(gòu)建來縮短反饋周期
當(dāng)構(gòu)建的時(shí)間過長時(shí),我們通常會(huì)要求開發(fā)人員只運(yùn)行速度較快的價(jià)值較高的構(gòu)建階段就可以繼續(xù)自己的開發(fā)任務(wù),而不必等待漫長的次級(jí)構(gòu)建完成。這里作者提到ThoughtWorks不同的團(tuán)隊(duì)有很多有趣的實(shí)踐,我們將在第二部分向讀者介紹其中的一部分。
報(bào)告
作者在第二版中專門拿出一節(jié)“每個(gè)人都能看到進(jìn)度(Everyone Can See What's Happening)”來介紹有關(guān)持續(xù)集成報(bào)告的內(nèi)容。因?yàn)椋?/p>
持續(xù)集成的目的是為了溝通。
這是第二版相對于第一版來說一個(gè)非常明顯的變化。在第一版中通知的手段還主要是電子郵件,實(shí)際上在作者撰寫第二版的時(shí)候,ThoughtWorks已經(jīng)不贊成將電子郵件作為主要的持續(xù)集成通知工具了。更好的溝通工具包括音樂、熔巖燈、顯示器等。
對于溝通的重視從工具的角度也可以體現(xiàn)出來。Cruise Control最主要做的事情是任務(wù)調(diào)度,在報(bào)告部分做的相對來說非常粗糙,比較有價(jià)值的報(bào)告大部分是從Cruise移植過去的。Cruise在從一開始就非常重視這一點(diǎn),通過Cruise你可以非常清晰地知道,代碼發(fā)生了什么變化、正在進(jìn)行的構(gòu)建的狀態(tài)和歷史構(gòu)建的狀態(tài)。網(wǎng)頁的形式對于分布式團(tuán)隊(duì)來說具有不可替代的優(yōu)勢。
正如我們前面所說的,音樂、熔巖燈等物理手段,具有更強(qiáng)的信息輻射能力。站起來往周圍看一看就知道哪個(gè)團(tuán)隊(duì)的構(gòu)建成功了,哪個(gè)失敗了。
持續(xù)部署
持續(xù)集成實(shí)踐有一個(gè)基本的思想就是:越是痛苦的事情,越要經(jīng)常做。集成之后更令人心驚膽顫的事情就是——部署。部署到生產(chǎn)環(huán)境的流程通常要嚴(yán)格得多,然而所有的工作必須經(jīng)歷了生產(chǎn)環(huán)境的驗(yàn)證才算是成功的,所以——持續(xù)部署才是王道。Martin在第二版中建議:
你應(yīng)該有一個(gè)腳本幫助你很容易地將系統(tǒng)部署到生產(chǎn)環(huán)境中去。......同時(shí)要特別考慮的是要能夠自動(dòng)回滾。
引入持續(xù)集成的建議
作者在第二版中特別給出了逐步引入持續(xù)集成的建議。包括:
- 引入版本控制。
- 實(shí)現(xiàn)自動(dòng)化構(gòu)建。
- 添加自動(dòng)化測試。
- 加快提交構(gòu)建。
- 尋找?guī)椭#ū热鏣houghtWorks)
第二部分 持續(xù)集成領(lǐng)域的新進(jìn)展
正如前文所說,ThoughtWorks中國公司在過去的幾年里面對于持續(xù)集成實(shí)踐和幫助客戶實(shí)施持續(xù)集成都積累了很多的經(jīng)驗(yàn),同時(shí)在理論體系方面也更加豐富完整。這也使ThoughtWorks在這個(gè)領(lǐng)域繼續(xù)保持了行業(yè)領(lǐng)先的位置。
正如我們在第一部分講到的,持續(xù)集成不應(yīng)該只作為一個(gè)孤立的實(shí)踐來應(yīng)用。我們的經(jīng)驗(yàn)表明如果只把持續(xù)集成作為一個(gè)孤立的實(shí)踐應(yīng)用很難從持續(xù)集成長期受益。持續(xù)集成往往進(jìn)入“長紅”或者“長綠”的不正常的狀態(tài)。長紅意味著系統(tǒng)長期無法集成;長綠則往往意味著缺少足夠的驗(yàn)證。為了術(shù)語上的澄清,我們明確地將持續(xù)集成的定義區(qū)分為狹義的持續(xù)集成和廣義的持續(xù)集成。
狹義的持續(xù)集成:基于某種或者某些變化對系統(tǒng)進(jìn)行的經(jīng)常性的構(gòu)建活動(dòng)。
廣義的持續(xù)集成:軟件開發(fā)團(tuán)隊(duì)在上述活動(dòng)的約束下所采用的開發(fā)流程。
狹義的持續(xù)集成
一般來說,狹義的持續(xù)集成包括如下幾個(gè)方面:持續(xù)檢查、持續(xù)編譯(鏈接)、持續(xù)驗(yàn)證、持續(xù)部署、持續(xù)基礎(chǔ)設(shè)施、持續(xù)報(bào)告等6個(gè)方面。
持續(xù)檢查
持續(xù)檢查的目的是保證代碼風(fēng)格一致,主要關(guān)注于代碼的靜態(tài)質(zhì)量和內(nèi)部質(zhì)量,比如變量命名方式、大括號(hào)位置等等。大部分的現(xiàn)代集成開發(fā)環(huán)境(IDE)都具備實(shí)時(shí)檢查代碼質(zhì)量的功能。為了保證主線上的代碼質(zhì)量能夠達(dá)到一致的標(biāo)準(zhǔn),應(yīng)當(dāng)在持續(xù)集成腳本中加入靜態(tài)檢查階段。比如,Java的PMD、 FindBugs等等。
持續(xù)編譯
持續(xù)編譯是一個(gè)很樸素的想法,就是保證主線上的代碼始終處于可編譯的狀態(tài)。但是這對于很多大中型團(tuán)隊(duì)來說卻并非想當(dāng)然的簡單。這是因?yàn)楹芏鄨F(tuán)隊(duì)并未采用集體代碼所有權(quán)策略,導(dǎo)致存在依賴的團(tuán)隊(duì)的代碼無法編譯。針對這樣的問題,一方面我們建議采用集體代碼所有權(quán);另一方面,對于確實(shí)因?yàn)榘踩蛐枰綦x的代碼應(yīng)該明確邊界與接口,很少存在大部分代碼需要對大部分人保密的情況。
持續(xù)檢查和持續(xù)編譯是持續(xù)集成中最基本的驗(yàn)證手段。
持續(xù)驗(yàn)證
持續(xù)驗(yàn)證的目的是檢查主線上的代碼是否能夠?qū)崿F(xiàn)所要求的功能,或者已有的功能是否被破壞。在大部分的構(gòu)建中,驗(yàn)證部分是耗時(shí)最長、成本最高的部分,但同時(shí)也是收益最大的部分。在這個(gè)階段,我們看到的主要問題是驗(yàn)證不充分和驗(yàn)證時(shí)間過長。針對這樣的問題,我們通常采用分層分級(jí)的持續(xù)集成策略。后面有詳細(xì)的描述。
持續(xù)部署
于大型軟件應(yīng)用來說,部署往往是一個(gè)費(fèi)時(shí)費(fèi)力又容易出錯(cuò)的步驟,因?yàn)檫@里面涉及到數(shù)據(jù)遷移、版本兼容等各種棘手的問題。持續(xù)部署的思想是將這些工作標(biāo)準(zhǔn)化自動(dòng)化,使其能夠可靠地、自動(dòng)地、快速地運(yùn)行。持續(xù)部署是當(dāng)前DevOps運(yùn)動(dòng)中的熱門話題之一。
持續(xù)基礎(chǔ)設(shè)施集成
現(xiàn)代大型軟件開發(fā),尤其是互聯(lián)網(wǎng)應(yīng)用開發(fā)中經(jīng)常依賴于一些常見的基礎(chǔ)設(shè)施——比如Spring、Tomcat、Database等等。這些基礎(chǔ)設(shè)施發(fā)生變化的時(shí)候,我們應(yīng)當(dāng)及時(shí)地觸發(fā)持續(xù)集成,以確保我們的系統(tǒng)是能夠與新的基礎(chǔ)設(shè)施一起工作的。
持續(xù)報(bào)告
報(bào)告是將持續(xù)集成的狀態(tài)以適當(dāng)?shù)男问秸宫F(xiàn)給關(guān)系人的基本手段。報(bào)告是持續(xù)集成的晴雨表,所以它必須直觀、易懂,而且對關(guān)注點(diǎn)不同的角色展現(xiàn)不同的內(nèi)容和粒度。比如,開發(fā)人員可能更關(guān)心錯(cuò)誤的日志;項(xiàng)目經(jīng)理可能更關(guān)心測試覆蓋率;產(chǎn)品經(jīng)理可能更關(guān)心持續(xù)集成通過率的趨勢等等。
廣義的持續(xù)集成及持續(xù)集成策略
當(dāng)要把持續(xù)集成實(shí)踐應(yīng)用到團(tuán)隊(duì)的時(shí)候,有很多額外的技術(shù)或者非技術(shù)因素需要考慮。
組織結(jié)構(gòu)
持續(xù)集成是一個(gè)重要的溝通工具,而開發(fā)過程中兩個(gè)最需要緊密溝通的角色就是開發(fā)和測試。在我們常見的組織結(jié)構(gòu)中開發(fā)和測試往往隸屬于不同的部門,甚至這些部門隸屬于不同的高級(jí)經(jīng)理。這往往會(huì)給持續(xù)集成的推廣帶來很大的阻力。這是因?yàn)槌掷m(xù)集成從環(huán)境搭建到運(yùn)行維護(hù)都需要兩種角色的通力合作。我們的經(jīng)驗(yàn)是這類涉及到人力資源的事情除非某一級(jí)“共同的大老板”出面,否則是很難協(xié)調(diào)的。“借調(diào)”這樣的方式往往不能保證效果。
流程
放到團(tuán)隊(duì)的角度看待流程應(yīng)當(dāng)更加關(guān)注于各個(gè)成員之間的配合。每個(gè)開發(fā)人員提交代碼之前應(yīng)當(dāng)確保是經(jīng)過本地構(gòu)建的;開發(fā)人員在提交之前應(yīng)該確認(rèn)主線上的代碼是通過了持續(xù)集成的;測試人員測試的版本應(yīng)該是通過了某次持續(xù)集成的,并且有相應(yīng)的具體版本信息。
為了保障流程的順利執(zhí)行,我們還經(jīng)常采用持續(xù)集成看板、提交令牌等輔助手段。
環(huán)境
環(huán)境是指持續(xù)集成運(yùn)行時(shí)所依賴的軟件和硬件的集合。我們經(jīng)常遇到的一個(gè)問題是,軟件在一臺(tái)機(jī)器上能夠通過持續(xù)集成的驗(yàn)證,而在另一臺(tái)機(jī)器上則不能通過。這通常是因?yàn)槲覀儗Τ掷m(xù)集成環(huán)境的定義不明確造成的。所以在搭建持續(xù)集成和在組織內(nèi)推廣持續(xù)集成的時(shí)候,我們需要特別注意持續(xù)集成環(huán)境的標(biāo)準(zhǔn)化,明確指出持續(xù)集成運(yùn)行時(shí)依賴哪些第三方庫,機(jī)器配置如何,端口和網(wǎng)絡(luò)狀況如何等等。
我們經(jīng)常采用將持續(xù)集成環(huán)境加入配置管理的方式來解決環(huán)境標(biāo)準(zhǔn)化的問題。
分層
在大型團(tuán)隊(duì)(超過100人)中,扁平的開發(fā)組織結(jié)構(gòu)是運(yùn)行起來是比較困難的。常見的做法是按照特性,將團(tuán)隊(duì)劃分為10人左右的小團(tuán)隊(duì)。一般來說,如果團(tuán)隊(duì)數(shù)量超過10個(gè),還會(huì)再增加一層架構(gòu)。這時(shí)候,配置管理的策略也應(yīng)當(dāng)做出調(diào)整。常見的做法是為每個(gè)團(tuán)隊(duì)拉出一個(gè)分支,設(shè)置一個(gè)集成分支用于將各個(gè)特性分支的內(nèi)容整合在一起。需要注意的是,這里每個(gè)分支都應(yīng)該具備所有代碼的訪問權(quán)限,也就是所有分支是同根的、等價(jià)的。
測試分級(jí)
在實(shí)施持續(xù)集成時(shí),對于測試的類型應(yīng)該有比較明確的定義。一般來說,我們經(jīng)常把測試分為三級(jí)——單元測試、集成測試和系統(tǒng)測試。這是一個(gè)很大的話題,這里只是說明此處的單元測試并不是指針對函數(shù)的測試。雖然單元測試主要是函數(shù)基本的測試,但是每個(gè)單元測試應(yīng)該針對的是特性或者對應(yīng)代碼在實(shí)現(xiàn)該特性上所發(fā)揮的作用。
單元測試的運(yùn)行速度通常非常快,應(yīng)該在數(shù)秒到數(shù)分鐘。單元測試應(yīng)該覆蓋絕大部分的特性需求。集成測試單個(gè)測試的運(yùn)行速度通常會(huì)比單元測試慢一個(gè)數(shù)量級(jí),比如存在文件讀寫或者其他的IO和網(wǎng)絡(luò)操作。集成測試主要用于保證系統(tǒng)的各個(gè)組件之間的調(diào)用是工作的。系統(tǒng)測試的運(yùn)行速度一般會(huì)比集成測試慢,通常需要將整個(gè)系統(tǒng)運(yùn)行起來,比如Web開發(fā)中的selenium測試。系統(tǒng)測試主要用于測試系統(tǒng)的正確路徑(Happy Path)可以工作。有的團(tuán)隊(duì)會(huì)開發(fā)很多基于整個(gè)系統(tǒng)的回歸測試,也屬于系統(tǒng)測試。就場景的覆蓋而言,單元測試>集成測試>系統(tǒng)測試,從運(yùn)行時(shí)間來看則相反。
持續(xù)集成的成熟度評估
在幫助客戶實(shí)施和推廣持續(xù)集成的過程中我們逐漸總結(jié)出一些原則,幫助客戶評估現(xiàn)狀,分析和設(shè)計(jì)未來的目標(biāo)。該評估方法借鑒了ThoughtWorks敏捷成熟度模型中有關(guān)配置管理、測試、構(gòu)建等內(nèi)容,并做了適當(dāng)?shù)暮喕?/p>
構(gòu)建:
級(jí)別 | 描述 |
3+:對外防御的 | 團(tuán)隊(duì)能夠根據(jù)自己的需要,協(xié)調(diào)其他團(tuán)隊(duì)的持續(xù)集成,當(dāng)依賴的其他團(tuán)隊(duì)的代碼和組件或者第三方庫和基礎(chǔ)設(shè)施發(fā)生改變時(shí)自動(dòng)進(jìn)行構(gòu)建。團(tuán)隊(duì)對于外部依賴的可靠性有信心。 |
3:對內(nèi)防御的 | 構(gòu)建是自動(dòng)的。由測試和檢查來保證團(tuán)隊(duì)內(nèi)部的開發(fā)質(zhì)量。持續(xù)集成的修復(fù)具有最高的優(yōu)先級(jí)。團(tuán)隊(duì)對持續(xù)集成的結(jié)果有信心。 |
2:頻繁的 | 構(gòu)建是自動(dòng)的,而且構(gòu)建的速度較快。構(gòu)建的觸發(fā)條件是明確的,通常每次代碼提交都會(huì)觸發(fā)構(gòu)建。團(tuán)隊(duì)中的每個(gè)人都會(huì)觸發(fā)構(gòu)建,并且了解構(gòu)建的狀態(tài)。 |
1:重復(fù)執(zhí)行 | 構(gòu)建是自動(dòng)的,但是執(zhí)行的不夠頻繁。構(gòu)建的觸發(fā)是隨機(jī)的或者頻率是非常低的(低于每天一次)。構(gòu)建的速度通常非常慢,比如一次構(gòu)建超過半個(gè)小時(shí)。 |
0:可重復(fù)的 | 主要依賴于手動(dòng)的方式構(gòu)建軟件,但是每次構(gòu)建的方式都是相同的或者相似的。通常有相關(guān)的文檔的指導(dǎo)。經(jīng)常團(tuán)隊(duì)指定某個(gè)人負(fù)責(zé)構(gòu)建軟件,雖然大部分人都能夠做這件事情。 |
-1:手動(dòng)的 | 主要依賴于手動(dòng)的方式集成軟件。每次集成的方式可能不一樣。經(jīng)常團(tuán)隊(duì)中只有個(gè)別人能夠?qū)④浖善饋怼? |
測試:
級(jí)別 | 描述 |
3+:全面集成的 | 全團(tuán)隊(duì)對測試負(fù)責(zé)。測試驅(qū)動(dòng)整個(gè)開發(fā)過程。測試與構(gòu)建完全集成。 |
3:測試驅(qū)動(dòng)的 | 業(yè)務(wù)分析人員和開發(fā)人員均參與測試。測試在構(gòu)建過程中自動(dòng)執(zhí)行。開發(fā)人員實(shí)踐測試驅(qū)動(dòng)開發(fā)。 |
2:集成的 | 開發(fā)人員參與測試。部分測試集成在構(gòu)建過程中執(zhí)行。大部分測試在軟件開發(fā)過程中執(zhí)行。 |
1:共享的 | 開發(fā)人員參與測試。測試并未集成在構(gòu)建過程中。部分測試在軟件開發(fā)過程中執(zhí)行,大部分測試在軟件開發(fā)結(jié)束后執(zhí)行。 |
0:審查的 | 測試由專門的測試人員負(fù)責(zé)。有部分測試是在軟件開發(fā)過程中執(zhí)行。但大部分測試在軟件開發(fā)結(jié)束后執(zhí)行。 |
-1:獨(dú)立的 | 測試由專門的測試人員負(fù)責(zé)。僅在軟件開發(fā)結(jié)束后執(zhí)行。 |
配置管理:
級(jí)別 | 描述 |
3+:企業(yè)級(jí)的 | 企業(yè)有統(tǒng)一的配置管理策略。 |
3:跨項(xiàng)目的 | 配置管理在多個(gè)項(xiàng)目之間協(xié)調(diào)。 |
2:自動(dòng)的 | 配置管理策略與持續(xù)集成策略緊密結(jié)合,團(tuán)隊(duì)成員有頻繁提交的意識(shí)。一般采用樂觀鎖策略,原子提交。 |
1:集成的 | 版本管理下的內(nèi)容是受控的。通常在版本管理中的代碼是可以編譯的。開發(fā)人員能夠訪問到自己工作所需要的代碼。開發(fā)人員按照一定的規(guī)則訪問配置管理工具和提交代碼。一般采用悲觀鎖策略。版本管理工具和構(gòu)建過程集成在一起的。 |
0:基本的 | 有基本的版本管理。但版本管理下的內(nèi)容不全面,或者不足以支撐團(tuán)隊(duì)的開發(fā)。 |
-1:無配置管理 | 沒有配置管理。或者使用方式完全錯(cuò)誤。 |
常用實(shí)踐和工具
持續(xù)集成看板7
問題:
我們需要讓整個(gè)團(tuán)隊(duì)能夠方便快捷的了解持續(xù)集成的狀態(tài)。
上下文:
在完成了基本的構(gòu)建基礎(chǔ)設(shè)施的搭建之后,我們需要讓團(tuán)隊(duì)成員及時(shí)獲得持續(xù)集成的狀態(tài)信息。傳統(tǒng)的郵件方式可能會(huì)使人厭煩,或者錯(cuò)過重要的構(gòu)建信息。
解決方案和實(shí)現(xiàn):
安裝一個(gè)顯示器,將構(gòu)建的狀態(tài)信息以簡明的方式展示在顯示器上。將顯示器放置在團(tuán)隊(duì)所有成員都能夠很容易看到的地方。
個(gè)人構(gòu)建中心
問題:
在某些情況下,構(gòu)建環(huán)境的成本很高,而我們需要每一個(gè)開發(fā)人員提交之前完成一次個(gè)人構(gòu)建。
上下文:
有些測試是依賴于設(shè)備的,而這些設(shè)備非常昂貴,并且配置復(fù)雜,所以無法給每個(gè)開發(fā)/測試人員一套構(gòu)建環(huán)境。我們發(fā)現(xiàn)根據(jù)本地構(gòu)建的理論模型,每個(gè)人的提交應(yīng)該是串行的,這樣我們實(shí)際上可以做到讓這些人共享一套環(huán)境,但是從邏輯上就像是每個(gè)人有一套自己的環(huán)境一樣。
解決方案:
在運(yùn)行個(gè)人構(gòu)建的時(shí)候?qū)⒈镜氐拇a同步到一臺(tái)共享的機(jī)器上執(zhí)行構(gòu)建,構(gòu)建完成后結(jié)果反饋給提交這次個(gè)人構(gòu)建的人。
實(shí)現(xiàn):
個(gè)人構(gòu)建中心的實(shí)現(xiàn)有很多種方案。這些方案的區(qū)別主要在于如何將代碼同步到個(gè)人構(gòu)建中心服務(wù)器上。兩種常見的方式:一個(gè)是使用rsync或者類似方式同步;另一個(gè)是使用分布式配置管理工具如git/hg同步。其拓?fù)浣Y(jié)構(gòu)如下:
第一種方式相對獨(dú)立靈活;第二種方式穩(wěn)定、高效,但是對于配置管理工具有依賴。
后果:
個(gè)人構(gòu)建中心節(jié)省了大量的計(jì)算資源,同時(shí)也容易使得中心服務(wù)器成為單點(diǎn)失敗的源頭。一旦中心服務(wù)器出現(xiàn)問題,可能會(huì)導(dǎo)致團(tuán)隊(duì)的流程受到較大影響。
提交令牌
問題:
在實(shí)施本地構(gòu)建的時(shí)候,向目標(biāo)分支的提交應(yīng)該是串行的,以避免構(gòu)建被破壞后難以定位問題來源。但是團(tuán)隊(duì)往往缺乏一種有效的機(jī)制來保證這種串行。
上下文:
有些團(tuán)隊(duì)試圖通過技術(shù)的手段來解決這個(gè)問題,比如通過配置管理上的鎖機(jī)制,這種方式和樂觀鎖模式有較大沖突。有些團(tuán)隊(duì)通過團(tuán)隊(duì)內(nèi)部溝通的方式解決,比如誰提交之前都會(huì)通知?jiǎng)e人,或者通過持續(xù)集成監(jiān)視器來了解當(dāng)前的構(gòu)建狀態(tài),以決定自己是否可以提交。這些方式各自有各自的適用情形,較容易理解。
解決方案和實(shí)現(xiàn):
使用一個(gè)實(shí)物作為令牌,準(zhǔn)備提交的代碼的人首先取得令牌,當(dāng)代碼提交完成(包括相應(yīng)的提交構(gòu)建)之后,將令牌交還。令牌要醒目,并且移動(dòng)方便。小型獎(jiǎng)杯、毛絨玩具、較大的頭飾(如下圖)都是不錯(cuò)的令牌。
分階段構(gòu)建
問題:
在某些團(tuán)隊(duì)中完整構(gòu)建所花費(fèi)的時(shí)間可能很長,如果每次提交都運(yùn)行完整的構(gòu)建會(huì)浪費(fèi)很多時(shí)間。
上下文:
隨著持續(xù)集成的日益完善,我們往往會(huì)發(fā)現(xiàn)驗(yàn)證所花費(fèi)的時(shí)間越來越長,而大部分驗(yàn)證趨于穩(wěn)定,失敗的情況很少見。通過技術(shù)手段縮短構(gòu)建時(shí)間是解決問題的根本辦法,但是縮短構(gòu)建時(shí)間是一個(gè)耗時(shí)耗力的工作,很難短期內(nèi)見效。
解決方案和實(shí)現(xiàn):
將構(gòu)建分為幾個(gè)階段執(zhí)行,在本地構(gòu)建中僅執(zhí)行速度比較快、可信度比較高、出錯(cuò)概率比較大的驗(yàn)證。利用晚上或者其他合適的時(shí)間執(zhí)行全面的驗(yàn)證——我們這次構(gòu)建稱為全量構(gòu)建。需要注意的是,這種情況下仍然要保證提交構(gòu)建和本地構(gòu)建的一致性。
iAnalysis
iAnalysis是一款輕量級(jí)的持續(xù)集成報(bào)告工具。該工具的核心思想是將持續(xù)集成構(gòu)建過程中產(chǎn)生的數(shù)據(jù)以趨勢和對比的方式展示出來。正如前文所說,我們在2009年的ThoughtWorks Away-Day上討論了敏捷度量的話題,大家最后一致認(rèn)為,數(shù)據(jù)有兩種最基本的用法——橫向?qū)Ρ群涂v向?qū)Ρ取M向?qū)Ρ染褪遣煌娜恕⒉煌膱F(tuán)隊(duì)之間對比;縱向?qū)Ρ染褪乾F(xiàn)在和過去對比。iAnalysis正是這種思想的體現(xiàn)。
關(guān)于作者
肖鵬,ThoughtWorks資深咨詢師,程序員,敏捷過程教練。擁有7年以上軟件開發(fā)實(shí)踐經(jīng)驗(yàn),多次擔(dān)任大中型企業(yè)敏捷流程改進(jìn)咨詢和培訓(xùn),服務(wù)對象涉及通信設(shè)備制造、通信運(yùn)營、互聯(lián)網(wǎng)行業(yè)等。他關(guān)注于設(shè)計(jì)模式、架構(gòu)模式、敏捷軟件開發(fā)等領(lǐng)域,并致力于軟件開發(fā)最佳實(shí)踐的推廣和應(yīng)用。他曾參與翻譯《Visual Studio 2005技術(shù)大全》,主持翻譯《面向模式的軟件架構(gòu)》第四卷和第五卷等圖書。
1 目前Cruise的開發(fā)任務(wù)已經(jīng)不在中國公司了。
2 實(shí)際上這篇文章介紹的是Matthew所在團(tuán)隊(duì)在2000年早些時(shí)候已經(jīng)在使用的實(shí)踐,ThoughtWorks中國公司的總經(jīng)理郭曉先生當(dāng)時(shí)也在這個(gè)團(tuán) 隊(duì)。
3 為了與ThoughtWorks常用的術(shù)語保持一致,部分術(shù)語與雷鎮(zhèn)和熊節(jié)同學(xué)所譯略有差別,下同。
5 Martin最近在自己的一篇博客上對幾種流行的配置管理工具做了對比。
6 注意,本文并非為指出第一版的缺陷,只是通過對比來說明作者論文中重點(diǎn)的變化。
7 這里只是借用“看板”這個(gè)詞的字面含義,與精益中的看板有區(qū)別。
it知識(shí)庫:持續(xù)集成理論和實(shí)踐的新進(jìn)展,轉(zhuǎn)載需保留來源!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時(shí)間聯(lián)系我們修改或刪除,多謝。