[ 2009-12-23 9:25:00 | By: 王海鵬 ]
 

引言

Thomas Carlyle說:“人類是使用工具的動(dòng)物。沒有工具,人什么都不是;有了工具,人無所不能。”金融家們創(chuàng)造了復(fù)雜的金融工具,并利用這些工具制造了財(cái)富神話,制造了著名的跨國(guó)公司,也制造了世界范圍的危機(jī)。軟件精英們?yōu)榱俗屪约旱墓ぷ餍矢撸懈鄷r(shí)間去做想做的事,也創(chuàng)造了各式各樣的工具。持續(xù)集成已經(jīng)不是一個(gè)新概念,在這個(gè)概念發(fā)展的十多年間,出現(xiàn)了支持這一概念的眾多工具。這些工具的組合使用,為軟件開發(fā)提供了強(qiáng)大的支持。

持續(xù)集成工具的分類和功能

一般來說,持續(xù)集成工具可以分成兩大類:自動(dòng)化構(gòu)建工具和構(gòu)建計(jì)劃安排工具。

自動(dòng)化構(gòu)建工具有這樣一些基本功能:代碼編譯、組件打包、程序執(zhí)行和文件操作。編譯源代碼是構(gòu)建的主要工作之一,為了提高效率,編譯應(yīng)該根據(jù)相應(yīng)的源代碼是否發(fā)生改變而有條件地執(zhí)行。組件打包是將編譯的結(jié)果和其他需要包含的文件組織在一起,形成可以部署的組件。構(gòu)建工具應(yīng)該知道何時(shí)需要重新打包。程序執(zhí)行是指構(gòu)建工具能夠在它支持的平臺(tái)上,調(diào)用所有提供命令行接口的程序。構(gòu)建工具應(yīng)該支持創(chuàng)建、拷貝、刪除文件和目錄等操作。

某些自動(dòng)化構(gòu)建工具還有一些擴(kuò)展功能:執(zhí)行開發(fā)者測(cè)試、版本控制工具集成、文檔集成、部署功能、代碼品質(zhì)分析、支持?jǐn)U展、多平臺(tái)構(gòu)建、加速構(gòu)建。雖然構(gòu)建工具可以通過命令行執(zhí)行的方式來集成構(gòu)建工具和測(cè)試工具,但如果它提供更直接的集成方式,開發(fā)者就更省力。同樣,如果構(gòu)建工具能夠直接與版本控制工具集成,開發(fā)者也會(huì)覺得更方便。文檔集成是指構(gòu)建工具能夠自動(dòng)從源代碼中抽取并生成API文檔。構(gòu)建工具還可以將打包好的組件自動(dòng)部署到目標(biāo)測(cè)試環(huán)境中去。構(gòu)建工具一般通過一些第三方插件,支持對(duì)代碼品質(zhì)進(jìn)行分析。而提供插件接口,是構(gòu)建工具實(shí)現(xiàn)可擴(kuò)展性的通用方式。如果您開發(fā)的軟件需要在多個(gè)平臺(tái)上構(gòu)建并測(cè)試,那么構(gòu)建工具對(duì)多平臺(tái)的支持就會(huì)帶來極大的方便。對(duì)于較大的代碼集,一次構(gòu)建可能需要好幾個(gè)小時(shí),這為持續(xù)集成帶來了一些挑戰(zhàn)。有的構(gòu)建工具支持加速構(gòu)建,即在多個(gè)構(gòu)建服務(wù)器的多個(gè)處理器上進(jìn)行分布式構(gòu)建。

常見的自動(dòng)化構(gòu)建工具包括Ant、NAnt、MSBuild、make、Maven、Rake等。

