久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

重溫經(jīng)典:Martin Fowler談持續(xù)集成丨IDCF

 過河卒沖 2020-09-16

來源:DevOps社區(qū)Meetup
原作者:Martin Fowler
原文網(wǎng)址:https:///articles/continuousIntegration.html
譯者:尚君領(lǐng) 朱露露 劉海燕 周一行
審校:王立杰 王英偉 高俊寧 陳文峰

Martin Fowler

目錄

摘要
引言
一,、使用持續(xù)集成構(gòu)建功能
二,、持續(xù)集成的實(shí)踐
2.1 維護(hù)單一的源代碼存儲庫
2.2 構(gòu)建自動化
2.3 如何構(gòu)建自動化測試
2.4 每人每天都向主干提交代碼
2.5 每次提交都應(yīng)該在集成機(jī)上構(gòu)建主線
2.6 立即修復(fù)失敗的構(gòu)建
2.7 保持快速構(gòu)建
2.8 在生產(chǎn)環(huán)境的克隆中測試
2.9 任何人都能輕松獲得最新的可執(zhí)行文件
2.10 每個(gè)人都可以看到正在發(fā)生什么
2.11 自動化部署
三、持續(xù)集成的好處
四,、引入持續(xù)集成
五,、最后的思考

延伸閱讀


摘要

持續(xù)集成是一種軟件開發(fā)實(shí)踐,團(tuán)隊(duì)成員頻繁地將他們的工作成果集成在一起,,通常每人每天至少提交一次,,這樣每天就會有多次集成。每次集成都通過自動構(gòu)建(包括測試)進(jìn)行驗(yàn)證,,以便盡可能快地檢測集成錯(cuò)誤,。許多團(tuán)隊(duì)發(fā)現(xiàn)這種方法可以顯著減少集成問題,并允許團(tuán)隊(duì)更快地開發(fā)內(nèi)聚軟件,。本文簡要介紹了持續(xù)集成技術(shù)及其應(yīng)用現(xiàn)狀,。

引言

我清楚地記得我第一次看到一個(gè)大型軟件項(xiàng)目。那時(shí)我在英國一家大型電子公司做暑期實(shí)習(xí),。我的經(jīng)理,,QA小組的一員,帶我參觀了一個(gè)地方,,我們進(jìn)入了一個(gè)令人沮喪的大倉庫,,里面堆滿了立方體。我被告知這個(gè)項(xiàng)目已經(jīng)開發(fā)了幾年,,目前正在集成,,并且已經(jīng)集成了幾個(gè)月。他告訴我,,沒有人真正知道完成集成需要多長時(shí)間,。從中我學(xué)到了軟件項(xiàng)目的一個(gè)共同的故事:集成是一個(gè)漫長而不可預(yù)測的過程。
其實(shí)不需要這樣,。我在ThoughtWorks的同事和世界上許多其他人所做的大多數(shù)項(xiàng)目都不把集成當(dāng)成一個(gè)很嚴(yán)重的事兒,。任何單個(gè)開發(fā)人員的工作都離共享的項(xiàng)目狀態(tài)只有幾個(gè)小時(shí),并且可以在幾分鐘內(nèi)集成回去,。任何集成錯(cuò)誤都能被快速發(fā)現(xiàn)并得到迅速修正,。
這種鮮明的對比并不是昂貴復(fù)雜工具的結(jié)果。它的本質(zhì)在于一個(gè)簡單的實(shí)踐,,也就是團(tuán)隊(duì)里的每個(gè)人都在頻繁的集成,,通常是每天對于一個(gè)受控的源代碼存儲庫進(jìn)行集成。
當(dāng)我向人們描述這一做法時(shí),我通常會發(fā)現(xiàn)兩種反應(yīng):“這里不行”和“這樣做不會有多大區(qū)別”,。人們在嘗試的過程中發(fā)現(xiàn),,這比聽起來容易得多,而且對開發(fā)有著巨大的影響,。因此,,第三種常見的反應(yīng)是“是的,我們這樣做了——沒有它你怎么活,?”
術(shù)語“持續(xù)集成”起源于Kent Beck的極限編程開發(fā)過程,,是最初的12個(gè)實(shí)踐之一。當(dāng)我開始在ThoughtWorks工作時(shí),,作為一名顧問,,我鼓勵(lì)在我工作的項(xiàng)目中使用這種技術(shù)。Matthew Foemmel把我模糊的建議變成了實(shí)際行動,,我們看到了這個(gè)項(xiàng)目從罕見而復(fù)雜的集成,,變?yōu)槲颐枋龅牟皇悄敲磭?yán)重的事情。Matthew和我在這篇論文的原始版本中寫下了我們的經(jīng)驗(yàn),,這篇論文一直是我網(wǎng)站上最受歡迎的論文之一,。
盡管持續(xù)集成是一種不需要特殊工具來部署的實(shí)踐,但我們發(fā)現(xiàn)使用持續(xù)集成服務(wù)器是很有用的,。最著名的此類服務(wù)器是CruiseControl,,這是一個(gè)開源工具,最初由ThoughtWorks的幾個(gè)人構(gòu)建,,現(xiàn)在由一個(gè)很大的社區(qū)維護(hù),。從那時(shí)起,出現(xiàn)了其他一些CI服務(wù)器,,有開源的,,也有商用的——包括ThoughtWorks工作室的Cruise。

一,、使用持續(xù)集成構(gòu)建功能

