在敏捷開發過程中,軟件構建周期以及自動化程度直接影響開發的速度和質量。本文結合具體的軟件開發項目,描述如何利用 IBM Rational Build Forge 在敏捷開發過程中實現完全自動化的軟件構建,產品安裝以及單元測試,進行每天持續快速構建,提高開發團隊的效率,改進產品和開發質量。
概述
敏捷開發(Agile development)是一種以人為核心、迭代、循序漸進的開發方法,開發周期一般是兩星期到四星期。敏捷開發的一大原則是盡早的、持續的交付有價值的軟件來使客戶滿意,交付的間隔時間越短越好。如何才能在很短的時間內實現產品的交付呢?每天持續構建能為實現短時間交付軟件提供很好的質量保證。
由於開發過程中每天都會有大量的代碼在修改,這些改動可能會給產品帶來潛在的問題。因此,為了盡早發現開發中存在的問題,代碼需要不斷地集成,並頻繁地進行構建(Build)、測試以及提交。如果構建不能夠完全自動化,頻繁的構建就需要花費大量的人力和時間。但是實現構建自動化的過程也是一項繁瑣,復雜的工作。IBM Rational Build Forge 提供了很好的持續構建框架,可以實現端到端流程的自動化。它不僅可以使用自有的腳本,還可以集成用戶現有的腳本和工具,因此可以有效利用現有的資源,同時它具有任務定制功能,可以周期性啟動所需的構建工程,提供一個可重復的、可靠的應用開發生命周期流程。
持續集成過程
2.1 典型的持續集成過程
持續集成過程中一般存在兩種構建:本地構建和集成構建。本地構建一般是開發人員完成代碼修改後,在自己的本機完成;集成構建一般是集成了所有開發人員的代碼,由專業的構建工程師完成。典型的持續集成過程如圖 1 所示,開發人員獲得開發代碼,開發人員進行開發工作後,各自進行本地構建。經過一定的開發時間,合並團隊開發成果,再次進行本地構建,如果該本地構建成功,開發人員就可以提交代碼到集成分支,構建工程師進行集成構建並進行發布。
圖 1. 典型的持續構建流程
項目 R 根據典型的持續構建過程,結合敏捷開發方式,對此典型的持續集成過程進行適當的修改。
2.2 項目 R 的持續集成過程
項目 R 的敏捷開發采用 Scrum 開發方式,一個版本的開發分為若干個 Sprint,一個 Sprint 一般為期四周。在每個 Sprint 中,需要三至四個集成構建,期間每天需要三個本地構建。根據項目提出的構建需求,項目 R 的構建采用了本地構建與集成構建相結合的持續構建方式,使用 Build Forge 的任務定制功能實現每天三個本地構建。
為了適應敏捷開發以及持續構建的需求,我們對項目的開發模式、代碼配置管理和構建流程進行相應的修改。項目R使用的代碼配置管理工具是 ClearCase(以下簡稱 CC)。在進行敏捷開發之前,每個開發人員都有單獨的開發流(Stream),每次做集成構建之前,各開發人員需要把代碼提交到集成流裡,然後創建基線(Baseline),構建工程師從最新的基線裡面檢出代碼,進行集成構建。如果開發人員之間的程序具有相互依賴關系,但又沒有及時溝通,往往會導致集成構建的失敗。采用敏捷開發以後,為了開發人員更方便獲取其它開發人員的代碼,建立了一個統一的開發流,所有的開發人員都基於該流進行開發,每天在該流上進行 3 個本地構建以盡快發現各種問題。通過本地構建,確認代碼正確以後,才提交代碼到集成流,創建基線,進行集成構建。采用敏捷開發方式以後的 CC 策略如圖 2 所示。
圖 2. ClearCase 簡化的開發分支策略示意圖
CC 的開發策略修改以後,項目R采用的持續構建過程如圖 3 所示。開發人員在開發流上進行開發活動,本地構建根據定制任務的時間周期性地啟動。如果本地構建成功,並且需要進行集成構建時,開發人員提交代碼並創建基線進行集成構建。
圖 3. 項目 R 持續集成過程
2.3 項目 R 的構建過程
項目 R 的構建主要由以下幾個部分組成:構建環境恢復,檢出代碼,自動構建,測試環境恢復,自動部署和測試以及構建狀態通知,由於項目同時支持三個數據庫,需要在三個數據庫中進行測試。項目 R 的一個構建過程如圖 4 所示。
圖 4. 項目 R 構建步驟
這幾個部分的完全自動化是實現持續構建的基礎,3.2 節主要針對構建的幾個部分,描述如何在 Build Forge 上實現持續構建。
基於 Build Forge 實現持續構建
結合敏捷開發對構建的需求以及 Build Forge 的特性,項目 R 在 Build Forge 中的持續集成采用定時觸發機制,其流程如圖 5 所示。
圖 5. 項目 R 在 Build Forge 上的持續構建過程
項目 R 的構建在 Build Forge 上定時觸發本地構建,如果構建成功,測試團隊就可以開始測試,如果失敗,構建和開發團隊及時修復問題,啟動下一個的構建或者等待下一次的觸發。在持續集成過程中,構建過程的完全自動化是必不可少的。此外,構建狀態及時更新和構建錯誤的快速修復影響著持續構建的效率。Build Forge 為構建狀態通知提供了很好的模板。
下面主要介紹項目 R 的集成構建在 Build Forge 上實現過程,首先介紹項目 R 的構建在Build Forge 中的配置,接著詳細介紹實現一個構建工程的運行步驟,然後介紹構建任務的制定,最後介紹構建通知。
3.1 Build Forge 的構建配置
在 Build Forge 中配置一個自動化的構建,一般需要以下幾個對象:服務器對象,環境變量對象和工程/庫對象。服務器對象是安裝了代理(Build Forge Agent)的邏輯機器,構建是在服務器對象上完成的;環境變量包括工程環境變量和服務器環境變量,工程運行的時候,會結合這兩種環境變量;工程/庫對象是由一系列的步驟組成,每一步的成功和失敗都可以給指定組成員發送郵件通知,因此合適粒度的步驟定義將有利於分析構建過程中出現的問題以及通知相關人員修復問題。項目 R 在 Build Forge 中的構建工程對象如圖 6 所示。工程 R_LocalBuild 引用的環境變量是工程環境變量 LocalBuildEnv,服務器是 Rdbx。
圖 6. 項目 R 的構建對象示意圖
3.2 項目 R 在 Build Forge 上的構建步驟
項目 R 的本地構建和集成構建除了獲取代碼的方式不同,其它的步驟都是一樣的。本地構建通過更新視圖(UpdateView)獲取最新代碼,集成構建通過 Rebase 獲得最新基線的代碼,本章以本地構建為例詳細介紹項目 R 在 Build Forge 中的構建步驟。
如 2.3 節所介紹,項目 R 的持續構建主要由以下幾個部分組成:構建環境恢復,檢出代碼,自動構建,自動測試環境恢復,自動部署和測試以及構建狀態通知。
一、構建環境恢復:主要是為構建做一些准備工作,確保構建的順利進行,一般包括環境檢查,磁盤空間的清理等。項目 R 在 Build Forge 上的准備步驟包括設置標簽,刪除舊的安裝文件以及重新啟動 CC 客戶端服務。
1.Prepare_BuildTag
.retag $BuildLevel
步驟一是准備構建的標簽以及給相應的組發送構建開始的郵件通知。由於每天的構建是自動啟動的,人為輸入是不現實的。但是 Build Forge 的默認標簽是阿拉伯數字,不便於標識。因此在每次構建之前都需要重新打一下標簽。使用的命名規則是“項目名稱+當前日期”,這個可以在 Build Forge 的 Environment 中進行定義。
2.Prepare_delete_Old_Driver
cd /d cd $BuildScriptHome perl deleteOldDrivers.pl
步驟二是刪除以前構建出來的安裝文件。由於系統空間有限,不可能保存所有的安裝文件,只能保存最新的一些文件。因此,在每此構建之前都要判斷所存的安裝文件數目是否已經超過預定義的數目,如果超過,即刪除較早的安裝文件。
3.Prepare_restart_ClearCaseServices
cd /d cd $BuildScriptHome CC_Services.bat
步驟三是重新啟動 ClearCase 客戶端服務。由於各種原因,CC 客戶端服務有的時候會停止。為了防止在構建過程中出現錯誤,因此重新啟動該服務確保 CC 客戶端服務處於運行狀態的。
二、檢出代碼:獲取最新的代碼,然後拷貝到構建的工作空間。
4.Prepare_updateView
cd $BuildScriptHome
perl UpdateCCView.pl $BuildLevel
.push ChangeFiles \IRM_Report\ChangeFile.log
步驟四是更新視圖,同時把本次構建修改的文件加入到變量 ChangeFiles,等構建完成後,同時發送給開發人員,以便開發人員確認自己修改的代碼是否已經加入到該構建中。同時,當構建失敗的時候,便於分析構建失敗的原因。
5.Prepare_SouceCode
cd $BuildScriptHome perl PrepSourceCode.pl
步驟五是准備代碼。需要把上一次構建的代碼刪除,把最新更新的代碼拷貝到構建工作區,同時創建構建所需要的目錄結構。
三、自動構建:這是構建的主要過程,主要包括修改版本號,編譯工作區代碼,分部件構建,然後打安裝包。項目 R 有 Engine,DataLoader,UI,Database,Install五個部件。
6.Prepare_ChangeVersion
cd $BuildScriptHome perl updateVersionNum.pl $BuildVersion
步驟六是修改版本號
7.Prepare_CompileWorkSpace
cd $BuildScriptHome perl prepCompile.pl
步驟七是刷新和預先編譯整個工作區。預編譯整個工作區有利於盡快發現編譯的錯誤,防止在各部件生成 jar 文件時候才出現編譯的問題。
8.Engine_Build:
cd $BuildScriptHome
perl IRMBuild.pl $BuildLevel -TASK "RAD" -RAD_COM "BLL"
9.DataLoader_Build
cd $BuildScriptHome
perl IRMBuild.pl $BuildLevel -TASK "RAD" -RAD_COM "BDL"
10.UI_Build
cd $BuildScriptHome
perl IRMBuild.pl $BuildVersion -TASK "RAD" -RAD_COM "UI"
11.Database_Build
cd $BuildScriptHome
perl IRMBuild.pl $BuildLevel -TASK "RAD" -RAD_COM "DB"
12.Install_Build
cd $BuildScriptHome
perl IRMBuild.pl $BuildLevel -TASK "RAD" -RAD_COM "INST"
步驟八至步驟十二都是各部件的構建,主要是生成各種 jar 包,ear 包等中間文件
13.Package_Windows:
cd $BuildScriptHome
perl IRMBuild.pl $BuildLevel -TASK "PG" -PG_OS "WIN32"
步驟十三是生成 Windows 的安裝包
四、測試環境恢復:主要是為部署和測試做准備,清空當前的環境,恢復到系統未安裝的初始狀態。
14.Prepare_Install_Env and BVT_Env
從本步驟開始,進入測試階段。步驟十四是測試前進行環境清空,還原到未安裝系統的初始化狀態。
五、自動部署和測試
Build Forge 同時還支持具有層次結構的工作鏈。該項目采用了工程和庫結合的方式測試項目 R 的三種不同的數據庫,如圖 7 所示。
圖 7. 項目 R 單元測試結構圖
15.Engine_Install
步驟十五是安裝引擎。
16.DB2_Install_JUnitTest
步驟十六是在 DB2 上安裝項目 R 數據庫,進行單元測試和存儲測試報告
17.ORA_Install_JUnitTest
步驟十六是在 ORACLE 上安裝項目 R 數據庫,進行單元測試和存儲測試報告
18.SQL_Install_JUnitTest
步驟十六是在 SQLServer 上安裝項目 R 數據庫,進行單元測試和存儲測試報告
19.Save_JUnitTest_Logs
步驟十九是在保存測試結果
3.3 Build Forge 構建定制
以上是本地構建工程定義的所有步驟,啟動該工程就可以運行本地構建。在敏捷開發中,為了能夠盡早發現存在的問題,需要頻繁地進行構建。手動啟動構建工程會造成大量的工作,或者導致人為原因延誤構建時機。Build Forge 為構建任務預訂提供了靈活的機制,可以設置每天/每周/每月等周期啟動構建,也還可以根據幾小時等時間間隔進行設置。本項目在開發周期之內每天運行三次本地構建,分別是 02:30,12:00 和 16:00 。圖 8 所示是在 Build Forge 中設置周一到周五每天運行三次的時間表。
圖 8. Build Forge 構建時間表
3.4 構建結果通知
運行構建的過程中難免會出現錯誤,及時有效的事件通知可以提高構建失敗處理的反應速度,提高構建效率。Build Forge 提供了強大的郵件通知功能,可以根據項目的需求制定郵件模板,可以把修改的文件列表,構建失敗的日志等有效信息加入到郵件中。不但是工程的成功和失敗可以發送郵件通知,工程中的每一個步驟都可以設定郵件發送通知組。通常不同的步驟是由不同的人負責的,這樣,相關人員就能在第一時間內獲得構建失敗的信息,失敗的構建能夠迅速得到修復。
在 Build Forge 中啟用郵件通知,首先需要設置 SMTP 服務器,設置的選項如下:Administration->System->SMTP Server。關於郵件通知模板,可以根據系統模板的格式,添加自己所需要的信息。在本項目中,郵件通知模板設置包括:構建狀態(成功,失敗,警告),安裝包下載鏈接,單元測試結果鏈接,更改文件列表,單元測試總結。對於構建失敗的模板,可以增加構建失敗日志,便於相關人員快速定位錯誤。
總結
本文結合項目 R 的敏捷開發需求,描述了該項目基於 Build Forge 的持續集成構建的全過程,包括軟件配置框架,詳細的構建步驟以及相應的信息反饋。Build Forge 的使用,極大地提高了構建的速度和質量,為敏捷開發提供很好的構建保證。