構(gòu)建計(jì)劃安排工具有這樣一些基本功能:構(gòu)建執(zhí)行、版本控制集成、構(gòu)建工具集成、提供反饋、為構(gòu)建打上標(biāo)簽。構(gòu)建計(jì)劃安排工具的核心功能就是在特定時(shí)間執(zhí)行自動(dòng)化的構(gòu)建,這可以通過輪詢版本控制庫(kù)、計(jì)劃驅(qū)動(dòng)或事件通知等方式來實(shí)現(xiàn)。大部分構(gòu)建計(jì)劃安排工具都支持大多數(shù)流行的版本控制系統(tǒng),也支持大多數(shù)流行的構(gòu)建工具。構(gòu)建計(jì)劃安排工具至少支持通過電子郵件提供反饋信息,有一些工具可以通過即時(shí)消息、手機(jī)短信或其他設(shè)備來提供反饋。大多數(shù)構(gòu)建計(jì)劃安排工具會(huì)提供某種類型的升序計(jì)數(shù),作為構(gòu)建版本的標(biāo)簽。

某些構(gòu)建計(jì)劃安排工具還有一些擴(kuò)展功能:支持項(xiàng)目間依賴關(guān)系、提供用戶界面、制品發(fā)布、安全。如果項(xiàng)目間存在依賴關(guān)系,您可能希望在被依賴的項(xiàng)目重新構(gòu)建時(shí),重新構(gòu)建依賴于它的項(xiàng)目。設(shè)計(jì)良好的用戶界面會(huì)在工作時(shí)為您節(jié)約時(shí)間。制品發(fā)布是指除了得到可部署的組件之外,一些成熟的某些構(gòu)建計(jì)劃安排工具可以將文檔、測(cè)試結(jié)果、品質(zhì)分析結(jié)構(gòu)和其他測(cè)量指標(biāo)數(shù)據(jù)格式化,便于查看。有一些工具提供了身份認(rèn)證和授權(quán)等安全方面的功能,允許您指定誰能查看結(jié)果和修改配置。

常見的構(gòu)建計(jì)劃安排工具包括AnthillPro、Continuum、CruiseControl、CruiseControl.NET、Draco.NET、Luntbuild、Hudson等。

下面介紹兩個(gè)頗具代表性的工具:Ant和Hudson。

Ant

Ant是Java構(gòu)建工具的事實(shí)標(biāo)準(zhǔn),一般建議,不論項(xiàng)目團(tuán)隊(duì)成員使用哪種集成開發(fā)環(huán)境,項(xiàng)目都要有一個(gè)可以脫離IDE執(zhí)行的Ant腳本。Ant采用插件式的設(shè)計(jì)結(jié)構(gòu),通過不同的插件來實(shí)現(xiàn)各種任務(wù),其任務(wù)分類如表1所示。

Archive Tasks
 打包解包任務(wù),支持的格式包括:BZip2、Cab、Ear、GZip、Jar、Rpm、Tar、War、Zip。
 
Audit/Coverage Tasks
 JDepend任務(wù),調(diào)用JDepend實(shí)現(xiàn)代碼靜態(tài)分析,針對(duì)每個(gè)Java包生成設(shè)計(jì)品質(zhì)指標(biāo)數(shù)據(jù)。
 
Compile Tasks
 編譯任務(wù),實(shí)現(xiàn)對(duì)Java、JSP、NetRexx等源文件的編譯。
 
Deployment Tasks
 部署任務(wù),實(shí)現(xiàn)在JavaEE服務(wù)器上熱部署。
 
Documentation Tasks
 文檔生成任務(wù),生成javadoc文檔、Apache Stylebook文檔。
 
EJB Tasks
 EJB任務(wù),提供對(duì)1.x和2.x的EJB的支持,并支持不同供應(yīng)商的應(yīng)用服務(wù)器。
 
Execution Tasks
 執(zhí)行任務(wù),包括對(duì)子項(xiàng)目調(diào)用Ant、調(diào)用同一腳本中的另一個(gè)target、執(zhí)行系統(tǒng)提供的命令行程序、執(zhí)行Java程序、暫停和并行同步執(zhí)行等功能。
 
File Tasks
 文件任務(wù),實(shí)現(xiàn)對(duì)文件和目錄的操作。
 
Java2 Extensions Tasks
 Java2 擴(kuò)展信息任務(wù),對(duì)jar包中的版本、供應(yīng)商等擴(kuò)展信息進(jìn)行檢查和操作。
 