對于我來說,,解釋什么是CI以及它是如何工作的最簡單的方法是展示一個(gè)快速的例子,說明它如何與一個(gè)小特性的開發(fā)一起工作,。假設(shè)我必須對一個(gè)軟件添加一點(diǎn)功能,,任務(wù)是什么并不重要,因?yàn)楝F(xiàn)在我假設(shè)它很小,,可以在幾個(gè)小時(shí)內(nèi)完成,。(稍后我們將探討更長的任務(wù)和其他問題。)
首先,,我將當(dāng)前集成源代碼的副本復(fù)制到本地開發(fā)機(jī)器上,。我通過使用源代碼管理系統(tǒng),,從主干簽出一個(gè)工作副本來實(shí)現(xiàn)這一點(diǎn)。
上面那段話對于使用源代碼控制系統(tǒng)的人來說是有意義的,,但是對于不使用源代碼控制系統(tǒng)的人來說是胡言亂語,。所以讓我快速地為后者解釋一下。源代碼控制系統(tǒng)將項(xiàng)目的所有源代碼保存在存儲庫中,。系統(tǒng)的當(dāng)前狀態(tài)通常稱為“主干”,。開發(fā)人員可以隨時(shí)在自己的機(jī)器上生成主干的受控副本,這稱為“簽出”,。開發(fā)人員機(jī)器上的副本稱為“工作副本”,。(大多數(shù)情況下,,你實(shí)際上是把你的工作副本更新到主干上——實(shí)際上和簽出也是一樣的,。)
現(xiàn)在我拿著我的工作副本,做任何我需要做的事情來完成我的任務(wù),。這將包括修改產(chǎn)品代碼,,以及添加或更改自動化測試。持續(xù)集成假定軟件中有高度自動化的測試:我稱之為自測試代碼的工具,。它們通常使用流行的XUnit測試框架的一個(gè)版本,。
當(dāng)我完成之后(通常在我工作的不同階段),我就在我的開發(fā)機(jī)器上執(zhí)行一個(gè)自動化的構(gòu)建,。這將獲取工作副本中的源代碼,,將其編譯并鏈接到可執(zhí)行文件中,然后運(yùn)行自動測試,。只有在所有的構(gòu)建和測試都沒有錯(cuò)誤的情況下,,整個(gè)構(gòu)建才被認(rèn)為是正確的。
有了正確的構(gòu)建,,我就可以考慮將更改提交到存儲庫中,。當(dāng)然,問題是,,在我有機(jī)會提交我的更改之前,,其他人可能,而且通常已經(jīng)對主干進(jìn)行了更改,。因此,,首先我用他們的更改來更新我的工作副本,并重新構(gòu)建,。如果他們的更改與我的更改沖突,,在編譯或測試中將顯示為失敗。在這種情況下,,我的責(zé)任是修復(fù)這個(gè)問題,,并重復(fù)構(gòu)建,,直到我可以建立一個(gè)與主干正確同步的工作副本。
一旦我自己構(gòu)建了一個(gè)正確同步的工作副本,,最終我就可以將我的更改提交到主干中,,之后會更新存儲庫。
然而,,我的提交并沒有完成我的工作,。此時(shí),我們再次構(gòu)建,,但這次是在基于主干代碼的集成服務(wù)器上,。只有當(dāng)這個(gè)構(gòu)建成功時(shí),我們才能說我的更改已經(jīng)完成,。因?yàn)榭傆腥f一,,我可能會遺漏了我的機(jī)器上的東西,存儲庫沒有得到適當(dāng)?shù)母?。只有?dāng)我提交的更改在集成服務(wù)器上成功構(gòu)建時(shí),,我的工作才能完成。這個(gè)集成構(gòu)建可以由我手動執(zhí)行,,也可以由Cruise自動完成,。
如果兩個(gè)開發(fā)人員之間發(fā)生沖突,通常會在第二個(gè)提交的開發(fā)人員構(gòu)建其更新的工作副本時(shí)捕獲沖突,。否則,,集成構(gòu)建將失敗。無論哪種方式,,錯(cuò)誤都會被快速檢測到,。此時(shí),最重要的任務(wù)是修復(fù)它,,并使構(gòu)建重新正常工作,。在持續(xù)集成環(huán)境中,不應(yīng)該讓失敗的集成構(gòu)建保持在失敗狀態(tài)太久,。一個(gè)好的團(tuán)隊(duì)一天應(yīng)該有很多正確的構(gòu)建,。不好的構(gòu)建時(shí)有發(fā)生,但應(yīng)該迅速被修復(fù),。
這樣做的結(jié)果是,,有一個(gè)穩(wěn)定的軟件,工作正常,,包含很少的錯(cuò)誤,。每個(gè)人都是從這個(gè)共享的穩(wěn)定的基礎(chǔ)上開發(fā)的,從來沒有離開這個(gè)基礎(chǔ)太遠(yuǎn),,以至于需要很長時(shí)間才能集成回來,。尋找錯(cuò)誤會花更少的時(shí)間,,因?yàn)殄e(cuò)誤很快就會顯現(xiàn)出來。

二,、持續(xù)集成的實(shí)踐

