nant的典型应用——部署web站点

概述

对于正在开发的项目,一般需要搭建测试/演示环境,将开发中的最新程序部署到测试环境上(Edge版本,一般指最新成果,但未经过严格测试),便于公司领导、客户、项目经理及时了解开发进展。

最简单的部署也大致需要获取源代码、编译、部署、运行几个环节,这几个环节伴随着较多的“手工操作”,容易出错,并且部署次数越多,累计花费的时间也越多。

因此在java领域,出现了很多项目构建(build)工具,而.net平台上的构建工具数量较少,除了微软自己的MSBuild外,最有影响力的是nant,NHibernate、log4net等多个开源项目都使用它来构建。

网络上介绍nant、svn的文档相当多,各位可以自行学习,本文的目的是介绍通过组合使用这些工具,用以完成“获取源代码”、“编译”、“部署”、“运行”几个环节的操作,将部署过程标准化,减少部署出错概率、节省时间。

个人认为mono是.net的未来,但我对linux还不熟悉,所以只讨论windows平台下nant的应用。

打造自己的工具包

想要达到“一键部署”的效果,需要制作工具包,将多个工具配合使用才可以,工具包的好处是我们可以根据项目情况对工具包进行剪裁和完善,删除不必要的文档和文件,以控制工具包尺寸,另外工具包要尽可能与环境无关,不应该要求运行环境安装svn、nant等等,我们应该包含这些基础组件,达到开箱即用的效果。因此需要大家自己动手了。我们的工具包中有三个工具,分别是svn客户端、nant和nantcontrib,另外还需要.net framework 2.0或以上版本。

1.建立工具包文件夹
首先在c盘根目录建立文件夹OneClickDeploy作为工具包的根文件夹,这个路径可以根据情况自行修改,构建脚本中指定即可。

2.svn客户端
svn客户端用于从svn服务器获取源代码,svn客户端的windows下二进制分发包有很多,建议使用SlikSvn,下载安装后,我们需要将C:\Program Files\SlikSvn\bin下的所有文件复制到c:\OneClickDeploy\SlikSvn下,只需要复制bin文件夹即可,其他文件夹中是版权声明、帮助文件等内容,我们不使用他们。

3.nant程序
nant就是我们构建工具的核心了,它负责执行构建脚本,并提供了很多任务、函数,比如获取当前时间,操作文件等,详细文档参见http://nant.sourceforge.net/release/latest/help/
http://nant.sourceforge.net/nightly/latest/nant-bin.zip下载最新程序,目前发布的0.86 Beta 1版本存在bug,因此还是建议下载nightly程序。下载后,将压缩包中的bin文件夹下的所有文件复制到c:\OneClickDeploy\nant-0.86。

4.nantcontrib程序
nantcontrib是对nant任务的扩展,比如支持多种源代码版本库,对iis操作等,文档参见http://nantcontrib.sourceforge.net/release/latest/help/
http://nantcontrib.sourceforge.net/nightly/latest/nantcontrib-bin.zip下载最新程序,下载后,将压缩包中的bin文件夹下的所有文件复制到c:\OneClickDeploy\nantcontrib-0.86。

至此,我们的工具包准备完成,大家可以自行丰富工具包,比如添加7z,提供文件压缩打包功能,文件夹结构如下:

c:\OneClickDeploy
                 \nant-0.86
                           \NAnt.exe
                           \...
                 \nantcontrib-0.86
                                  \NAnt.Contrib.Tasks.dll
                                  \...
                 \SlikSvn
                         \svn.exe
                         \...

