[转]Nant daily build实践
本文轉自:http://www.cnblogs.com/moonvan/archive/2006/11/07/552585.html
折騰了一個周,基于Nant的VS.NET項目每日構建終于成功了,在網上實際上有很多這樣的例子,但所集成的解決方案都比較簡單,我現在做的解決方案,有4個類庫項目和2個web項目,使用網上的資料時,編譯過程都不能成功,最后翻了不少資料,問了不少人才成功,其中主要過程參考了ht tp://bitarray.co.uk/marc/這個博客,我的文章大部分內容就算是翻譯吧,寫出來希望對大家有用處,同時感謝給過幫助的朋友,包括coolbug的文章
?????? asp.net下開發產品的部署,不同于asp中interdev開發目錄和站點發布目錄相同的特點,在asp.net下,開發目錄實際上存在于VSS中,必須建立對應的發布目錄,將編譯過的文件放到其中,建立應用程序的虛擬目錄才能完成asp.net的發布,如果使用手動方式完成這一過程,則在項目多、 或者迭代式開發的多次小規模發布情況下,人工工作量大,且不易管理,本文的.net每日構建過程,可以自動的完成這一過程,簡化管理過程。
一、?????????? 系統需求
Win2000 以上操作系統?? .NET 框架1.0以上運行平臺
二、?????????? 相關工具及下載地址
1.???? Nant????? 開源工具,完成.net代碼自動編譯及其它工具的調用(必選)
http://nant.sourceforge.net/builds/
2.???? NantContrib 開源工具,Nant的擴展組件,實現Nant從VSS中獲取文件功能(必選)
http://nantcontrib.sourceforge.net/nightly/builds/
3.???? Visual Source Safe 源代碼管理工具,VSS6.0C以上版本(必選)
三. 相關軟件安裝
1.?? 安裝VSS
?????? 在指定服務器上安裝VSS6.0C以上版本
2.?? 安裝NANT和NantContrib
在網上下載最新版NANT和NantContrib壓縮包
解壓Nant,復制其中bin目錄到安裝地點,如d:\DailyBuildTools\Nant\bin
解壓NantContrib,復制其中bin中所有內容到Nant的bin目錄
注:如果Nant和NantContrib版本不兼容,需要重新編譯Nant,可下載源代碼后查看相關文檔
四. 建立.Net項目,并簽入到VSS中指定位置,分配相應帳號(除相關開發和管理人員外,可為Nant分配專用帳號)
五. 定義項目發布所包含的過程
Nant工具功能強大,配合nant、ndoc、fxcop等工具,可以完成代碼編譯,站點發布,文檔生成、代碼測試等功能,并可反向在VSS中加入基線。
一個比較通用的發布過程如下:
5.1 定義發布環境,如站點發布目錄,源代碼存放目錄、文檔存放目錄、發布版本分發包存放目錄等
5.2 項目組人員編寫Nant所需要的運行文件default.build,并根據環境定義其中的相關變量,并提交到服務器
5.3服務器的計劃任務等自動過程每天定時運行Nant
5.4 Nant清除上一版本發布時存放的文檔
5.5 Nant從VSS中獲取新的源代碼
5.6 Nant編譯從VSS中獲取的源代碼,并將生成的dll文件存放到指定目錄
5.8 生成測試報告
5.9 生成項目文檔(需要源代碼中加入充分的注釋)
5.10 如果包含web項目,Nant刪除不必要的如*.cs等文件后,將發布需要的*.aspx、*.resx、*.js等文件按原有目錄結構復制到指定目錄
5.11 向VSS中加入基線定義(需要寫權限)
5.12 生成項目zip分發包,并用指定格式定義分發包文件名,存到指定目錄
5.13 發布項目到指定目錄,如web站點將發布到指定虛擬目錄,也可由Nant來完成虛擬目錄的建立過程
六. 編寫Nant運行所需要的運行文件default.build
此文件要求在同一目錄下有且僅有一個存在,所以為統一管理,所有項目可以統一使用一個default.build文件
該文件中將包含所有相關項目的vss帳戶信息,需要保證其安全
將些文件放在獨立的目錄中以便于管理
七. Default.build的編寫說明
根據上面描述的通用項目發布過程,一個基于Nant的項目發布過程主要為以下幾步:
1 清除舊版本
2 獲取新版代碼
3 編譯
4 測試和文檔生成
5 發布
因為Nant在同一目錄下僅可有一個default.build的限制,可將每個項目的發布過程定義為4個xml文件,如對集團黃頁系統
TYS.Master.xml????? build主文件,定義各種環境變量
TYS.PreBuild.xml??? 項目預處理過程定義文件,完成舊的文件的清除工作
TYS.Build.xml?????????? 主要構建過程定義文件,完成VSS中獲取,編譯、生成壓縮包的過程,并測試、生成文檔的過程
TYS.Deploy.xml????? 項目發布到最終位置的過程定義文件
對于復雜的多層的項目,build文檔的編寫比較復雜,可以參考Nant和NantContrib的相關文檔,針對不同類型的項目,xxx.Build.xml文件的編寫可以使用不同方法,對于簡單項目,可以使用Nant的solution任務、對于復雜的項目,可以使用NantContrib的slingshot任務自動成生,不過可 能需要做稍微的改動,
在合理的定義變量的條件下,上面4個文件中的XXX.PreBuild.xml、XXX.Build.xml、XXX.Deploy.xml實際上都是可以重用的,也就是說,每次項目發布,項目組人員只需要提交XXX.Master.xml
八. Default.build的編寫過程
下面以集團黃頁系統TYS的default.build編寫為例講述具體過程,先假定項目發布服務器Nant配置完成,并存在以下結構的目錄設置
1)?????? 項目所在vss目錄:vss.directory = d:\VSS\TYS
2)?????? 項目構建工作和存放文件根目錄:core.basedir = d:\Daily_Build_Folder
3)?????? 項目虛擬目錄位置:core.publish? = d:\inetpub\wwwroot\tys
4)?????? 所有項目源代碼存放目錄:Core.build? = Core.basedir\source
5)?????? 項目zip分發包存放目錄core.distribution = core.basedir\distribution
6)?????? 項目日志存放目錄core.logs = core.basedir\logs
7)?????? 項目文檔存放目錄core.documentation = core.basedir\docs
1編寫XXX.Master.xml
<?xml version="1.0" encoding="gb2312"?> <project name="DNMCCIT.TYS" default="go"> ??? <!-- 可配置屬性列表 --> ??????? <!-- 主要屬性列表 --> ??????????? <property name="core.basedir" value="d:Daily_Build_Folder"/> ??????????? <property name="core.publish" value="D:inetpubwwwrootTYS"/> ??????????? <property name="core.build" value="Build"/> ??????????? <property name="core.distribution" value="Distribution"/> ??????????? <property name="core.logs" value="Logs"/> ??????????? <property name="core.documentation" value="Docs"/> ??????????? <property name="core.source" value="Source"/> ??????????? <property name="supportal.core" value="\SupportalServersupportal$files"/> ??????????? <property name="supportal.fxcop" value="${supportal.core}fxcop"/> ??????????? <property name="supportal.nunit" value="${supportal.core}nunit"/> ??????????? <property name="supportal.ndoc" value="${supportal.core}ndoc"/> ??????????? <!--項目相關信息--> ??????????? <property name="project.manager" value="p520214@gnpjvc.com.cn"/> ??????????? <property name="project.developer" value="p520214@gnpjvc.com.cn"/> ??????????? <property name="project.name" value="DNMCCIT.TYS"/> ??????????? <!--Build位置信息--> ??????????? <property name="build.configuration" value="Release"/> ??????????? <property name="build.number" value="1.0"/> ??????????? <property name="build.directory" value="${core.basedir}${core.build}${project.name}"/> ??????????? <property name="build.documentation" value="${build.directory}${core.documentation}"/> ??????????? <property name="build.logs" value="${build.directory}${core.logs}"/> ??????????? <property name="build.support" value="${core.publish}@support"/> ??????????? <property name="build.distribution" value="${core.basedir}${core.distribution}${project.name}"/> ??????????? <property name="build.publish" value="${core.publish}${project.name}"/> ??????????? <!--VSS信息--> ??????????? <property name="vss.username" value=""/> ??????????? <property name="vss.password" value=""/> ??????????? <property name="vss.dbpath" value="\t-net1vss8002TYSsrcsafe.ini"/> ??????????? <property name="vss.path" value="$/DNMCCIT.TYS/"/> ??????????? <property name="vss.directory"? value="${core.basedir}${core.source}${project.name}"/> ??????????? <!--VS.NET解決方案信息--> ??????????? <property name="solution.file" value="DNMCCIT.TYS.sln"/> ??????????? <!--程序集引用信息--> ??????????? <property name="solution.assembly.1" value="DNMCCIT.TYS.Data"/> ??????????? <property name="solution.assembly.2" value="DNMCCIT.TYS.Entity"/> ??????????? <property name="solution.assembly.3" value="DNMCCIT.TYS.Logic"/> ??????????? <property name="solution.assembly.4" value="DNMCCIT.TYS.Common"/> ??????????? <property name="solution.fxcop" value="${project.name}.fxcop"/> ??????? <!--屬性列表結束--> ??? <target name="go" depends="prebuild,build"/> ??? <target name="prebuild"> ??????? <nant buildfile="TYS.PreBuild.xml" target="go" inheritall="true"/> ??? </target> ??? <target name="build"> ??????? <nant buildfile="TYS.Build.xml" target="go" inheritall="true"/> ??? </target> ??? <target name="deploy"> ??????? <nant buildfile="TYS.Deploy.xml" target="go" inheritall="true"/> ??? </target> </project>
2編寫TYS.PreBuild.xml
<?xml version="1.0" encoding="GB2312"?>
<project name="TYS.PreBuild" default="go"> ??? <target name="go" depends="clean,getsourcecode"/> ??? <target name="clean" description="Remove all files"> ??????? <delete dir="${build.directory}" failοnerrοr="false"/> ??????? <delete dir="${vss.directory}" failοnerrοr="false"/> ??????? <delete dir="${build.distribution}" failοnerrοr="false"/> ??????? <mkdir dir="${build.directory}"? /> ??????? <mkdir dir="${build.documentation}"?? failοnerrοr="false" /> ??????? <mkdir dir="${build.logs}"?? failοnerrοr="false" /> ??????? <mkdir dir="${vss.directory}"/> ??????? <mkdir dir="${build.publish}" failοnerrοr="false" />??????? ??? </target> ??? <!--從VSS中取得源代碼--> ??? <target name="getsourcecode"> ??????? <vssget ??????????? user="${vss.username}" ??????????? password="${vss.password}" ??????????? localpath="${vss.directory}" ??????????? recursive="true" ??????????? replace="true" ??????????? dbpath="${vss.dbpath}" ??????????? path="${vss.path}" ??????????? /> ??? </target>??? </project>
這個文件實際上是通用的,對所有項目基本相同
3 編寫TYS.Build.xml文件,TYS.Build.xml文件根據項目復雜程度不同而不同,下面是一個只有一層,且為web層的例子
<?xml version="1.0" encoding="GB2312"?> <project name="TYS.Build" default="go"> ??? <target name="go" depends="compile,distribute"/> ??? <!--編譯解決方案--> ??? <target name="compile" > ??????? <!-- ??????? 如果項目比較簡單,如只有一層或層之間關系比較簡單,可以直接使用項目的解決方案文件 ??????? --> ??????? <solution ??????????? solutionfile="${vss.directory}${solution.file}" ??????????? configuration="${build.configuration}" ??????????? outputdir="${build.directory}"> ??????????? <webmap> ??????????????? <map ??????????????????? url="http://localhost/DNMCCIT.TYS.WEB/DNMCCIT.TYS.WEB.csproj? ??????????????????? path="${vss.directory}TYS.WEBDNMCCIT.TYS.WEB.csproj" ??????????????? /> ??????????? </webmap>??? ??????? </solution> ??? </target> ??? <!--生成分發包--> ??? <target name="distribute"> <IMG src="/Images/OutliningIndicators/None.gif" align=top<?xml version="1.0" encoding="GB2312"?> <project name="TYS.Deploy" default="go"> ??? <target name="go" depends="propertycheck,unzip,copyrequiredfiles"/> ??? <!--檢查必須的參數是否設置--> ??? <target name="propertycheck" > ??????? <ifnot propertyexists="build.number"> ??????????? <fail message="build.number 屬性沒有設置,不能進行部署" /> ??????? </ifnot> ??????? <ifnot propertyexists="target.directory"> ??????????? <fail message="target.directory 目錄沒有設置,不能進行文件復制" /> ??????? </ifnot>??????? ??? </target> ??? <target name="unzip"> ??????? <unzip ??????? zipfile="${build.publish}${project.name}--build-${build.number}.zip" ??????? todir="${target.directory}" /> ??? </target>
??? <target name="copyrequirefiles"> ??????? <mkdir dir="${target.directory}webctrl_client" failοnerrοr="false" /> ??????? <mkdir dir="${target.directory}aspnet_client" failοnerrοr="false" />??????? ??????? <!--復制web assets--> ??????? <copy? todir="${target.directory}webctrl_client"> ??????????? <fileset basedir="${core.publish}webctrl_client" > ??????????????? <includes name="**"/> ??????????? </fileset> ??????? </copy> ??????? <copy? todir="${target.directory}aspnet_client"> ??????????? <fileset basedir="${core.publish}aspnet_client" > ??????????????? <includes name="**"/> ??????????? </fileset> ??????? </copy>??????? ??? </target>??? </project>
本例中,并沒有給出生成文檔、日志等功能的build代碼,實際上這個過程應該寫在TYS.Build.xml中,具體運用中,項目成員可根據需要參照相關文檔添加
三. 自動運行過程
編寫全局使用的default.build,存放到buildconfig,在其中調用TYS.Master.xml,內容如下:
<?xml version="1.0" encoding="gb2312"?>
<project name="DNMCCIT" default="go">
?????? <target name="go" depends="DNMCCIT.TYS"/>
?????? <target name="DNMCCIT.TYS">
????????????? <nant buildfile="TYS.Master.xml" target="go" inheritall="true"/>
?????? </target>
</project>
編寫批處理程序,內容可以簡單的只有一行
Nant,然后存放到d:\buildconfig下的makefile.bat中
在計劃任務中增加自動運行計劃,按自定計劃運行makefile.bat
四. 其它解決方案
支持.net平臺、VSS做源代碼管理的每日構建,除了本文提到的Nant之外,還有微軟公司的BuildIt和MsBuild兩種工具,BuildIt工具因為擴展功能不強,使用較少,MSBuild的開發借鑒了Nant的思想,很多方面使用方法和Nant類似,并且也使用xml格式的build定義文件,并且可以根據VS.NE T的解決方案sln文件完全自動進行build,網上資料也較為豐富,但MSBuild現在階段為beta產品,僅在Visual Studio2005中提供,且需要.net framework2.0的支持,.net1.1下的產品只有有限有人員可以得到,待MSBuild正式發布后,將會成為另一有力工具
?
五. 用于管理方便的部分自動發布方式
上面講述的方法,有一個比較大的缺點,就是對于不熟悉nant的人來說,編寫build文件有一定難度,實際上如果僅從服務器管理方便的角度,完全可以使用一種比較簡便的方法,描述如下:
a)?????? 每個具體的開發項目,在其VSS中建立BUILD項目,如對黃頁系統為
$DNMCCIT.TYS.BUILD
b)?????? 由開發人員,不定期從開發環境,將編譯好的build文件,以zip壓縮包的方式存放到$DNMCCIT.TYS.BUILD中
c)?????? 修改服務器的nant編譯定義文件TYS.DeployZip.xml,過程僅為從VSS中取得DNMCCIT.TYS.BUILD.zip,并在服務器上解壓并釋放到指定的目的目錄
此時的default.build將只調用TYS.DeployZip.xml即可,代碼如下:
Default.build
<?xml version="1.0" encoding="gb2312"?>
<project name="DNMCCIT" default="go">
?????? <target name="go" depends="DNMCCIT.TYS"/>
?????? <target name="DNMCCIT.TYS">
????????????? <nant buildfile="TYS.DeployZip.xml" target="go" inheritall="true"/>
?????? </target>
</project>
TYS.DeployZip.xml
<?xml version="1.0" encoding="GB2312"?>
<project name="TYS.Deploy" default="go">
?????? <property name="core.basedir" value="d:\Daily_Build_Folder\"/>
?????? <property name="core.publish" value="D:\inetpub\wwwroot\TYS\"/>
?????? <property name="core.build" value="Build\"/>
?????? <!--項目相關信息-->
?????? <property name="project.manager" value=""/>
?????? <property name="project.developer" value=""/>
?????? <property name="project.name" value="DNMCCIT.TYS"/>
?????? <!--Build位置信息-->
?????? <property name="build.directory" value="${core.basedir}${core.build}${project.name}\"/>
?????? <!--VSS信息-->
?????? <property name="vss.username" value="aaaa"/>
?????? <property name="vss.password" value=""/>
?????? <property name="vss.dbpath" value="\\t-net1\vss\8002TYS\srcsafe.ini"/>
?????? <property name="vss.path" value="$/DNMCCIT.TYS.BUILD/"/>
?????? <property name="vss.directory" value="D:\inetpub\wwwroot\TYS\"/>
?????? <target name="go" depends="clean,getzip,unzip"/>
?????? <target name="clean" description="Remove all files">
????????????? <delete failοnerrοr="false">
???????????????????? <fileset>
??????????????????????????? <include name="${core.publish}**" />
??????????????????????????? <include name="${build.directory}" />
???????????????????? </fileset>
????????????? </delete>
?????? </target>
?????? <!--從VSS中取得源代碼-->
?????? <target name="getzip">
????????????? <vssget
???????????????????? user="${vss.username}"
???????????????????? password="${vss.password}"
???????????????????? localpath="${build.directory}"
???????????????????? recursive="true"
???????????????????? replace="true"
???????????????????? dbpath="${vss.dbpath}"
???????????????????? path="${vss.path}"
???????????????????? />
?????? </target>?????
?????? <target name="unzip">
????????????? <unzip
????????????? zipfile="${build.directory}${project.name}.BUILD.zip"
????????????? todir="${core.publish}" />
?????? </target>
?
?????? <target name="copyrequirefiles">
????????????? <mkdir dir="${target.directory}webctrl_client" failοnerrοr="false" />
????????????? <mkdir dir="${target.directory}aspnet_client" failοnerrοr="false" />?????????
????????????? <!--復制web assets-->
????????????? <copy? todir="${target.directory}webctrl_client">
???????????????????? <fileset basedir="${core.publish}\webctrl_client\" >
??????????????????????????? <includes name="**"/>
???????????????????? </fileset>
????????????? </copy>
????????????? <copy? todir="${target.directory}aspnet_client">
???????????????????? <fileset basedir="${core.publish}\aspnet_client\" >
??????????????????????????? <includes name="**"/>
???????????????????? </fileset>
????????????? </copy>???????
?????? </target>?????
</project>
注:不知怎么弄的,上次發的內容沒發完,xml內容怎么變成圖片了?現在補上
轉載于:https://www.cnblogs.com/freeliver54/archive/2013/01/22/2872074.html
總結
以上是生活随笔為你收集整理的[转]Nant daily build实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 从FLC中学习的设计模式系列-创建型模式
- 下一篇: SQL Server 2005中的分区表