上面的故事是關(guān)于CI的概述,,以及它在日常生活中是如何工作的。顯然,,讓所有這些工作順利進(jìn)行并不僅僅是這些,。我現(xiàn)在將重點(diǎn)介紹構(gòu)成有效CI的關(guān)鍵實(shí)踐。
2.1 維護(hù)單一的源代碼存儲庫
軟件項(xiàng)目涉及許多需要組合在一起才能構(gòu)建產(chǎn)品的文件,。跟蹤所有這些文件,,是一項(xiàng)重要的工作,特別是當(dāng)有多人參與時(shí),。因此,,我們毫不意外的看到,多年來,,軟件開發(fā)團(tuán)隊(duì)已經(jīng)構(gòu)建了管理所有這些文件的工具,。這些工具稱為源代碼管理工具,、配置管理,、版本控制系統(tǒng)、存儲庫或各種其他名稱,,是大多數(shù)開發(fā)項(xiàng)目不可分割的一部分,。令人悲哀和驚訝的是,它們并不是所有項(xiàng)目的一部分,。盡管很少見,,但我確實(shí)遇到不使用這樣的系統(tǒng)的項(xiàng)目,項(xiàng)目使用一些混亂的本地和共享存儲器的組合,。
因此,,作為一個(gè)簡單的基礎(chǔ),確保你要有一個(gè)像樣的源代碼管理系統(tǒng),。成本不是問題,,因?yàn)橛懈哔|(zhì)量的開源工具。當(dāng)前選擇的開源存儲庫是Subversion,。(較老的開源工具CVS仍然被廣泛使用,,雖然比什么都沒有要好得多,但是Subversion是更時(shí)髦的選擇,。)有趣的是,,當(dāng)我與開發(fā)人員交談時(shí),我了解到大多數(shù)商業(yè)源代碼管理工具比Subversion更受歡迎,。我一直聽到人們說唯一值得花錢的工具就是Perforce,。(譯者注:本文寫于2006年,,時(shí)至今日,Git更為流行)
一旦你得到一個(gè)源代碼管理系統(tǒng),,確保它位于眾所周知的地方,,每個(gè)人都去獲取源代碼。沒有人會問“foo-whiffle文件在哪里,?”所有的東西都應(yīng)該在存儲庫里,。
盡管許多團(tuán)隊(duì)都會使用存儲庫,但我發(fā)現(xiàn)一個(gè)常見的錯(cuò)誤是,,他們沒有將所有內(nèi)容都放在存儲庫中,。如果人們使用它,他們會把代碼放在那里,,但你的構(gòu)建需要做的一切都應(yīng)該在那里,,包括:測試腳本,屬性文件,,數(shù)據(jù)庫架構(gòu),,安裝腳本和第三方庫。我知道一些項(xiàng)目,,將編譯器檢入到存儲庫(對于早期的大量的C++編譯器很重要),。基本的經(jīng)驗(yàn)法則是,,你應(yīng)該能夠用一臺空白的機(jī)器開始項(xiàng)目,,做一個(gè)簽出,并且能夠完整的構(gòu)建系統(tǒng),。只有少量的東西應(yīng)該放在空白的機(jī)器上,,通常是大的、安裝復(fù)雜的和穩(wěn)定的東西,。操作系統(tǒng),、Java開發(fā)環(huán)境或基礎(chǔ)數(shù)據(jù)庫系統(tǒng)是典型的例子。
你必須將構(gòu)建所需的所有內(nèi)容都放在源代碼管理系統(tǒng)中,,但是你也可以將人們通常使用的其他內(nèi)容放在其中,。IDE配置很適合放在那里,因?yàn)檫@樣人們就可以很容易地共享相同的IDE設(shè)置,。
版本控制系統(tǒng)的一個(gè)特點(diǎn)是,,它們允許你能創(chuàng)建多個(gè)分支,以處理不同的開發(fā)流,。這是一個(gè)有用的,,但不必要的功能,但它經(jīng)常被過度使用,,并使人們陷入麻煩,。盡量少用分支,。特別是在有一條主干的情況:目前正在開發(fā)的項(xiàng)目的唯一分支。幾乎每個(gè)人大部分時(shí)間都應(yīng)該在這條主干上工作,。(合理的分支是修復(fù)先前生產(chǎn)版本的錯(cuò)誤和臨時(shí)的實(shí)驗(yàn),。)
一般來說,你應(yīng)該在源代碼管理中存儲構(gòu)建所需的所有內(nèi)容,,但不存儲實(shí)際構(gòu)建出的內(nèi)容,。有些人確實(shí)將構(gòu)建的產(chǎn)品放在源代碼管理中,但我認(rèn)為這是一種壞味道——這意味著更深層次的問題,,通常是無法可靠地重新創(chuàng)建構(gòu)建,。
2.2 構(gòu)建自動化
將源代碼轉(zhuǎn)換為可以運(yùn)行的系統(tǒng),通常是一個(gè)復(fù)雜的過程,,它包括編譯,、移動文件、把數(shù)據(jù)庫模式加載到數(shù)據(jù)庫等等,。然而,,與軟件開發(fā)中的大多數(shù)任務(wù)一樣,它是可以被自動化的,。它也應(yīng)該是自動化的,。讓人們輸入奇怪的命令或點(diǎn)擊對話框是浪費(fèi)時(shí)間,也最容易產(chǎn)生錯(cuò)誤,。
構(gòu)建自動化環(huán)境是系統(tǒng)中一個(gè)共同的特性,。Unix世界使用make作為工具已經(jīng)幾十年了,,Java社區(qū)發(fā)展了ANT(譯者注:后來JAVA的構(gòu)建工具發(fā)展為Maven和Gradle),,并且. net社區(qū)已經(jīng)有了Nant,現(xiàn)在又有了MSBuild,。確保你可以使用單個(gè)命令使用這些腳本構(gòu)建和運(yùn)行系統(tǒng),。
一個(gè)常見的錯(cuò)誤是沒有在自動化構(gòu)建中包含所有內(nèi)容。構(gòu)建應(yīng)該包括從存儲庫中獲取數(shù)據(jù)庫模式,,并在執(zhí)行環(huán)境中啟動它,。我將詳細(xì)闡述我先前的經(jīng)驗(yàn)法則:任何人都應(yīng)該能夠引入一臺空白機(jī)器,簽出存儲庫中的源代碼,,發(fā)出一個(gè)命令,,之后在自己的機(jī)器上就擁有了一個(gè)正在運(yùn)行的系統(tǒng)。
構(gòu)建腳本通常有不同的風(fēng)格,,通常是特定于平臺或社區(qū)的,,但他們大可不必如此。盡管我們的大多數(shù)Java項(xiàng)目都使用Ant,,有一些在使用Ruby(Ruby Rake是一個(gè)非常好用的構(gòu)建腳本的工具),。我們通過使用Ant自動化在早期的微軟 COM項(xiàng)目中獲得了某些價(jià)值,。
一個(gè)大的構(gòu)建通常需要花費(fèi)很多精力,如果你僅僅做了一個(gè)小小的更改,,那么你不會想要執(zhí)行所有的步驟,。所以,一個(gè)好的構(gòu)建工具會分析在流程中需要更改的內(nèi)容,。通常的做法是檢查源文件和目標(biāo)文件的日期,,只有在源文件的日期較晚時(shí)才進(jìn)行編譯。依賴關(guān)系會變得更加棘手:如果一個(gè)對象文件改變了那些依賴于它的對象文件,,那么這些對象文件可能也需要重新構(gòu)建,。編譯器能夠處理這類事情,也可能不處理,。
根據(jù)你的需要,,你可以構(gòu)建不同類型的東西。你可以通過是否使用測試代碼或者使用不同的測試集來構(gòu)建系統(tǒng),。有些組件可以獨(dú)立構(gòu)建,。構(gòu)建腳本應(yīng)該允許你為不同的情況構(gòu)建可選目標(biāo)。
我們普遍使用IDE,,而且在使用IDE時(shí),,大多數(shù)的公司內(nèi)部都有一些構(gòu)建管理的過程。然而,,這些文件總是IDE專有的,,而且它們非常脆弱。不過,,他們這些公司需要通過IDE進(jìn)行工作,。用戶通過IDE設(shè)置自己的項(xiàng)目文件并將其用于單獨(dú)的開發(fā)是完全沒有問題的。然而,,有一個(gè)在服務(wù)器上可用并且可以從其他腳本運(yùn)行的主干是非常重要的,。所以在Java項(xiàng)目中,我們可以讓研發(fā)人員在IDE中構(gòu)建,,但是主干需要使用Ant來保證它可以在開發(fā)服務(wù)器上運(yùn)行,。
2.3 如何構(gòu)建自動化測試
從傳統(tǒng)意義上來講,構(gòu)建意味著編譯,,鏈接以及執(zhí)行程序所需的所有其他過程,。一個(gè)項(xiàng)目可能會運(yùn)行,但是,,這并不意味著它在做正確的事情?,F(xiàn)代靜態(tài)類型語言可以發(fā)現(xiàn)許多bug,但是更多的bug會成為“漏網(wǎng)之魚”。
在構(gòu)建過程中包含自動化測試是更快,、更有效地發(fā)現(xiàn)bug的比較好的方法,。當(dāng)然,測試并不是完美的,,但它能夠發(fā)現(xiàn)很多Bug,,這就足夠有用了。特別是極限編程(XP)和測試驅(qū)動開發(fā)(TDD)的興起為自動化測試的普及做了大量工作,,因此許多人已經(jīng)看到了這種技術(shù)的價(jià)值,。
經(jīng)常閱讀我作品的讀者會發(fā)現(xiàn)我是XP和TDD的忠實(shí)粉絲。然而,,我想要強(qiáng)調(diào)的是,,這兩種方式都不是構(gòu)建自動化測試的最佳途徑。這兩種方式都強(qiáng)調(diào)在使測試通過之前你要先編寫測試——在這種模式下,,測試不僅能夠用于發(fā)現(xiàn)錯(cuò)誤,,而且還涉及探索系統(tǒng)的設(shè)計(jì)。這是一件好事情,,但是,,對持續(xù)集成而言,這并不是必需的,。因?yàn)槲覀兺ǔψ詣踊瘻y試代碼的需求比較少,。(盡管TDD是我進(jìn)行自動化測試的首選)
對于自測試代碼而言,你需要一套自動化測試體系它可以檢查大部分代碼庫中的Bug,。測試可以從一個(gè)簡單的指令中啟動并進(jìn)行自動檢測,。運(yùn)行測試套件的結(jié)果應(yīng)該可以指出是否有任何測試失敗。對于具備自測試的構(gòu)建,,測試的失敗應(yīng)該會導(dǎo)致構(gòu)建失敗,。
在過去的幾年時(shí)間里,TDD的興起普及了XUnit開源工具家族,,這些工具對于這類測試非常理想,。Xunit 工具對我們 ThoughtWorks 來說非常有價(jià)值,我也總是建議人們使用這些工具,。這些由Kent Beck首創(chuàng)的工具,能夠幫你非常容易的構(gòu)建一個(gè)自動化測試環(huán)境,。
XUnit工具當(dāng)然是讓代碼進(jìn)行自動化測試的起點(diǎn),。你也應(yīng)該尋找其他專注于更多端到端測試的工具。目前有很多這樣的工具,,包括FIT,、Selenium、Sahi,、Watir,、FITnesse,,還有很多其他工具,我在這里不打算都列出來,。
當(dāng)然,,你不能指望測試能發(fā)現(xiàn)一切錯(cuò)誤。正如人們常說的那樣:測試并不能證明沒有缺陷,。雖然你從自動化測試的構(gòu)建中得到的反饋并不一定是完美的,,經(jīng)常運(yùn)行的不完美的測試也比根本不寫的完美測試要好得多。
2.4 每人每天都向主干提交代碼
集成主要是關(guān)于溝通的,。集成允許開發(fā)人員將他們所做的更改告知其他開發(fā)人員,。頻繁的交流能讓人們在變化發(fā)生時(shí)迅速了解情況。
開發(fā)人員遵守主干的一個(gè)先決條件是,,他們可以正確地構(gòu)建自己的代碼,。當(dāng)然,這包括通過構(gòu)建測試,。與任何提交周期一樣,,開發(fā)人員首先更新其工作分支以匹配主干,解決與主干的任何沖突,,然后在其本地上構(gòu)建,。如果構(gòu)建通過,那么他們可以自由地提交到主干上,。
通過經(jīng)常這樣做,,開發(fā)人員可以快速發(fā)現(xiàn)兩個(gè)開發(fā)人員之間是否存在沖突??焖傩迯?fù)問題的關(guān)鍵是快速找到它們,。由于開發(fā)人員每隔幾小時(shí)就提交一次沖突,所以在沖突生后的幾小時(shí)內(nèi)就可以檢測到,,此刻沒有發(fā)生太多代碼修改,,所以容易解決。持續(xù)數(shù)周不被發(fā)現(xiàn)的沖突,,可能很難解決,。
在更新工作分支時(shí)進(jìn)行構(gòu)建,這一事實(shí)意味著可以同時(shí)檢測到編譯沖突和文本沖突,。由于構(gòu)建是自測試的,,所以你還可以檢測代碼運(yùn)行中的沖突,如果后一種Bug在代碼中存在了很長時(shí)間而沒有被發(fā)現(xiàn),,那么它們是特別難以發(fā)現(xiàn)的錯(cuò)誤,。由于兩次提交之間只有幾個(gè)小時(shí)的更改,所以問題隱藏的地方也就只有那么多了。此外,,由于沒有太大的變化,,你可以使用差異調(diào)試來幫助你找到錯(cuò)誤。
我的一般經(jīng)驗(yàn)法則是,,每個(gè)開發(fā)人員每天都應(yīng)該提交到代碼庫,。在實(shí)踐中,如果開發(fā)人員更頻繁地提交,,通常是有用的,。提交的頻率越高,尋找沖突錯(cuò)誤的地方就越少,,解決沖突的速度也就越快,。
頻繁的提交會鼓勵(lì)開發(fā)人員將他們的工作分解成幾個(gè)小時(shí)的小塊。這有助于跟蹤進(jìn)度,,并提供一種進(jìn)度感,。通常人們一開始覺得他們不能在幾個(gè)小時(shí)內(nèi)做一些有意義的事情,但是我們發(fā)現(xiàn)指導(dǎo)和練習(xí)可以幫助他們學(xué)習(xí),。
2.5 每次提交都應(yīng)該在集成機(jī)上構(gòu)建主線
通過使用每日構(gòu)建,,團(tuán)隊(duì)可以得到頻繁的測試構(gòu)建。這應(yīng)該意味著主干保持在健康的狀態(tài),。然而,,在實(shí)踐中,依然有出錯(cuò)的情況,。一個(gè)原因是紀(jì)律,,人們沒有在提交之前進(jìn)行更新和構(gòu)建。另一個(gè)原因是開發(fā)人員使用的機(jī)器之間的環(huán)境差異,。
因此,,你應(yīng)該確保常規(guī)構(gòu)建發(fā)生在集成機(jī)器上,并且只有在此集成構(gòu)建成功時(shí),,才應(yīng)該認(rèn)為提交已經(jīng)完成,。由于開發(fā)人員對提交的代碼負(fù)責(zé),所以該開發(fā)人員需要監(jiān)視主干構(gòu)建,,以便在它崩潰時(shí)進(jìn)行修復(fù),。這樣做的一個(gè)推論是,你如果在當(dāng)天晚些時(shí)候提交了一些改動,,那么在主干構(gòu)建通過之前你不能回家,。
我見過兩種主要的方法來確保這一點(diǎn):使用手動構(gòu)建或持續(xù)集成服務(wù)器。
手工構(gòu)建方法是描述起來最簡單的方法,。本質(zhì)上,它類似于開發(fā)人員在提交到存儲庫前進(jìn)行的本地構(gòu)建。開發(fā)人員走到集成計(jì)算機(jī),,簽出主線的頭部(現(xiàn)在存放他的最后提交),,并開始集成構(gòu)建。他會密切關(guān)注構(gòu)建的進(jìn)展,,如果構(gòu)建成功,,他就完成了提交。(參見Jim Shore的描述,。)
持續(xù)集成服務(wù)器充當(dāng)存儲庫的監(jiān)視器,。每次完成對代碼庫的提交時(shí),服務(wù)器都會自動將源簽出到集成機(jī)器上,,啟動構(gòu)建并將構(gòu)建的結(jié)果通知提交者,。直到提交者收到通知——通常是一封電子郵件——它才算完成。
在ThoughtWorks,,我們是持續(xù)集成服務(wù)器的忠實(shí)粉絲——事實(shí)上,,我們領(lǐng)導(dǎo)了CruiseControl和CruiseControl.NET的起初的開發(fā),他們是被廣泛使用的開源CI服務(wù)器,。從那時(shí)起,,我們還建立了商業(yè)版的Cruise CI服務(wù)器。我們幾乎在每個(gè)項(xiàng)目上都使用CI服務(wù)器,,并且對結(jié)果非常滿意,。
并不是所有人都喜歡使用CI服務(wù)器。吉姆·肖爾(Jim Shore)對他為什么更喜歡手工方法給出了一個(gè)頗有爭議的描述,。我同意他的觀點(diǎn),,CI不僅僅是安裝一些軟件。這里的所有實(shí)踐都需要有效地進(jìn)行持續(xù)集成,。但是,,同樣有許多優(yōu)秀的CI團(tuán)隊(duì)發(fā)現(xiàn)CI服務(wù)器是一個(gè)有用的工具。
許多組織按照定時(shí)計(jì)劃進(jìn)行定期構(gòu)建,,比如每天晚上,。這與持續(xù)構(gòu)建不同,對于持續(xù)集成來說還不夠,。持續(xù)集成的全部意義在于盡快發(fā)現(xiàn)問題,。夜間構(gòu)建意味著bug在被發(fā)現(xiàn)之前一整天都沒有被發(fā)現(xiàn)。一旦它們在系統(tǒng)中存在了那么長時(shí)間,,就需要花費(fèi)很長時(shí)間才能找到并修復(fù)它們,。
2.6 立即修復(fù)失敗的構(gòu)建
做持續(xù)構(gòu)建非常關(guān)鍵的一點(diǎn)就是一旦主線構(gòu)建失敗就要立即修改它。使用CI的意義就在于,,你總是能在已知穩(wěn)定基礎(chǔ)上進(jìn)行開發(fā),。主線構(gòu)建失敗是常有的事,,且也并不是什么壞事,但這卻能夠表明人們在提交代碼之前對本地的更新和構(gòu)建不夠小心,。然而,,當(dāng)主線構(gòu)建確實(shí)中斷時(shí),快速修復(fù)它就變得極為重要,。
我記得Kent Beck說過一句話:“沒有人擁有比修復(fù)失敗的構(gòu)建更高的優(yōu)先級任務(wù)”,。但也不必團(tuán)隊(duì)中的每個(gè)人都必須停止他們手頭的工作來修改失敗的構(gòu)建,通常只需要幾個(gè)人就可以成功修復(fù),。我們要有意識的將修復(fù)構(gòu)建作為一個(gè)緊急的,、高優(yōu)先級的任務(wù)進(jìn)行優(yōu)先排序。
通常,,修復(fù)構(gòu)建的最快方法是從主線還原到最新一次已知的,、良好的構(gòu)建提交狀態(tài)。當(dāng)然,,團(tuán)隊(duì)不應(yīng)該在構(gòu)建失敗的主線上進(jìn)行任何調(diào)試,。除非失敗的原因很明顯,否則只需恢復(fù)主線然后在開發(fā)工作站上調(diào)試問題,。
為了避免破壞主線,,你可以考慮使用pending head。
當(dāng)團(tuán)隊(duì)引入CI時(shí),,這通常是最難解決的問題之一,。在早期,團(tuán)隊(duì)很難養(yǎng)成處理主線構(gòu)建的常規(guī)習(xí)慣,,特別是在處理現(xiàn)有代碼庫時(shí),。耐心和堅(jiān)持不懈的努力看起來確實(shí)經(jīng)常起作用,,,所以不要?dú)怵H,。
2.7 保持快速構(gòu)建
持續(xù)集成的關(guān)鍵是提供快速的反饋。沒有什么比一個(gè)需要很長時(shí)間的構(gòu)建更能危害CI的活動了,。在這里我必須承認(rèn)有一些古怪的老員工把長時(shí)間的構(gòu)建當(dāng)成娛樂,。我的大多數(shù)同事認(rèn)為一個(gè)需要一個(gè)小時(shí)的構(gòu)建是完全不合理的。我記得一些團(tuán)隊(duì)夢想著他們能以如此之快的速度完成任務(wù)——但是有時(shí)候我們?nèi)匀粫龅竭@樣的情況:很難以這樣的速度完成任務(wù),。
然而,,對于大多數(shù)項(xiàng)目來說,十分鐘構(gòu)建的XP指導(dǎo)方針是完全合理的?,F(xiàn)在我們的大多數(shù)項(xiàng)目都實(shí)現(xiàn)了這一點(diǎn),。這值得我們集中精力來實(shí)現(xiàn)它,因?yàn)槊繙p少一分鐘的構(gòu)建時(shí)間,,那么對于每個(gè)開發(fā)人員的每次提交都會節(jié)省一分鐘的時(shí)間,。由于CI需要頻繁提交,,這就會增加很多的時(shí)間。
如果你一開始就需要一個(gè)小時(shí)的構(gòu)建時(shí)間,,那么獲得更快的構(gòu)建可能會讓人畏懼,。甚至在一個(gè)新的項(xiàng)目上工作,,并思考如何讓事情保持快速也會讓人畏懼,。至少對于企業(yè)應(yīng)用程序,我們發(fā)現(xiàn)通常的瓶頸是測試——特別是涉及外部服務(wù)(如數(shù)據(jù)庫)的測試,。
最關(guān)鍵的一步是開始建立部署流水線,。部署流水線(也稱為構(gòu)建流水線或分階段構(gòu)建)背后的思想是,實(shí)際上有多個(gè)按順序完成的構(gòu)建,。對主線的提交觸發(fā)了第一個(gè)構(gòu)建——我稱之為提交構(gòu)建,。提交構(gòu)建是當(dāng)有人需要提交到主線時(shí)所需的構(gòu)建。提交構(gòu)建是必須快速完成的構(gòu)建,,因此它將采用許多快捷方式,,這將降低檢測錯(cuò)誤的能力。關(guān)鍵在于平衡發(fā)現(xiàn)bug的能力和速度的需求,,這樣一個(gè)好的提交構(gòu)建就足夠穩(wěn)定,,可以供其他人工作使用
一旦有良好的提交構(gòu)建,其他人就可以滿懷信心地處理代碼,。不過,,你可以開始做更多、更漫長的測試,。其他機(jī)器可以在構(gòu)建上運(yùn)行需要更長時(shí)間的測試程序,。
這是一個(gè)簡單的兩階段部署流水線例子。第一階段將進(jìn)行編譯并運(yùn)行更本地化的單元測試,,數(shù)據(jù)庫通過“打樁”的方式完全被隔離掉,。這樣測試可以運(yùn)行得非常快,,保持在10分鐘的范圍內(nèi),。但是,任何涉及大規(guī)模交互的bug,,特別是涉及真實(shí)數(shù)據(jù)庫的bug,,都很難被發(fā)現(xiàn)。第二階段構(gòu)建運(yùn)行一組不同的測試,,這些測試確實(shí)會測試真實(shí)的數(shù)據(jù)庫,,并涉及更多的端到端行為。這一次運(yùn)行可能需要幾個(gè)小時(shí)的時(shí)間,。
在這個(gè)場景中,,人們使用第一個(gè)階段作為提交構(gòu)建,,并使用它作為主CI周期。第二階段構(gòu)建在可能的情況下運(yùn)行,,從最近的良好提交構(gòu)建中獲取可執(zhí)行文件以進(jìn)行進(jìn)一步的測試,。如果這個(gè)二次構(gòu)建失敗,那么它可能沒有 “停止一切”的質(zhì)量目標(biāo),,但是團(tuán)隊(duì)的目標(biāo)是在保持提交構(gòu)建運(yùn)行的同時(shí),,盡快修復(fù)此類錯(cuò)誤。在這個(gè)例子中,,后面的構(gòu)建通常是純測試,,因?yàn)楝F(xiàn)在通常是測試導(dǎo)致了緩慢。
如果第二級構(gòu)建檢測到一個(gè)bug,,這表明提交構(gòu)建可能使用另一套測試,。盡可能地確保任何后期階段的失敗,都會觸發(fā)在提交構(gòu)建中引入新的測試,,這樣在提交構(gòu)建中就能捕獲bug,,從而在提交構(gòu)建中就能解決掉這些bug。這樣,,每當(dāng)有錯(cuò)誤漏過提交時(shí),,提交測試就會加強(qiáng)。在某些情況下,,沒有一種快速運(yùn)行的測試來暴露bug,,因此你可能決定只在第二級構(gòu)建中測試該條件。幸運(yùn)的是,,大多數(shù)情況下,,你可以向提交構(gòu)建添加適當(dāng)?shù)臏y試。
這個(gè)例子是一個(gè)兩級流水線,,但是基本原理可以擴(kuò)展到任何后期階段,。提交構(gòu)建之后的構(gòu)建也可以并行完成,因此如果有兩個(gè)小時(shí)的第二階段測試,,則可以通過讓兩臺機(jī)器分別運(yùn)行一半的測試來提高響應(yīng)速度,。通過使用類似這樣的并行第二階段構(gòu)建,你可以將進(jìn)一步的自動化測試(包括性能測試)引入到常規(guī)構(gòu)建過程中,。
2.8 在生產(chǎn)環(huán)境的克隆中測試
測試的重點(diǎn)是在受控條件下,,清除系統(tǒng)在生產(chǎn)中可能出現(xiàn)的任何問題。其中很重要的一部分是生產(chǎn)系統(tǒng)運(yùn)行的環(huán)境,。如果你在不同的環(huán)境中進(jìn)行測試,,每一個(gè)差異都會導(dǎo)致風(fēng)險(xiǎn),即在測試中發(fā)生的事情不會在生產(chǎn)中發(fā)生,。
因此,,你希望將測試環(huán)境設(shè)置為盡可能精確地模擬生產(chǎn)環(huán)境,。使用相同版本的數(shù)據(jù)庫軟件,使用相同版本的操作系統(tǒng),。將生產(chǎn)環(huán)境中的所有適用的庫放入測試環(huán)境中,,即使系統(tǒng)實(shí)際上沒有使用它們。使用相同的IP地址和端口,,在相同的硬件上運(yùn)行它,。
事實(shí)上,這是有限度的,。如果你正在編寫桌面軟件,,使用不同人員運(yùn)行的、并安裝了所有的第三方軟件的桌面克隆中,,進(jìn)行測試那是不現(xiàn)實(shí)的。類似地,,有些生產(chǎn)環(huán)境的復(fù)制成本可能高得令人望而卻步(盡管我經(jīng)常遇到不復(fù)制中等成本的環(huán)境而產(chǎn)生的浪費(fèi)成本),。盡管存在這些限制,你的目標(biāo)仍然應(yīng)該是盡可能多地復(fù)制生產(chǎn)環(huán)境,,并理解測試和生產(chǎn)之間的每一個(gè)差異所帶來的風(fēng)險(xiǎn),。
如果你有一個(gè)非常簡單的設(shè)置,而沒有許多笨拙的通信,,那么你可以在模擬的環(huán)境中運(yùn)行提交構(gòu)建,。但是,通常需要使用測試替身(test double),,因?yàn)橄到y(tǒng)響應(yīng)緩慢或不夠穩(wěn)定,。因此,通常都有一個(gè)非常人工的環(huán)境來進(jìn)行提交測試,,以提高速度,,并使用生產(chǎn)克隆進(jìn)行輔助測試。
我注意到越來越多的人對使用虛擬化來簡化測試環(huán)境的組合越來越感興趣,。虛擬化的機(jī)器可以保存在虛擬化中的所有必要元素中,。安裝最新的構(gòu)建和運(yùn)行測試相對簡單。此外,,這還允許你在一臺計(jì)算機(jī)上運(yùn)行多個(gè)測試,,或者在一臺計(jì)算機(jī)上模擬網(wǎng)絡(luò)中的多臺計(jì)算機(jī)。隨著虛擬化的性能損失降低,,這個(gè)選項(xiàng)變得越來越有意義,。
2.9 任何人都能輕松獲得最新的可執(zhí)行文件
軟件開發(fā)中最困難的部分之一是確保你構(gòu)建了正確的軟件。我們發(fā)現(xiàn),,很難事先明確自己想要什么,,也很難做到正確,;人們更容易看到不太正確的東西,并說出需要如何改變,。敏捷開發(fā)過程明確地期望并利用人類行為的這一部分,。
為了幫助實(shí)現(xiàn)這一點(diǎn),任何參與軟件項(xiàng)目的人都應(yīng)該能夠獲得最新的可執(zhí)行文件并能夠運(yùn)行它:用于演示,、探索性測試,,或者只是看看本周發(fā)生了什么變化。.
這樣做非常簡單:確保有一個(gè)眾所周知的地方,,人們可以找到最新的可執(zhí)行文件,。在這樣的存儲中放置幾個(gè)可執(zhí)行文件可能是有用的。對于最新的可執(zhí)行文件,,你應(yīng)該放置最新的可執(zhí)行文件以通過提交測試—如果提交套件相當(dāng)強(qiáng)大,,那么這樣的可執(zhí)行文件應(yīng)該相當(dāng)穩(wěn)定。
如果你正在使用定義良好的迭代來跟蹤一個(gè)流程,,那么通常明智的做法是將迭代構(gòu)建的結(jié)束也放在流程里,。特別是演示,需要的是讓人熟悉功能的軟件,,因此通常為演示者知道如何操作的,,而犧牲最新的一些事是值得的。
2.10 每個(gè)人都可以看到正在發(fā)生什么
持續(xù)集成就是為了溝通,,所以你希望保證每個(gè)人都能很方便的看到系統(tǒng)當(dāng)前的狀態(tài)以及在系統(tǒng)上所做的改變,。
其中用于溝通的最重要的一個(gè)途徑是主線構(gòu)建的狀態(tài)。如果你使用Cruise,,那么有一個(gè)網(wǎng)站可以展示給你看是否有個(gè)構(gòu)建正在進(jìn)行,,以及最后一次主線構(gòu)建的狀態(tài)。很多團(tuán)隊(duì)喜歡將持續(xù)顯示和構(gòu)建系統(tǒng)連接起來,,從而使它更顯而易見,。通常用燈來表示:綠燈表示構(gòu)建成功,當(dāng)失敗的時(shí)候則亮紅燈,。常見的一個(gè)設(shè)計(jì)是紅色和綠色的熔巖燈—不僅僅給出這些構(gòu)建狀態(tài)的指示,,而且還指示已經(jīng)處于該種狀態(tài)多久了。紅色熔巖燈上的氣泡表明此次構(gòu)建已經(jīng)失敗很久了,。每個(gè)團(tuán)隊(duì)都可以自己選擇構(gòu)建傳感器—當(dāng)然你的選擇也可以是很好玩的(最近我看到有人在用一只跳舞的兔子),。
即使你使用手動的持續(xù)集成,可視化依然很重要,。物理構(gòu)建機(jī)器的監(jiān)視器可以展現(xiàn)主線構(gòu)建的狀態(tài),。通常可以給正在構(gòu)建的人的桌子上放一個(gè)構(gòu)建令牌(再說一次,像橡膠雞這樣的蠢東西也是一個(gè)很好的選擇),。人們常常喜歡給構(gòu)建成功加上一點(diǎn)簡單的噪音,,比如說鈴聲。
當(dāng)然,,持續(xù)集成服務(wù)器的網(wǎng)頁可以承載更多的信息,。Cruise不僅能提供誰正在構(gòu)建,而且還能提供他們做了什么改變,。Cruise還可以提供改變的歷史,,以使得團(tuán)隊(duì)成員可以對當(dāng)前項(xiàng)目中最近的行為有更好的了解。我知道團(tuán)隊(duì)的領(lǐng)導(dǎo)喜歡用這些信息來了解團(tuán)隊(duì)成員在做什么以及保持對系統(tǒng)改變的感知,。
使用網(wǎng)站的另外一個(gè)優(yōu)勢是那些異地辦公的成員可以獲知項(xiàng)目狀態(tài),。一般來說,我傾向于積極緊密工作在同一個(gè)項(xiàng)目上的成員坐在一起,,但是經(jīng)常還會有一些其他人員關(guān)心項(xiàng)目的相關(guān)事宜,。同時(shí)對于組織將多個(gè)項(xiàng)目的構(gòu)建信息聚合在一起也是很有用的—可以為不同的項(xiàng)目提供一個(gè)簡單并且自動的狀態(tài)。
好的信息展示不僅僅是電腦屏幕上那些,。我最喜歡的一個(gè)信息展示來自一個(gè)使用持續(xù)集成的項(xiàng)目上,。它在一個(gè)很長的時(shí)間里不能穩(wěn)定構(gòu)建。我們把一整年的日歷放到墻上,,用一個(gè)方框表示一年中的一天。如果QA團(tuán)隊(duì)得到一個(gè)通過了提交測試的穩(wěn)定的構(gòu)建,,他們會把一個(gè)綠色的貼紙放到這一天的方框里,,反之則放一個(gè)紅的貼紙。隨著時(shí)間過去,,日歷揭示了構(gòu)建過程持續(xù)改善的情況,,直到綠色的方框越來越多的時(shí)候,日歷就消失了—因?yàn)檫_(dá)到了它的目的,。
2.11 自動化部署
為了做持續(xù)集成,,你需要多個(gè)環(huán)境,一個(gè)用來運(yùn)行提交測試,,一個(gè)或者多個(gè)用來運(yùn)行第二階段測試,。因?yàn)槟忝刻於家谶@些環(huán)境之間移動可執(zhí)行文件很多次,所以你希望能自動的做這些事兒,。很重要的是你要有一些腳本可以很容易的把應(yīng)用部署到任意環(huán)境中去,。
這么做很自然的結(jié)果就是你還應(yīng)該有腳本,以使得你可以同樣簡單的部署到生產(chǎn)環(huán)境,。你可能不會每天都部署到生產(chǎn)環(huán)境(雖然我曾經(jīng)參與過這樣的項(xiàng)目),,但是自動化部署可以幫助你提高速度并且減少錯(cuò)誤。這同樣是一個(gè)便宜的選項(xiàng),因?yàn)檫@只是使用了你用于部署到測試環(huán)境的相同資源,。
如果你在生產(chǎn)環(huán)境自動部署,,那么你需要考慮的一個(gè)額外的功能是自動回滾。糟糕的事情隨時(shí)會發(fā)生,,如果發(fā)臭的棕色物質(zhì)撞到旋轉(zhuǎn)的金屬上(情況不妙),,最好能夠很快的回到最后一個(gè)已知的好的狀態(tài)。能夠自動回滾,,可以大大減少部署產(chǎn)生的緊張感,,鼓勵(lì)人們更頻繁的部署,因此我們可以更快的把新特性提供給用戶,。(Ruby on Rails社區(qū)開發(fā)了一款名為Capistrano的工具,,是做此類事情的工具的一個(gè)好例子)
在集群環(huán)境中我看到滾動部署,新的軟件會一次部署到一個(gè)節(jié)點(diǎn),,然后在幾個(gè)小時(shí)內(nèi)慢慢將整個(gè)應(yīng)用替換掉,。
對于面向大眾的網(wǎng)站應(yīng)用,我接觸到的一個(gè)很有趣的部署方式是:將一個(gè)試用版本部署給部分用戶,。接著團(tuán)隊(duì)可以觀察該試用版本是如何被使用的,,然后決定是否將其部署給全量用戶。這使得你可以在做出最終選擇之前測試新特性和用戶接口,。自動化部署結(jié)合良好的持續(xù)集成原則,,是此工作的重要基礎(chǔ)。

