其实关于Daily Build介绍有很多了。
1)什么是Daily Build?
Daily Build按照字面上的意思就是“每日构建”,在成功的构建和发布看起来很容易在某一阶段。 在实际中,从开发环境,测试,SIT,以及UAT到PRD环境,在每一个不同的环境或多或少会遇到一些问题, 比如少拷一个配置文件,或者其他一些一直没有在意的方面,因此产生了这个必不可少的步骤。
2)为什么需要每日构建呢?它又能做什么呢?
其实说的简单点,早点发现问题,不要到最后.它能广泛地用于编译,备份,产生文档,测试以及部署Application。
3)那怎么去做呢?
一般流程是这样的:
A)Get最新的SouceCode
B)编译
C)部署
D)测试
当然也有比较两个DataBase表结果和DML有何不同,有生成文档。
接下来,就开始怎么去做吧,用一个例子来讲,
首先用到以下技术的版本:
Technology Version
Visual Studio .NET 2005 (and therefore .NET Framework version 2.0)
Subversion
NAnt 0.85 RC2
NAntContrib 0.85 RC2
CruiseControl.NET 0.8
Toad9.0
(备注其实微软也有自己MSBuild,
The Detail is by the following URL:http://msbuildtasks.tigris.org/)
CommonProperty
<property name="SVDatabasePath" value="https://xxxx/SouceCodes" />
<property name="SVUserName" value="xxxx" />
<property name="SVPassword" value="xxxx" />
<property name="DailyBuildDir" value=":\DailyBuild\" />
<property name="BuildFileDir" value="${DailyBuildDir}BuildFile\" />
<property name="SourceDir" value="${DailyBuildDir}Build\${project::get-name()}\" />
<property name="OutPutDir" value="${DailyBuildDir}Output\" />
<property name="AssemblyDir" value="${OutPutDir}Assembly\" />
<property name="MailLogger.mailhost" value="sss" />
<property name="MailLogger.from" value="ssss@ddd.com" />
<property name="MailLogger.failure.notify" value="true" />
<property name="MailLogger.success.notify" value="true" />
<property name="MailLogger.failure.to" value="vssss@ddd.com;" />
<property name="MailLogger.success.to" value="ssss@ddd.com;" />
<property name="MailLogger.failure.subject" value="Daily build failure for the project!Please check the error." />
<property name="MailLogger.success.subject" value="Daily build success for project." />
<property name="MailLogger.failure.attachments" value="MailLogger.failure.files" />
<property name="MailLogger.success.attachments" value="MailLogger.success.files" />
<!-- set of files to attach when build fails -->
<fileset id="MailLogger.failure.files">
<include name="dump.log" />
<include name="trace.txt" />
</fileset>
<!-- set of files to attach when build is successful -->
<fileset id="MailLogger.success.files">
<include name="trace.txt" />
</fileset>
<property name="FXCOPpath" value="D:\Program Files\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop" />
<!-- Code Analysis need set this environment variant-->
<if test="${not environment::variable-exists('FXCOPDIR')}">
<echo>FXCOPDIR environment does exists.Create.</echo>
<setenv>
<variable name="FXCOPDIR" value="${FXCOPpath}" />
</setenv>
</if>
<property name="WebServer" value="localhost" />
<property name="WebRootDir" value="${OutPutDir}WWWRoot\" />
<property name="RemotingApplicationName" value="xxxx" />
<property name="RemotingUrl" value="http://${WebServer}/${RemotingApplicationName}/{0}" />
<property name="webNamespace" value="http://schemas.microsoft.com/.NetConfiguration/v2.0" />
A) Get the lasest source code and the related subversion revision number;
GetSC
<target name="GetSouceCode" Description="Get Source code from subversion" verbose="false" >
<!--Get source code from subversion by the specied account.-->
<svn-checkout destination="${SourceDir}" uri="${SVDatabasePath}" recursive="true" verbose="false" username="${SVUserName}" password="${SVPassword}" revision="HEAD" cache-auth="true" failonerror="True"/>
<echo message="Retrieving Subversion revision number" />
<property name="svn.revision" value="not_available" />
<exec program="svn.exe" commandline="info ${SVDatabasePath} -r HEAD --xml" output="_revision.xml" failonerror="false" verbose="false" />
<xmlpeek file="_revision.xml" xpath="/info/entry/commit/@revision" property="svn.revision" failonerror="false" verbose="false" />
<echo message="Using Subversion revision number: ${svn.revision}" />
</target>
B) Build the appliation
BuildProject
<!-- Build in the specified configuration -->
<property name="Debug" value="false" />
<property name="Configuration" value="Release" />
<target name="Build" description="Compiles the source code in the specified solution to the specified configuration" verbose="false">
<msbuild project="${SolutionFile}" verbosity="Quiet" failonerror="true" verbose="false">
<property name="Configuration" value="${Configuration}" />
<property name="RunCodeAnalysis" value="false" />
<property name="OutputPath" value="${AssemblyDir}${SolutionName}.${Configuration}" />
<property name="debug" value="${Debug}" />
<property name="trace" value="${Debug}" />
</msbuild>
</target>
C) Deploy the many portal.
DeployWeb
<target name="DelopyWeb" description="Deploy the web site.">
<property name="WebName" value="xxxxx" />
<delete dir="${WebRootDir}WebUI" failonerror="false" />
<foreach item="Folder" in="${AssemblyDir}${SolutionName}.${Configuration}\_PublishedWebsites" property="foldername">
<echo message="${foldername}" />
<property name="webfolderPath" value="${foldername}" />
<copy todir="${WebRootDir}WebUI" overwrite="true">
<fileset basedir="${webfolderPath}">
<include name="**/*.*" />
<exclude name="**/*.pdb" />
<exclude name="**/*.xml" />
</fileset>
</copy>
</foreach>
<!--Update the related informaiton-->
<attrib file="${WebRootDir}WebUI\Web.Config" readonly="false" verbose="false" />
<xmlpoke file="${WebRootDir}WebUI\Web.Config" xpath="/xsi:configuration/xsi:commonSettings/xsi:remotingSetting/@baseRemoteAddress" value="${RemotingUrl}">
<namespaces>
<namespace prefix="xsi" uri="${webNamespace}" />
</namespaces>
</xmlpoke>
<attrib file="${WebRootDir}WebUI\Web.Config" readonly="true" verbose="false" />
<mkiisdir iisserver="${WebServer}" dirpath="${WebRootDir}WebUI" vdirname="${WebName}" appfriendlyname="${WebName}" />
</target>
D)Compare oracle10g database from dev and other db and send the mail to notify;
CompareDB
<property name="TOADExe" value="D:\Program Files\Quest Software\Toad for Oracle\TOAD.exe" />
<property name="SQLPlusExe" value="D:\oracle\product\10.2.0\db_1\BIN\sqlplus.exe" />
<property name="DatabaseScriptsDir" value="E:\DailyBuild\BuildFile\dbscripts\" />
<property name="CompareDevTestScript" value="${DatabaseScriptsDir}database_compare_dev_test.txt" />
<property name="DatabaseResultDir" value="E:\DailyBuild\DBResults\" />
<property name="COMPResult_LRMEDBU" value="${DatabaseResultDir}InteractiveResultsFile_LRMEDBU.txt" />
![](/Images/OutliningIndicators/None.gif)
<target name="compareDB" description="Compare development database with test database">
<exec program="${TOADExe}" commandline="CONNECT=${DBConnection} comp=${CompareDevTestScript}" />
<mail from="xxx@dd.com" tolist="tttx@dd.com;" cclist="xxx@dd.com" bcclist="" subject="Compare against Test database at ${datetime::now()}" mailhost="${MailServer}" message="Compare against Test database at ${datetime::now()}">
<attachments>
<include name="${COMPResult_LRMEDBU}" />
</attachments>
</mail>
</target>
![](/Images/OutliningIndicators/None.gif)
E)schedule to run the command or use CC to run.
RunJob
cd cd E:\Build\nant-0.85\bin
nant -buildfile:"E:\DailyBuild\BuildFile\xxxx.Build" -l:today.log -logger:NAnt.Core.MailLogger
或
在ccnet.config中(注意要在windows service设定ccservice.exe's log on right),
<cruisecontrol>
<project name="ccnetProject" webURL="Http://localhost/ccnet">
<workingDirectory>E:\DailyBuild\Build</workingDirectory><!--Souce Code path-->
<artifactDirectory>E:\DailyBuild\BuildFile</artifactDirectory><!--Build file path-->
<triggers> <!--ScheduleTrigger-->
<scheduleTrigger time="14:00" buildCondition="ForceBuild">
</scheduleTrigger>
</triggers>
<tasks>
<exec executable="E:\DailyBuild\BuildFile\run.bat"/> <--Just the previous command-->
</tasks>
</project>
</cruisecontrol>
4)常用到的工具:
Nant
NAntContrib
Cruisecontrol
Draco
Ndoc
NUnit
BTW:编辑Nant工具:Nantpad
5)很不错得书
《Apress - Expert .NET Delivery Using NAnt and CruiseControl.NET》