Nant daily build实践

转载自:http://blog.csdn.net/ljianl/archive/2007/04/27/1587067.aspx

 折腾了一个周,基于Nant的VS.NET项目每日构建终于成功了,在网上实际上有很多这样的例子,但所集成的解决方案都比较简单,我现在做的解决方案,有4个类库项目和2个web项目,使用网上的资料时,编译过程都不能成功,最后翻了不少资料,问了不少人才成功,其中主要过程参考了http://bitarray.co.uk/marc/这个博客,我的文章大部分内容就算是翻译吧,写出来希望对大家有用处,同时感谢给过帮助的朋友,包括coolbug的文章

       asp.net下开发产品的部署,不同于aspinterdev开发目录和站点发布目录相同的特点,在asp.net下,开发目录实际上存在于VSS中,必须建立对应的发布目录,将编译过的文件放到其中,建立应用程序的虚拟目录才能完成asp.net的发布,如果使用手动方式完成这一过程,则在项目多、或者迭代式开发的多次小规模发布情况下,人工工作量大,且不易管理,本文的.net每日构建过程,可以自动的完成这一过程,简化管理过程。
一、           系統需求
Win2000 以上操作系统   .NET 框架1.0以上运行平台
二、           相关工具及下载地址
1.      Nant      开源工具,完成 .net 代码自动编译及其它工具的调用(必选)
2.      NantContrib 开源工具, Nant 的扩展组件,实现 Nant VSS 中获取文件功能(必选)
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
这个文件实际上是通用的,对所有项目基本相同
3 编写 TYS.Build.xml 文件, TYS.Build.xml 文件根据项目复杂程度不同而不同,下面是一个只有一层,且为 web 层的例子
<? 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"  failonerror ="false"  />
        
< mkdir  dir ="${target.directory}aspnet_client"  failonerror ="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.NET的解决方案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 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" _fcksavedurl=""/Images/OutliningIndicators/None.gif"" align=top
<? 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}"  failonerror ="false" />
        
< delete  dir ="${vss.directory}"  failonerror ="false" />
        
< delete  dir ="${build.distribution}"  failonerror ="false" />
        
< mkdir  dir ="${build.directory}"    />
        
< mkdir  dir ="${build.documentation}"    failonerror ="false"  />
        
< mkdir  dir ="${build.logs}"    failonerror ="false"  />
        
< mkdir  dir ="${vss.directory}" />
        
< mkdir  dir ="${build.publish}"  failonerror ="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 >


Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1587067

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值