三,、持續(xù)集成的好處

總起來說我認(rèn)為持續(xù)集成最顯著也是最寬泛的好處在于減少了風(fēng)險(xiǎn),。我又想起了在本文第一段中提到的軟件項(xiàng)目。團(tuán)隊(duì)已經(jīng)處于一個(gè)漫長項(xiàng)目的末期(起碼他們是這么認(rèn)為的),,但是還沒法判斷距離項(xiàng)目真正做完還有多久,。

推遲集成的麻煩在于很難預(yù)測到底需要多久來做這件事兒,并且更糟糕的是甚至很難看到你在這個(gè)過程中的進(jìn)展,。結(jié)果就是,,即使你是少數(shù)幾個(gè)還沒延遲的案例之一,你也會在項(xiàng)目最緊張的部分陷入完全的盲區(qū),。

持續(xù)集成完全可以解決這個(gè)問題,。沒有了長期的集成,你就可以完全的消除盲區(qū),。在所有的時(shí)間點(diǎn)上你都會知道你身處何處,,什么可以工作,什么不能工作,,你的系統(tǒng)里有什么最大的bug,。

Bug—也就是那些討厭的東西,會摧毀我們的信心,破壞我們的計(jì)劃和聲譽(yù),。如果已經(jīng)發(fā)布的軟件中有缺陷,,用戶就會對你很生氣。而正在進(jìn)行的工作中有bug,,則會擋住你的道路,,會使得接下來的工作變得更加困難。