Logging Tasks
 日志任務(wù),將構(gòu)建過程事件記錄到文件中。
 
Mail Tasks
 郵件任務(wù),發(fā)送SMTP郵件。
 
Miscellaneous Tasks
 其他任務(wù),各種或許會(huì)用到的小任務(wù),例如播放wav文件。
 
.NET Tasks
 .NET任務(wù),支持執(zhí)行.NET程序、執(zhí)行NUnit測(cè)試、調(diào)用NAnt、調(diào)用MSBuild、調(diào)用WiX工具。
 
Pre-process Tasks
 預(yù)處理任務(wù),實(shí)現(xiàn)編譯之前的一些預(yù)處理。例如調(diào)用ANTLR、JavaCC、Native2Ascii等程序。
 
Property Tasks
 屬性任務(wù),對(duì)腳本中的屬性變量進(jìn)行判斷和操作。
 
Remote Tasks
 遠(yuǎn)程任務(wù),支持FTP、Rexec、Scp、SSH和Telnet。
 
SCM Tasks
 SCM任務(wù),支持各種配置管理(版本控制)軟件,包括CVS、ClearCase、Continuus、Visual SourceSafe、Perforce、PVCS、SourceOffSite和StarTeam。
 
Testing Tasks
 測(cè)試任務(wù),支持執(zhí)行JUnit測(cè)試。
 
表1. Ant任務(wù)分類

以上介紹的只是Ant發(fā)行版所帶的一些任務(wù)。由于Ant采用的是插件結(jié)構(gòu),所以開發(fā)者可以開發(fā)自己需要的Ant任務(wù),支持各種工具,如FindBugs、TestNG等其他代碼檢查工具和測(cè)試工具。早期的Ant沒有很好的依賴關(guān)系支持,后來則通過Ivy彌補(bǔ)了這一缺點(diǎn)。

關(guān)鍵是Ant為我們提供了一個(gè)跨平臺(tái)的Java構(gòu)建工具,為持續(xù)集成提供了根本的支持。對(duì)于Java開發(fā)者來說,如果不想采用Ant,也可以考慮采用Maven。

Hudson

Hudson是一個(gè)開放源代碼的CI服務(wù)器,受到世界各地各種規(guī)模和類型的開發(fā)團(tuán)隊(duì)的歡迎。關(guān)鍵是因?yàn)樗浅R子诎惭b和使用,提供了靈活的配置方式和復(fù)雜的功能,同時(shí)支持Java項(xiàng)目和非Java項(xiàng)目,由強(qiáng)大的Hudson社區(qū)提供技術(shù)支持。

簡(jiǎn)而言之,Hudson不僅僅是一個(gè)CI服務(wù)器,它的可擴(kuò)展架構(gòu)使它不僅是一個(gè)構(gòu)建管理系統(tǒng),也成為一個(gè)通用的開發(fā)生命周期管理系統(tǒng),讓開發(fā)者能夠完成提升基線、打標(biāo)簽、執(zhí)行工作流、根據(jù)依賴關(guān)系追蹤變更、監(jiān)視并圖示測(cè)試結(jié)果、查看代碼覆蓋率和違反編碼標(biāo)準(zhǔn)的情況等任務(wù)。

Hudson是最活躍,成長(zhǎng)最快的開源社區(qū)之一,目前每周下載達(dá)4000次,有超過2萬個(gè)在工作的安裝實(shí)例。它的開發(fā)者超過160人,貢獻(xiàn)的工作量超過137人年,目前已發(fā)布了超過300個(gè)發(fā)行版本。Hudson實(shí)際上是現(xiàn)在世界上最受歡迎的開源CI服務(wù)器。

圖1是Apache軟件基金會(huì)運(yùn)行Hudson的屏幕截圖,您可以在http://wiki.hudson-ci.org/display/HUDSON/Meet+Hudson 看到更多Hudson的使用案例。

圖1. Apache運(yùn)行的Hudson

Huddon的主要優(yōu)點(diǎn)包括:

