转载自: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
下开发产品的部署,不同于
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
这个文件实际上是通用的,对所有项目基本相同
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"
/>
<
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,内容如下:
编写批处理程序,内容可以简单的只有一行
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
TYS.DeployZip.xml
user="${vss.username}"
password="${vss.password}"
localpath="${build.directory}"
recursive="true"
replace="true"
dbpath="${vss.dbpath}"
path="${vss.path}"
/>
zipfile="${build.directory}${project.name}.BUILD.zip"
todir="${core.publish}" />
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"
>
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
="[email protected]"
/>
<
property
name
="project.developer"
value
="[email protected]"
/>
<
property
name
="project.name"
value
="DNMCCIT.TYS"
/>
<
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}"
/>
<
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}"
/>
<
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
>
<
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