持續(xù)集成不會避免bug,,但是它可以讓你非常容易找到并消除bug,。從這個(gè)角度看它很像自測代碼。如果你引入了一個(gè)bug后能很快檢測到它,,那么就能很容易改正它,。因?yàn)槟阒皇菍ο到y(tǒng)做了一個(gè)很小的改變,你不用往回追溯太遠(yuǎn),。因?yàn)橄到y(tǒng)的那一部分正是你剛剛工作過的那一部分,,它還很清楚的存在于你的記憶里—這使得查找bug很容易。你還可以使用diff debugging,,來對系統(tǒng)的當(dāng)前版本和沒有bug的更早的版本作比較,。

Bug也是累積的。你的bug越多,,消除每一個(gè)bug也就越不容易,。一定程度上是因?yàn)閎ug互相影響,表現(xiàn)出來的失敗可能是很多錯(cuò)誤共同疊加的結(jié)果—這就導(dǎo)致很難找到每一個(gè)錯(cuò)誤,。這也是心理上的,,當(dāng)有很多bug的時(shí)候,人們自然就缺少激情去找到并解決這些bug—這是一種在《Pragmatic Programmer》一書中被稱為“破窗效應(yīng)”的現(xiàn)象,。

因此,使用了持續(xù)集成的項(xiàng)目,,無論是在生產(chǎn)環(huán)境里,,還是在開發(fā)過程中,其bug的數(shù)量將會極大的減少,。但是需要強(qiáng)調(diào)的是,,受益的程度直接取決于你的測試套件的好壞。你應(yīng)該可以看到,,構(gòu)建一個(gè)帶來顯著差異的測試套件并不是那么困難,。當(dāng)然,通常一個(gè)團(tuán)隊(duì)真正達(dá)到他們可能達(dá)成的較低水平的bug程度,,需要一定的時(shí)間,。要達(dá)到這個(gè)水平意味著需要持續(xù)的改善你的工作。