易于安裝。只要執(zhí)行“java –jar hudson.war”,或者將hudson.war部署到應(yīng)用服務(wù)器上就可以了,不需要其他的安裝工作,也不需要建立數(shù)據(jù)庫(kù)。
易于配置。所有東西都通過Web GUI界面來配置,不需要手工修改XML文件。
支持分布式構(gòu)建。Hudson支持將構(gòu)建和測(cè)試負(fù)載分布到多臺(tái)機(jī)器上,圖2是Apache采用Hudson的分布式構(gòu)建功能。
支持環(huán)境配置矩陣。Hudson支持在不同的環(huán)境配置下執(zhí)行相同的任務(wù),例如不同的JDK版本、不同的操作系統(tǒng)、不同的數(shù)據(jù)庫(kù)。執(zhí)行的結(jié)果可以匯總在一起。
支持JUnit/TestNG測(cè)試報(bào)告。測(cè)試的結(jié)果可以分標(biāo)簽列出、匯總,并與歷史信息一同顯示。歷史趨勢(shì)可以顯示在圖中。
追蹤依賴關(guān)系。Hudson追蹤記錄哪次構(gòu)建生成了哪些jar,某次構(gòu)建使用了哪些版本的jar,即使這些jar包來自于外部也可以。

圖2. Hudson支持的分布式構(gòu)建

Hudson通過大量的插件來實(shí)現(xiàn)其豐富的功能,這些插件大致可以分為以下幾類:

SCM。Hudson缺省支持CVS和Subversion,通過安裝插件支持Accurev、Bitkeeper、ClearCase、Git、Mercurial、Perforce、StarTeam、Synergy等
構(gòu)建觸發(fā)器。可以通過IRC、Ivy、Jabber、Join、Locks and Latches、Navigator來觸發(fā)執(zhí)行構(gòu)建。
構(gòu)建工具。缺省支持Ant、Maven、shell s和Windows 批處理命令,通過安裝插件支持batch tasks、Gant、Gradle、Grails、Groovy、Jython、Kundo、MSBuild、Phing、Powershell、Python、Rake、Ruby、SCons、SCTMExecutor,Selenium等。
構(gòu)建包裝。對(duì)構(gòu)建的方式進(jìn)行一些控制,如并發(fā)同步、啟停虛擬機(jī)等。包括Hudson Centralized Job Action、Hudson Distributed Workspace Clean、Locks and Latches、M2 Extra Steps、M2 Release、Release、VMware、Xvnc、Zen Timestamp等。
構(gòu)建通知。缺省支持電子郵件通知,通過插件支持Campfire、Google Calendar、HudsonTracker (RSS feeds)、IRC、Jabber、Nabaztag、SameTime、Status Monitor、The new Emailer、TuxDroid、Twitter等。
Slave啟動(dòng)和控制。缺省支持JNLP和命令行,通過插件支持SSH。
構(gòu)建報(bào)告。缺省支持JUnit、javadoc和FindBugs,通過插件支持CCCC、Checkstyle、Clover、DRY、Emma、Gallio、Gnat、Grinder、Japaex、JavaNCS、JavaTest Report、MSTest、N Cover、NUint、Plot、PMD、PureCoverage、Ruby metrics、Selenium AES、Selenium hq、Serenitec、SLOCCount、Task Scanner、Testability Explorer、Violations、Warnings、WebTest Presenter等。圖3是Sonar生成的項(xiàng)目報(bào)告的樣例。
集群管理/分布式構(gòu)建。支持DistFork、Hadoop、PXE、Selenium、Swarm等。
制品上傳。支持FTP-Publisher、java.net uploader、SCP,SFEE、SVN等。
身份認(rèn)證和用戶管理。支持操作審計(jì)追蹤、LDAP、MySQL認(rèn)證等。

圖3. Sonar Dashboard

結(jié)束語

工欲善其事,必先利其器。人是工具的主宰。A fool with a tool is still a fool(傻子拿著工具還是傻子)。人們總是在學(xué)習(xí)工具、使用工具、創(chuàng)造更好的工具,以期提高工作的效率和品質(zhì)。人要有智慧,工具要先進(jìn)。