持續(xù)集成(continuous integration)作為敏捷編程的基石現(xiàn)在已經(jīng)被絕大多數(shù)的開(kāi)發(fā)團(tuán)隊(duì)所廣泛采用。而持續(xù)集成的工具現(xiàn)如今也是百花齊放,各有千秋,本文主要對(duì)比了在Java領(lǐng)域中比較常見(jiàn)的幾種CI server(因?yàn)楣疽蠼y(tǒng)一整個(gè)公司的CI server)。如果想了解更多的工具,可以看這里:http://confluence.public.thoughtworks.org/display/CC/CI+Feature+Matrix,這個(gè)網(wǎng)頁(yè)集中了決大多數(shù)比較流行的CI server,但是我發(fā)現(xiàn)很多的內(nèi)容已經(jīng)落后于實(shí)際產(chǎn)品的功能了,所以如果要對(duì)比的話,可能要實(shí)際到產(chǎn)品的站點(diǎn)去看一下,最好還是下載下來(lái)運(yùn)行起來(lái)看。
在本文中,我主要針對(duì)以下幾種CI Server作對(duì)比,這也是公司里各個(gè)項(xiàng)目組目前自行選用的(版本有點(diǎn)多,國(guó)內(nèi)的多選用了一些open source的,而老外那邊用得比較多的是商用版本,CruiseControl和TeamCity是我加的,因?yàn)槊麣夥浅4?/strong>。):
- CruiseControl (http://cruisecontrol.sourceforge.net/)
- Hudson (https://hudson.dev.java.net/)
- LuntBuild (http://luntbuild.javaforge.com/)
- TeamCity (http://www.jetbrains.com/teamcity/)
- AntHill Pro (http://www.anthillpro.com/)
- Bamboo (http://www.atlassian.com/software/bamboo/)
- QuickBuild (http://www.pmease.com/)
在持續(xù)集成領(lǐng)域,
==>OpenSource的CruiseControl和LuntBuild可謂老牌了,尤其是CruiseControl,出自thoughtworks,這可是Martin Fowler的老巢啊。
==>Hudson作為OpenSource里持續(xù)集成的后起之秀,現(xiàn)在已經(jīng)趕超了這兩個(gè)前輩,目前恐怕是使用最多的一個(gè)CI Server了。
而后面4個(gè)是商用的CI Server,
==>其中TeamCity是來(lái)自jetbrains的,
==>jetbrains是開(kāi)發(fā)著名的IDE IntelliJ的公司。
==>Bamboo則是開(kāi)發(fā)著名的Bug Tracking工具Jira和Wiki Confluence的公司atlassian公司出品的。
==>AntHill也屬于Continuous Integration界的元老,
==>QuickBuild則是LuntBuild的商業(yè)版本,
我在下面重點(diǎn)考量的是QuickBuild,因?yàn)長(zhǎng)untBuild好像現(xiàn)在更新較慢了,而且QuickBuild現(xiàn)在好像也有了免費(fèi)的所謂的Community Edition,功能齊全,只是配置數(shù)有所限制。
在這些商業(yè)版本中,TeamCity應(yīng)該是目前市場(chǎng)占有率最高的。
由于公司里比較傾向使用商業(yè)版本的服務(wù)器,所以我重點(diǎn)比較的是后4種,捎帶比較了一下CruiseControl和Hudson。TeamCity和QuickBuild都有各自的免費(fèi)版本,有興趣的也可以去看看。
功能對(duì)比
CI Server在本質(zhì)上就是一個(gè)定時(shí)調(diào)度器。我們配置一系列的項(xiàng)目,然后設(shè)定一個(gè)定時(shí)器,讓它干一些活,然后通知大家。所以很多公司都使用所謂Home-made的工具,用cron+Ant/Maven來(lái)做持續(xù)集成,這個(gè)就已經(jīng)可以達(dá)到CI的最簡(jiǎn)單的功能了。而使用工具,就是我們除了基本的編譯和通知功能以外,我們還有很多其它的需求,在我們公司里,選擇CI Server主要考慮以下幾點(diǎn):
- 便于公司的統(tǒng)一管理(大約有200+ Projects需要統(tǒng)一管理)
- 對(duì)于項(xiàng)目本身進(jìn)行流程管理: Daily Build -> QA Build -> Release Build
- 和公司AD(Active Directory)的連接以對(duì)用戶進(jìn)行權(quán)限管理
- Continuous Testing的支持,即對(duì)于項(xiàng)目的Test要能產(chǎn)生出詳盡的報(bào)告以及收集Test的統(tǒng)計(jì)數(shù)據(jù)以作為項(xiàng)目的分析和考量
- Continuous Code Quality Analysis的支持,即能處理項(xiàng)目產(chǎn)生的Coverage報(bào)告,Code的static analysis報(bào)告,并且能收集這些報(bào)告的統(tǒng)計(jì)數(shù)據(jù)以作項(xiàng)目的分析和考量
- 與SCM工具的集成,我們公司主要有三種VCS,ClearCase, Subversion和StarTeam
- 與其它工具的集成,如bug tracking工具,IDE集成等等。
首先,我們從安裝的角度來(lái)查看一下
安裝CI
安裝是我們開(kāi)始的第一步,同時(shí)也對(duì)各個(gè)CI server都有了初步的印象。按照各自的手冊(cè),很快就裝好了,我基本上選擇的是Standalone的版本,就是不配置數(shù)據(jù)庫(kù),使用自帶的,也不deploy到Tomcat或者其它容器,這點(diǎn),基本上每個(gè)CI Server都非常簡(jiǎn)單。所以也沒(méi)看出什么好壞來(lái)。這里不得不提一下AntHill,有點(diǎn)小家子氣,要download還得提交一個(gè)request,然后才能下載,安裝,有點(diǎn)煩。
配置項(xiàng)目
在大多數(shù)的CI Server中,絕大部分都是以Project或者Project Group來(lái)進(jìn)行管理,只有LuntBuild和QuickBuild比較另類,它們使用了Configuration這個(gè)術(shù)語(yǔ),意即一個(gè)配置。在配置一個(gè)典型的項(xiàng)目的時(shí)候,即只處理基本的一個(gè)流程:CheckOut, Build, Publish Artifacts,這些工具都完成的非常好,也非常簡(jiǎn)單,我使用下來(lái),覺(jué)得TeamCity的導(dǎo)航最方便,一目了然。而LuntBuild和QuickBuild在這方面稍顯人性化不足,這兩個(gè)工具都沒(méi)有使用wizard的模式。
下面,我接著實(shí)驗(yàn)配置50個(gè)測(cè)試項(xiàng)目,這也就開(kāi)始考驗(yàn)一個(gè)CI Server的管理能力了(因?yàn)槲覀冺?xiàng)目較多)。使用下來(lái),我發(fā)現(xiàn)QuickBuild對(duì)于我而言,最實(shí)用。因?yàn)樗褂肅onfiguration而不是Project,并且QuickBuild是這些CI Server中唯一支持樹(shù)狀結(jié)構(gòu)配置的。我可以把Configuration配置成Team A, Team B ...,然后根據(jù)實(shí)際情況,對(duì)每個(gè)Team配置任意多個(gè)子節(jié)點(diǎn),孫節(jié)點(diǎn)(注意,Configuration的數(shù)目在QuickBuild的Community Edition里是要限制的,好像是最多16個(gè)).
==>另外,QuickBuild的繼承關(guān)系使用起來(lái)也非常方便,如果要管理一個(gè)大型的CI Server,沒(méi)有這種繼承對(duì)我而言簡(jiǎn)直是一種折磨。比如說(shuō)用hudson來(lái)配置50個(gè)項(xiàng)目,我折騰了大半天,而用QuickBuild來(lái),我大約只用了一個(gè)小時(shí),我實(shí)際配置的Configuration(含有實(shí)際step定義的)只有3個(gè),其它的都是繼承下來(lái),然后修改了一下參數(shù)而已,而如果我們需要批量修改一系列的configurations的時(shí)候,則由于有繼承關(guān)系,通常我們只要去修改一下父節(jié)點(diǎn)的設(shè)置就可以了。TeamCity支持Project Group的概念,類似于一種樹(shù)形,但是還不完備,它只能分成兩級(jí)關(guān)系,即Project Group和Project。
==>另外QuickBuild所擁有的繼承的功能,在別的CI里沒(méi)有看到過(guò),有的只是象TeamCity類似的copy project的功能。而QuickBuild在復(fù)制的能力上遠(yuǎn)遠(yuǎn)勝過(guò)其它的CI Server,它可以整個(gè)子樹(shù)拷貝,這也就意味著,我可以配置一個(gè)公司用的template configuration樹(shù),然后復(fù)制出A部門(mén),B部門(mén),C部門(mén),等等等等。對(duì)于不同項(xiàng)目之間的區(qū)別則通過(guò)變量來(lái)控制,贊一個(gè)!TeamCity在配置的方便上真得是沒(méi)話說(shuō),非常直觀,最酷的是象JUnit,NUnit這樣的Tests,連Ant腳本都不需要寫(xiě)了,它直接就可以找出項(xiàng)目里的unit tests,這個(gè)在其它的工具里也沒(méi)有看到過(guò)。至于CruiseControl,Hudson,Bamboo等則是中規(guī)中矩,無(wú)甚亮點(diǎn)。
這個(gè)環(huán)節(jié),QuickBuild和TeamCity勝出。
另外配置一個(gè)項(xiàng)目要配的就是項(xiàng)目持續(xù)集成的流程管理,在我們這里,基本上是這樣一個(gè)流程: Daily Build -> QA Build -> Integration Build -> Release Build。所謂Daily Build,顧名思義,就是每天一次的,由development team管理以保證項(xiàng)目的順暢執(zhí)行,然后經(jīng)過(guò)一段時(shí)間后,development team要提交到QA那邊進(jìn)行測(cè)試,通常是2個(gè)星期到一個(gè)月左右,隨項(xiàng)目大小不等,QA測(cè)試結(jié)束之后,如果沒(méi)有重大的問(wèn)題,則提交作Integration Test,以保證在模擬的實(shí)際環(huán)境中能正常工作,最后,如果沒(méi)有什么問(wèn)題的話則作Release Build以形成發(fā)布版本。對(duì)于公司里有一些Team使用敏捷編程的,則需要增加所謂的Commit Test Build,也就是developer在作每一個(gè)checkin的時(shí)候自動(dòng)觸發(fā)一個(gè)build,以保證build不會(huì)被這個(gè)checkin破壞(包括不會(huì)破壞unit tests和code quality)。這也是所謂的要作continuous testing和continuous code quality analysis,這些都是通過(guò)利用JUnit, NUnit,CheckStyle, PMD,Cobertura,F(xiàn)xCop等工具來(lái)實(shí)現(xiàn)的。我們?cè)诤竺嬉矔?huì)講到,這里略過(guò)。這個(gè)環(huán)節(jié)里,個(gè)人比較喜歡AntHill Pro和QuickBuild,這兩個(gè)工具都是比較強(qiáng)調(diào)流程的,尤其是AntHill Pro更是將其作為賣(mài)點(diǎn)。AntHill Pro以工作流的模式來(lái)定義這個(gè)流程,一個(gè)項(xiàng)目可以定義多個(gè)的workflow,對(duì)應(yīng)于我們的case,就是定義Daily Build的workflow,定義QA Build的workflow,等等,然后在作promote的時(shí)候,通過(guò)選擇不同的workflow來(lái)達(dá)到目的。而QuickBuild則是利用已有的configuration的概念,定義不同的Configuration,然后在Configuration的setting里定義一個(gè)或多個(gè)要promote的configurations。要作promote的時(shí)候,則通過(guò)點(diǎn)擊某個(gè)build的promote按鈕將其promote到指定的configuration上去,也很方便。使用AntHill的模式,概念上很清晰,因?yàn)槲覀円鞯氖橇鞒坦芾砺铮詗orkflow會(huì)聽(tīng)起來(lái)比較容易接受。而QuickBuild則是把它綁定在Configuration上,使用起來(lái)比較簡(jiǎn)單,但是找起來(lái)要費(fèi)點(diǎn)事,至少對(duì)于我而言是這樣。Hudson也有類似的流程管理,但是它是自動(dòng)的,而promote在我們這里是需要人來(lái)作review的,也就是說(shuō)要人去參與,判斷究竟使用哪個(gè)版本來(lái)promote,所以在我們這里,不是很合適。
在配置項(xiàng)目這個(gè)環(huán)節(jié)里,個(gè)人感覺(jué)QuickBuild比較靈活,既可以做到很簡(jiǎn)單的配置,也可以做到非常復(fù)雜的配置,而且配置起來(lái)方便性非常好。只是術(shù)語(yǔ)與其它的CI Server有些不同,需要熟悉一下。
Build功能
CI Server最重要的就是Build本身的功能,包括SCM的連接,用戶的權(quán)限管理,Build工具的支持。首先我們來(lái)看看SCM的支持。
SCM支持
在這些CI Server中,AntHill Pro和Hudson支持的種類最多,尤其是Hudson,基本上市面上的SCM都有所支持。對(duì)于象比較常見(jiàn)的Subversion,CVS,ClearCase,StarTeam,SourceSafe等,各家都已經(jīng)支持了。而在上一項(xiàng)目中表現(xiàn)較好的QuickBuild,則屬于在SCM里支持最少的一家,它還不支持git,Team Foundation Server,這個(gè)目前已經(jīng)很流行的兩種SCM,實(shí)在有些遺憾。不過(guò)瑕不掩瑜,QuickBuild在支持SCM的時(shí)候,由于使用變量的支持,卻是多家CI Server中最靈活的一家,它可以使用變量來(lái)配置SCM的URL,而其它的,則是通過(guò)定義一個(gè)基本的URL,然后針對(duì)不同項(xiàng)目來(lái)定義各自的SCM repository。而QuickBuild還有一個(gè)它自有的QuickBuild Repository,用于在不同的Configuration中傳遞artifacts,實(shí)際用起來(lái)也很方便,比如說(shuō)我們?cè)谝粋€(gè)項(xiàng)目里要用到別的項(xiàng)目的artifacts,那么就可以定義一下這個(gè)repository。當(dāng)然,這個(gè)功能也可以通過(guò)Maven的repository來(lái)完成來(lái)達(dá)到相同的目的。TeamCity也提供了類似的機(jī)制,只不過(guò)TeamCity的Repository其實(shí)就是一個(gè)Ivy的擴(kuò)展。
SCM的數(shù)據(jù)在這些CI Server中都有體現(xiàn),從每一個(gè)Build的change sets到歷史統(tǒng)計(jì)。說(shuō)明現(xiàn)在大家都很重視對(duì)于這些數(shù)據(jù)的收集和分析。其中TeamCity能直接從Web頁(yè)面上直接調(diào)用IDE來(lái)打開(kāi)這些改動(dòng)的文件是一大亮點(diǎn),畢竟是做IntelliJ的公司啊!
用戶管理
這個(gè)基本上是每個(gè)CI Server的必備功能了,基本上都是既可以用內(nèi)置的數(shù)據(jù)庫(kù)管理(Hudson好像沒(méi)用數(shù)據(jù)庫(kù)),又可以連接LDAP服務(wù)器。我只是簡(jiǎn)單測(cè)試了一下,沒(méi)有深入,也就沒(méi)有什么發(fā)言權(quán)了。
Build的Dependencies管理 (Dependent Builds)
在實(shí)際的項(xiàng)目中,我們常常會(huì)出現(xiàn)項(xiàng)目之間的依賴關(guān)系,比如說(shuō)A項(xiàng)目依賴于B項(xiàng)目,B項(xiàng)目依賴于C項(xiàng)目。所以當(dāng)我們要編譯A項(xiàng)目的時(shí)候,我們需要先編譯C項(xiàng)目,然后編譯B項(xiàng)目,最后再來(lái)編譯A項(xiàng)目,這樣做的好處顯而易見(jiàn),就是保證我們總是使用最新開(kāi)發(fā)的code來(lái)編譯一個(gè)版本,如果發(fā)生了什么問(wèn)題,我們也可以很容易的知道究竟是哪個(gè)項(xiàng)目break了整個(gè)build的流程。這個(gè)功能基本上所有的這些CI Server都有提供,而能力各有千秋。TeamCity在這里屬于最弱的一個(gè),它只能通過(guò)定義Ivy來(lái)達(dá)到Artifacts在不同項(xiàng)目中的依賴管理,而AntHill Pro,Bamboo和QuickBuild則都有提供兩種類型的dependency管理,即artifacts和項(xiàng)目本身的依賴管理。不過(guò)TeamCity卻有另外的殺手锏,就是導(dǎo)入項(xiàng)目的功能,它支持從IntelliJ的項(xiàng)目,Maven的項(xiàng)目中直接導(dǎo)入創(chuàng)建這種依賴關(guān)系。
分布式Build Pool
由于公司的項(xiàng)目繁多,平臺(tái)繁多,對(duì)于一個(gè)項(xiàng)目需要分布到不同的平臺(tái)去編譯,測(cè)試,這時(shí)候就需要建立一個(gè)Build Pool了,基本上上述各家的CI Server都已經(jīng)支持了這種分布式的build pool,其實(shí)質(zhì)是利用了grid computing技術(shù)來(lái)進(jìn)行管理。也就是一個(gè)build server帶上一群的build agent,然后把build的任務(wù)分布到不同的agent上去執(zhí)行。在這里不得不再贊一個(gè)QuickBuild了(呵呵,這個(gè)QuickBuild好像給人驚喜不斷啊),其實(shí)QuickBuild的agent與其它家的倒沒(méi)什么不同,只不過(guò)就是一個(gè)computing unit,關(guān)鍵在于QuickBuild里配置一個(gè)configuration,它使用了step的概念(這個(gè)QuickBuild的術(shù)語(yǔ)倒是不少嘛),這個(gè)step在AntHill Pro里也存在,關(guān)鍵在于這個(gè)step是可以分布的,也就是說(shuō),我配置一個(gè)項(xiàng)目的時(shí)候,可以定義一系列并行的分布式的step,這樣對(duì)于管理和收集artifacts非常方便,我們可以定義Test On Windows, Test On Mac, Test On Linux,然后設(shè)置一下運(yùn)行這些step的時(shí)候需要什么類型的agent,QuickBuild就可以把這些任務(wù)分布到這些平臺(tái)的agents上去運(yùn)行了。而其它家的可能是因?yàn)槭召M(fèi)的方式,象TeamCity,一個(gè)build只能在一個(gè)agent上運(yùn)行,我如果要做到同樣的效果,就需要定義出三個(gè)項(xiàng)目,然后讓這三個(gè)項(xiàng)目在不同的agents上運(yùn)行,最后,還要再定義一個(gè)項(xiàng)目,讓這個(gè)項(xiàng)目去收集它們的artifacts,非常麻煩。Bamboo和AntHill也類似于TeamCity。而Hudson在這塊的能力很弱,個(gè)人感覺(jué)不如其它的產(chǎn)品強(qiáng)大,而且使用起來(lái)也更復(fù)雜一些。
Report功能和統(tǒng)計(jì)
上述各家CI SERVER都提供了Report的功能和統(tǒng)計(jì)的功能,在這個(gè)領(lǐng)域里,Hudson毫無(wú)懸念的是支持報(bào)告類型最多,最全的(誰(shuí)叫咱OpenSource呢,有的是人開(kāi)發(fā))。Bamboo屬于支持報(bào)告類型最少的,不過(guò)也有很多第三方的plugin供選擇。我們所關(guān)心的幾個(gè)reports都有被各家支持,其中QuickBuild的report給我的感覺(jué)最華麗,不過(guò)好像是參考google analytics來(lái)的,從界面上看和analytics簡(jiǎn)直就是一個(gè)翻版。在使用上,QuickBuild和TeamCity的最方便,直接點(diǎn)報(bào)告中的鏈接就可以作一些過(guò)濾。在統(tǒng)計(jì)信息方面,各家對(duì)tests的統(tǒng)計(jì)都非常完備,這也從一個(gè)側(cè)面反應(yīng)出test driven現(xiàn)在那是深入人心啊。在支持Test Driven方面,TeamCity是力拔頭籌,得益于開(kāi)發(fā)IntelliJ的經(jīng)驗(yàn),TeamCity不僅可以自動(dòng)尋找出項(xiàng)目中的unit tests(你不用在Ant腳本里調(diào)用junit task,或者在Maven里調(diào)用surefire),而且對(duì)于上次運(yùn)行失敗的test cases,它可以在下次build中自動(dòng)先運(yùn)行,這樣就可以避免一個(gè)build運(yùn)行了很久才發(fā)現(xiàn)上次失敗的test還沒(méi)有被更正過(guò)來(lái)呢,強(qiáng)!
另外,要提一下的是QuickBuild中那個(gè)Build的Dashboard我非常喜歡,對(duì)于一個(gè)項(xiàng)目當(dāng)前的狀況可以一目了然,有多少個(gè)tests成功了,多少失敗了,多少被fix了,多少還沒(méi)有fix,總之,信息很豐富,不過(guò)就是配置起來(lái)有點(diǎn)復(fù)雜,需要我去一個(gè)報(bào)告一個(gè)報(bào)告去加step,如果能做到TeamCity的程度,簡(jiǎn)直就是完美了。
對(duì)于其它的CI Server則是亮點(diǎn)不多(其實(shí)也很強(qiáng),只不過(guò)是對(duì)比而言,我覺(jué)得TeamCity和QuickBuild更強(qiáng),更好)。
與第三方工具的集成
在與第三方工具的集成中,Hudson遙遙領(lǐng)先,是所有CI Server里Plugin最多的。可以和FaceBook,Google Calendar,Twitter,反正基本上你能想到的,它都有。不過(guò)對(duì)于我們而言,好多Plugin沒(méi)有太大的價(jià)值。Bamboo在與它自己的幾個(gè)產(chǎn)品中集成度也非常好,比如說(shuō)Jira,Wiki,Clover等。這幾個(gè)我們公司都有用到,在這點(diǎn)上非常理想。
價(jià)格
不得不考慮一下價(jià)格的因素,好像記得有人說(shuō)過(guò),Price is nothing, but price is everything,尤其在這個(gè)金融危機(jī)的年代里。這點(diǎn),勿庸置疑,OpenSource永遠(yuǎn)是最好的。而在商用的這幾個(gè)里QuickBuild最便宜,它使用的是Site License,一個(gè)Site收$2999,AntHill最貴,我詢問(wèn)了一下,按我的配置,隨便搞搞就要$10000了,TeamCity的入門(mén)也很便宜,$1999帶3個(gè)agents,可是針對(duì)我們的情況,算了一下也要上$8000了(它是按agent收費(fèi)的),Bamboo也很貴,按照它的功能而言,我覺(jué)得性價(jià)比不是很好。
總結(jié)
綜合各方面因素的考慮,我們最終選擇了QuickBuild,雖然這個(gè)產(chǎn)品名聲不是很大,不過(guò)想想它的客戶中,不乏象Cisco,HP這樣級(jí)別的公司,應(yīng)該還是可以值得信賴的吧。另外就是我們使用下來(lái)覺(jué)得它還是擁有諸多亮點(diǎn),對(duì)于我們的統(tǒng)一管理來(lái)說(shuō),可謂是方便至極。另外價(jià)格方面考慮也很不錯(cuò)。當(dāng)然如果你的團(tuán)隊(duì)不是很大,那么選擇QuickBuild的Community Edition和TeamCity的Professional Edition都是非常值得的,這兩者都是免費(fèi)的,而且QuickBuild的Community Edition功能沒(méi)有任何裁剪,只是限制了一下configuration的數(shù)目,非常適合要求比較高而項(xiàng)目不是很多的團(tuán)隊(duì)。
好了,有太多太多需要討論的東西了,CI這個(gè)領(lǐng)域現(xiàn)在還處于高速發(fā)展階段,本文純屬探討,歡迎大家拍磚。由于時(shí)間有限,對(duì)每個(gè)產(chǎn)品了解的不是很深入,錯(cuò)誤在所難免,如果我有什么地方不是很準(zhǔn)確,也歡迎告訴我。