1. 程式人生 > >.NET專案持續整合實踐

.NET專案持續整合實踐

現在這個專案裡,我們使用了jenkins (原hudson, http://www.jenkins-ci.org/)作為CI server,開源肯定是最基本的考慮,此外這個決定是受到了前任老大的影響,jenkins是java生態圈中的一個不錯的選擇,現在我們這個專案採用的是.net技術,能否很好的用起來呢,有點兒擔憂,一路見佛殺佛見魔殺魔,磕磕碰碰,到現在基本是搭建起來了。基本的組合是,jenkins + svn + msbuild + mstest +psexec,在這個搭建的過程中,也碰到了不少問題,有些問題解決了,有些問題繞過了,有些問題到現在都無法很好的解決。現在把這個過程簡要的寫下來,算是一點總結,也希望能夠對大家有點兒參考作用。

jenkins伺服器的選擇

最開始我們的jenkins伺服器是執行在linux上的,純粹是安裝java開發的需要來搭建的,眾所周知,.net需要使用nant / msbuild進行構建,最致命的是依賴於.net framework, 僅僅這一點我們就只能把jenkins搬到windows 2003/2008上,而出於謹慎的考慮,我們最後決定選擇msbuild。jenkins支援msbuild,有相關的外掛可以使用。版本控制的支援,自然是沒有問題,jenkins預設支援當前幾款主流的版本控制軟體,而單元測試這一塊,我們還是優先選擇了mstest,因為這也是.net 4.0 / vs 2010中內嵌的一個元件,而且在vs 2010中可以建立各種不同需要的test project,因此我們就沒有選擇nunit, 當然jenkins也支援mstest,當然在測試報告的支援上碰到了一些問題。當然jenkins能夠支援svn / msbuild / mstest, 那麼對一個.net專案的持續整合的需要也就基本能夠滿足了。

Jenkins安裝及一些初始工作

從jenkins的官網上(http://www.jenkins-ci.org/)下載一個Jenkins的最新版本,安裝到我們的windows 2008 R2上。jenkins會自動安裝為一個windows service: Jenkins。預設使用8080作為埠,開啟http://localhost:8080/就可以開啟我們的jenkins主介面了。進入Manage Jenkins -> Manage system, 選中Jenkins's own user database -> Allow users to sign up, 然後點右上角的sign up,先註冊一個pm的賬號先,然後根據需要是否允許組員也建立屬於他們自己的賬號,如果不允許,可以在Allow users to sign up取消選中即可。接下來登入進去,Manage Jenkins -> Manage Plugins, 選中我們需要使用的幾個元件:

Subversion plugin, Jenkins MSBuild plugin, Jenkins MSTest plugin, Version Number plug-In等。

這樣,Jenkins方面的準備工作就基本差不多了,此外順便提一下,Jenkins的外掛更新這一塊還有點兒問題,例如Subversion plugin的新版本更新有點兒問題,而且版本的回滾也稍稍有問題。

持續整合實踐思路

對於持續整合,我們也只是採取比較基礎的持續整合實踐,每天定時從svn上輪詢程式碼變更,如果有程式碼變更,那麼會通過msbuild進行編譯,然後進入下一步,編譯單元測試solution, 接著通過mstest執行單元測試,如果有測試用例不通過,同樣會發郵件給team,否則進入下一步:構建部署包,生成一個可安裝的軟體版本,包括服務端,資料庫,以及smart client。緊接著通過net use建立區域網磁碟對映,將所有釋出出來的軟體版本拷貝到區域網的test server上,然後通過PSExec在test server上遠端部署最新的軟體版本。當部署完畢後,開始編譯整合測試solution,然後通過msbuild對test server上釋出的服務進行整合測試(我們的整合測試,主要是對服務進行測試,而smart client這一塊交給test team,讓系統測試來覆蓋),並將測試報告發送給team。如果這一系列的環節都正常執行,那麼表明持續整合正常進行,否則任何一個環節出現問題,都將會發郵件給team。

此外,整合的頻率大概在一個小時一次,因此單元測試也是一個小時一次,但釋出和整合測試的頻率我們暫定在一天一次。

Jenkins專案規劃

基於我們的持續整合的思路,我們需要建立兩個Jenkins專案,一個用於程式碼構建和單元測試,另一個用於釋出,部署和整合測試。因此在每個Jenkins專案中將需要編譯哪些solution,也就一目瞭然了。這兩個專案的名稱,我們暫定位ABC Build和ABC Publish。

Jenkins專案配置

第一步選擇專案的風格,此處我們選擇Build a free-style software project。

Source control management,這個選擇Subversion, 設定我們專案的svn地址,然後會提示你提供svn的驗證。接下來開始Build Triggers, Build periodically: @hourly。

Version Number:在開發階段,我們採用的版本號格式是0.{# of phase}.{# of month in current phase}.{# of successfully build of current month}。這個可以根據你的實際需要來定,由於我們在部署方面選擇了smartclient / clickonce, 所以版本號管理我們需要提前都要確定下來(在Publish/Deploy client program的時候都需要指定版本號)。

接下來Add build step: Build a visual studio project or solution using MSBuild。MSBuild version: {Default}, MSBuild build file: solution file, Command line arguments: /t:Build /p:Configuration=Release。其中MSBuild build file需要注意,solution file的路徑是什麼呢,是基於workspace的相對路徑,這個一定要設定正確。

如何通過msbuild執行單元測試呢?這個要增加的build step是,Execute Windows batch command, 在裡面使用mstest命令:

mstest /testcontainer:***.Test.dll

這裡我沒有指定/resultfile,是因為我在配置resultfile的時候,出現了一些問題,mstest執行測試後生產的測試結果檔案格式為.trx,而在Jenkins中配置一個通用的測試結果檔案,發現mstest不能正常執行,所以現在我們專案的測試報告這一塊還是有問題的,如果你們有好的實踐經驗,歡迎分享出來。另外由於Jenkins預設支援的人JUnit的測試報告,而Jenkins MSTest Report主要是將.trx轉換為JUnit的測試報告,這樣可以統一在Jenkins中進行顯示。這一塊我也沒有嘗試成功。

接下來,build deployment packages, 同樣使用msbuild來完成,只是它是通過呼叫windows batch command來完成:

call Deployment/ABC.Server/BuildABCService.bat

call Deployment/ABC.Database/BuildABCDatabase.bat

call Deployment/ABC.Client/BuildABCClient.bat %ABC_VERSION%

部署包編譯完畢,那麼需要將其拷貝到區域網內的test server上,這也是通過呼叫windows batch command來完成,大致如下:

@echo off
SET VER=%1
SET LCF=Shell_%VER:.=_%

net use \\1.2.3.4\DropLocation /user:test server name\account password
rem xcopy /s DropLocation \\1.2.3.4\DropLocation /y

xcopy /s "DropLocation\ABC Deployment\ABC.Database" "\\1.2.3.4\DropLocation\ABC Deployment\ABC.Database" /y

...

net use \\1.2.3.4\DropLocation /delete

接下來是遠端部署,通過PSExec實現,遠端部署目前還存在問題,具體的過程,請看另外一篇隨筆: PSExec issues with Jenkins

@echo off
echo Start to update ABC Database...
psexec \\1.2.3.4 -u account -p password -n 60 -s -h "C:\DropLocation\ABC Deployment\ABC.Database\DeployABCDatabase.bat" -accepteula

目前手動遠端執行已經可以,但是通過Jenkins執行PSExec碰到了問題,所以自動部署還沒有搞定。呵呵。所以現在沒有辦法,整合測試需要依賴於暫時性的手動部署,所以,目前整合測試也是建了又一個新的Jenkins專案來定時執行。

這些是我們目前專案的CI實踐,簡要的介紹一下,難以作為實際操作參考,但是可以作為一個思路上的參考,如果大家在配置過程中也遇到了問題,歡迎共同探討。