一般web站点的部署脚本
Xml代码 复制代码 收藏代码
  1. <?xml version="1.0" encoding="utf-8" ?>  
  2. <!-- 项目名称,只用于显示 -->  
  3. <project name="project_name" >  
  4.     <!-- 使用NAnt.Contrib,指定Contrib的路径 -->  
  5.     <loadtasks assembly="C:/OneClickDeploy/nantcontrib-0.86/NAnt.Contrib.Tasks.dll" />  
  6.   
  7.     <!-- 源代码环境配置 -->  
  8.     <!-- 源代码输出路径,默认为输出到当前文件夹下的src文件夹 -->  
  9.     <property name="source.outdir" value="src"/>  
  10.     <!-- svn服务器地址 -->  
  11.     <property name="source.svn.path" value="svn://server/trunk/web0"/>  
  12.     <!-- svn用户名 -->  
  13.     <property name="source.svn.username" value="user"/>  
  14.     <!-- svn密码 -->  
  15.     <property name="source.svn.password" value="pass"/>  
  16.   
  17.     <!--   
  18.     ***************************************************************************   
  19.     更新代码:如果代码已签出,执行update命令,否则执行checkout命令,一般不需要修改   
  20.     ***************************************************************************   
  21.     -->  
  22.     <target name="source">  
  23.         <if test="${directory::exists(source.outdir)}">  
  24.             <echo message="更新代码${source.svn.path}"/>  
  25.             <svn-update uri="${source.svn.path}" destination="${source.outdir}" username="${source.svn.username}" password="${source.svn.password}" verbose="false" />  
  26.         </if>  
  27.         <if test="${not directory::exists(source.outdir)}">  
  28.             <echo message="签出代码${source.svn.path}"/>  
  29.             <mkdir dir="${source.outdir}"/>  
  30.             <svn-checkout uri="${source.svn.path}" destination="${source.outdir}" username="${source.svn.username}" password="${source.svn.password}" verbose="false" cache-auth="false" />  
  31.         </if>  
  32.     </target>  
  33.   
  34.     <!--   
  35.         编译代码“函数”   
  36.         compile.target:exe, winexe, library or module   
  37.         compile.assembly: 程序集   
  38.         compile.outdir: 输出路径   
  39.         complie.debug: true/false   
  40.      -->  
  41.     <target name="compile">  
  42.         <!-- 生成编译后的文件名 -->  
  43.         <if test="${compile.target=='library'}">  
  44.             <property name="compile.output" value="${compile.assembly}.dll"/>  
  45.         </if>  
  46.         <if test="${compile.target=='winexe'}">  
  47.             <property name="compile.output" value="${compile.assembly}.exe"/>  
  48.         </if>  
  49.         <csc target="${compile.target}" output="${path::combine(compile.outdir, compile.output)}" debug="${compile.debug}" optimize="true" verbose="false">  
  50.             <sources>  
  51.         <!-- 编译所有cs文件 -->  
  52.                 <include name="${source.outdir}/${compile.assembly}/**/*.cs" />  
  53.             </sources>  
  54.             <references>  
  55.         <!-- 编译引用的dll文件,我将依赖的dll放到了svn://server/trunk/web0/Assembly文件夹下,所以这里需要制定引用Assembly下的所有dll文件 -->  
  56.                 <include name="${source.outdir}/Assembly/**/*.dll" />  
  57.         <!-- 引用编译结果文件夹下的所有dll文件,一般来说类库项目之间也存在应用关系,基础类库编译完成后将编译结果dll存放compile.outdir文件夹下,编译业务类库时需要引用基础类库,因此需要引用compile.outdir下的所有dll -->  
  58.                 <include name="${compile.outdir}/**/*.dll" />  
  59.         <!-- 排除引用的dll文件 -->  
  60.                 <exclude name="${source.outdir}/Assembly/**/libmySQL.dll"/>  
  61.             </references>  
  62.             <resources>  
  63.         <!-- 嵌入的资源,需要将nhibernate映射文件作为嵌入的资源,编译到程序集中 -->  
  64.                 <include name="${source.outdir}/${compile.assembly}/**/*.hbm.xml" />  
  65.             </resources>  
  66.         </csc>  
  67.     </target>  
  68.   
  69.     <!--   
  70.     ***************************************************************************   
  71.     构建web站点   
  72.     ***************************************************************************   
  73.     compile.debug:   
  74.     /debug [+/-] :当选用/debug +就会把创建.pdb文件,并把调试信息存储到里面;/debug -是一个缺省设置,就是不产生任何调试信息。   
  75.     /debug:[full/pdbonly] :当使用/debug:full就是创建缺省的调试信息,有点类似/debug+选项。/debug: pdbonly选项是创建.pdb文件,并且你只能使用源代码调试在调试工具里。   
  76.     compile.outdir:   
  77.     编译结果输出文件夹   
  78.     -->  
  79.     <property name="compile.debug" value="PdbOnly"/>  
  80.     <!-- 将类库的编译结果存放到web/bin文件夹下 -->  
  81.     <property name="compile.outdir" value="${source.outdir}/web/Bin"/>  
  82.     <!-- web站点的物理路径 -->  
  83.     <property name="deploy.rundir" value="C:/web0"/>  
  84.        
  85.     <target name="compile-web" description="编译web站点">  
  86.         <echo message="编译web站点"/>  
  87.         <!-- 将Common和Business编译后放到源代码web/bin文件夹,需要根据web站点引用类库的依赖关系按顺序编译-->  
  88.         <delete dir="${compile.outdir}" verbose="true" if="${directory::exists(compile.outdir)}" />  
  89.         <mkdir dir="${compile.outdir}"/>  
  90.   
  91.         <property name="compile.assembly" value="Common"/>  
  92.         <property name="compile.target" value="library"/>  
  93.         <call target="compile" />  
  94.   
  95.         <property name="compile.assembly" value="Business"/>  
  96.         <property name="compile.target" value="library"/>  
  97.         <call target="compile" />  
  98.         <!-- 源代码Assembly下的所有dll复制到web/bin文件夹-->  
  99.         <copy todir="${compile.outdir}">  
  100.             <fileset basedir="${source.outdir}/Assembly">  
  101.                 <include name="/**/*.dll" />  
  102.             </fileset>  
  103.         </copy>  
  104.         <!--停止IIS-->  
  105.         <exec program="iisreset">  
  106.             <arg value="-stop" />  
  107.         </exec>  
  108.         <!--删除web站点物理文件夹-->  
  109.         <delete dir="${deploy.rundir}" verbose="true" if="${directory::exists(deploy.rundir)}" />  
  110.         <!--web预编译-->  
  111.         <exec program="aspnet_compiler">  
  112.             <arg value="-v" />  
  113.             <arg value="/s" />  
  114.             <arg value="-p" />  
  115.             <arg value="${source.outdir}/web" />  
  116.             <arg value="${deploy.rundir}" />  
  117.         </exec>  
  118.         <!--启动IIS-->  
  119.         <exec program="iisreset">  
  120.             <arg value="-start" />  
  121.         </exec>  
  122.     </target>  
  123. </project>  

上面的构建文件比较复杂,实际上分为几个环节:获取源代码source、编译web站点compile-web,编译web站点内又包括编译类库和预编译web站点,大家需要根据项目的实际情况,对构建文件进行修改。

使用
将上面的构建文件保存在任意文件夹下,如c:\deploy\web.build,并在这个文件夹下创建批处理脚本deploy.bat
Java代码  
  1. path=C:\OneClickDeploy\nant-0.86;C:\OneClickDeploy\SlikSvn;C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727  
  2. nant -t:net-3.5 -buildfile:web.build source compile-web   
  3. pause  

运行deploy.bat,首先会设置nant、svn、.net2.0 framework的路径,然后使用构建脚本进行部署:
1.更新源代码,首次运行会签出源代码
2.编译类库,示例中为Common、Business
4.停止iis并删除web站点物理路径
3.预编译web站点并输出到web站点物理路径
4.启动iis

本文介绍了使用svn客户端、nant工具,完成“获取源代码”、“编译”、“部署”、“运行”几个环节的操作,抛砖引玉,希望大家灵活运用,提出更好的想法。
posted @ 2011-04-14 21:14  J&amp;W  阅读(1685)  评论(0)    收藏  举报