如果你使用了持續(xù)集成,它會消除掉頻繁部署的一個(gè)最大障礙,。對于能夠?yàn)樾绿匦愿斓墨@得反饋來說,,頻繁部署是有價(jià)值的,因?yàn)樗梢允鼓愕挠脩艉芸煊蒙线@些新的特性,,而且頻繁部署可以使他們(開發(fā)團(tuán)隊(duì)和用戶)在開發(fā)周期中更加協(xié)作,。這將有利于打破客戶和開發(fā)之間的障礙—我認(rèn)為該障礙是成功的軟件開發(fā)中最大的障礙。

四,、引入持續(xù)集成

所以如果你想要嘗試下持續(xù)集成的話,,從哪兒開始呢?上面我提到的所有的實(shí)踐可以帶給你全部的收益,,但是你并不需要一開始就把它們都用上,。

這兒其實(shí)并沒有固定的套路,而是很大程度上依賴于你的配置和團(tuán)隊(duì)的現(xiàn)狀,。但是我們也學(xué)到下面的一些經(jīng)驗(yàn)可以幫助我們把接下來要做的事情搞清楚,。

  • 第一步就是把構(gòu)建自動化。把你所有需要用到的東西都放到源碼控制系統(tǒng)中,,從而你可以用一條指令來構(gòu)建整個(gè)系統(tǒng),。對于很多項(xiàng)目來說,這并不是一件小事——但是它是其他所有的事情的基礎(chǔ),。一開始的時(shí)候你可能只是偶爾按需構(gòu)建,,或者只是做自動的每夜構(gòu)建。當(dāng)還不是持續(xù)集成的時(shí)候,,自動的每夜構(gòu)建也是一個(gè)很好的開始,。

  • 在你的構(gòu)建中引入一些自動化測試。嘗試著識別出問題最多的部分,,并且加入自動化測試以暴露這些問題,。需要特別指出,在一個(gè)現(xiàn)存的項(xiàng)目上非??斓膶?shí)現(xiàn)一個(gè)真正好的測試套件是很困難的—因?yàn)樾枰獣r(shí)間來構(gòu)建測試,。你必須從某個(gè)地方開始—畢竟羅馬不是一天建成的。

  • 盡量加速提交的構(gòu)建,。構(gòu)建需要幾個(gè)小時(shí)的持續(xù)集成也比沒有持續(xù)集成要強(qiáng),,但是如果能將這個(gè)時(shí)間降到10分鐘那就太好了。這通常需要對你的代碼基礎(chǔ)做一些相當(dāng)大的手術(shù),,因?yàn)槟阈枰蚱茖τ谙到y(tǒng)中較慢部分的依賴,。

  • 如果你開始一個(gè)新的項(xiàng)目,那么從一開始就用持續(xù)集成,。一直關(guān)注構(gòu)建時(shí)間,,一旦構(gòu)建速度變慢,,超過10分鐘的時(shí)候,馬上采取行動,。通過很快的采取行動,,你可以在代碼變得太大以至于成為主要的痛點(diǎn)之前進(jìn)行必要的重構(gòu)。

上面所有的這些都可以給我們提供一些幫助,。找到一個(gè)以前做過持續(xù)集成的人來幫助你,。和任何新技術(shù)一樣,當(dāng)你還不知道最終結(jié)果會是什么樣子的時(shí)候,,很難引入該技術(shù),。找一個(gè)導(dǎo)師來可能會花一些錢,但是如果不這樣做,,你將不得不付出大量的時(shí)間和生產(chǎn)效率,。(免責(zé)聲明/廣告—是的,我們ThoughtWorks在該領(lǐng)域提供顧問工作,,畢竟我們已經(jīng)犯過大多數(shù)你們將要犯的錯(cuò)誤,。)

五、最后的思考

在Matt和我寫完這個(gè)網(wǎng)站上最初的論文后的幾年中,,持續(xù)集成變成了軟件開發(fā)的一個(gè)主流技術(shù),。ThoughtWorks的項(xiàng)目中很少有不用它的—并且我們可以看到遍布全球的很多人也在使用持續(xù)集成。不像一些有爭議的極限編程實(shí)踐一樣,,我很少聽到關(guān)于持續(xù)集成的負(fù)面反饋,。

如果你沒有正在使用持續(xù)集成,那么我強(qiáng)烈建議你嘗試一下,。如果你正在使用持續(xù)集成,,那么這篇文章里的一些想法可以幫助你做得更有效率。在過去的幾年里,,關(guān)于持續(xù)集成我們已經(jīng)學(xué)習(xí)了很多,,我希望依然有更多的東西可以學(xué)習(xí)和改善。

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多