[转]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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/576115.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

滤镜混合应用

混合滤镜使用&#xff1a;创建一个滤镜对象&#xff1b; 创建一个数组&#xff0c;并将滤镜的对象添加到该数组当中&#xff1b; 利用影片剪辑的filters属性&#xff0c;将数组当中的效果赋予该影片剪辑即可12345678import flash.display.Bitmap; import flash.display.…

Redisson的看门狗机制

来自他人文章&#xff1a;Redisson的看门狗机制_JAVA_侠的博客-CSDN博客_redisson看门狗机制

2013年1月23号

这几天一直在打酱油&#xff0c;估计到年前都不会有什么大动作了。 这周6公司年会&#xff0c;话说真够抠门的&#xff0c;年会还要在星期6开。 每天到公司来&#xff0c;打开电脑&#xff0c;看书&#xff0c;看代码&#xff0c;看界面&#xff0c;看文档&#xff0c;一天很快…

Windows 8的企业部署之路漫漫兮

日前&#xff0c;TechRepublic.com网站就企业升级Windows 8的计划对1200名IT员工进行了调查。结果显示&#xff0c;约74%的企业目前还没计划在企业内部部署Windows 8。排在前三名的原因分别是&#xff1a;1)现有的OS够用了;2)担心与之前应用的兼容性; 3)需培训员工熟悉Win8的新…

MyBatis + MVC 获取 UI 参数的几种方法(二)

方法一&#xff1a;(Form 中必须放name与model的字段名称相同的控件) { xtype: hiddenfield, name: id, id: id, hidden: true }var mNewRecord new IniStore.model.Store();mNewRecord.set(id, this.activeRecord.data.id);mImportForm.loadRecord(mNewRecord);mImportForm.s…

ramdisk根文件系统+initramfs

这几天做了下ramdisk根文件启动实验&#xff0c;小结下。 测试环境:Ubuntu 12.04 首先我认为先制作根文件系统好&#xff0c;因为配置内核中有一项跟你制作的ramdisk大小有关。这里我是直接使用原先制作好的根文件系统。 1. 制作ramdisk根文件系统镜像 首先安装ext2文件系…

MySQL数据库开启root用户远程登录

MySQL数据库开启root用户远程登录 如果mysql不支持远程连接&#xff0c;会出现提示&#xff1a;错误代码是1130&#xff0c;ERROR 1130: Host 192.168.0.10 is not allowed to connect to this MySQL server &#xff0c;解决此问题有以下2个方法&#xff1a;1、改表法&#x…

CentOS操作系统(LAMP)安装教程

http://hi.baidu.com/marvinchen/item/d4f358d971b5b3e054347f44 转载于:https://www.cnblogs.com/Joynic/articles/2881344.html

localToGlobal 本地转换全局

// localToGlobal 本地转换全局var square:Sprite new Sprite(); square.graphics.beginFill(0xFFCC00); square.graphics.drawRect(0, 0, 100, 100); square.x 100; square.y 200;addChild(square);square.addEventListener(MouseEvent.CLICK, traceCoordinates)functio…

viewController详解

一、生命周期当一个视图控制器被创建&#xff0c;并在屏幕上显示的时候。 代码的执行顺序 1、 alloc 创建对象&#xff0c;分配空间 2、init (initWithNibName) 初始化对象&#xff0c;初始化数据 3、loadView 从n…

Editplus For Python[转]

EditPlus是我常用的文件编辑器之一&#xff0c;用它来下脚本程序甚是方便&#xff0c;下面来看看如果配置吧&#xff1a; 1.先到www.editplus.com上下载editplus.exe&#xff0c;一步一步安装就好了&#xff0c;只有30天的试用期。 2.来配置python环境&#xff0c;到www.editpl…

硬件工程师在笔试中容易遇到的题目

名企硬件工程师面试考题大全 一、模拟电路 1、基尔霍夫定理的内容是什么&#xff1f;&#xff08;仕兰微电子&#xff09; 2、平板电容公式(CεS/4πkd)。&#xff08;未知&#xff09; 3、最基本的如三极管曲线特性。&#xff08;未知&#xff09; 4、描述反馈电路的概念&…

PyPyODBC 0.9.2发布 - 纯Python实现的pyodbc替代库

PyPyODBC发布了0.9.2版本&#xff0c;新版本加入了对Python 2.4的兼容性&#xff0c;加强了模块的健壮性&#xff0c;并修正了对Windows平台上Access MDB文件的创建和压缩功能。该模块的API语法尽力达到和著名的pyodbc库百分之百兼容&#xff0c;如果要在原有使用pyodbc的脚本上…

春节前51Aspx源码发布详情

材料科学与工程学院网站源码 2013-2-8 [VS2008] 本源码是为大学的一个学院网站定做的&#xff0c;现已经在某大学&#xff08;不提名&#xff09;网站上正式应用&#xff0c;且应用良好。本系统基于微软VS.net 2008 C# 、SQL Server2008&#xff0c;技术领先&#xff0c;完全模…

Java Swing 树状组件JTree的使用方法【图】

树中特定的节点可以由 TreePath&#xff08;封装节点及其所有祖先的对象&#xff09;标识&#xff0c;或由其显示行&#xff08;其中显示区域中的每一行都显示一个节点&#xff09;标识。展开 节点是一个非叶节点&#xff08;由返回 false 的 TreeModel.isLeaf(node) 标识&…

实测java 与php运行速度比较

java如下 public class aa{ public static void main(String[] args){ System.out.println(System.currentTimeMillis()"----"); int a0; int i; for(i0;i<10000000;i){ a; } System.out.println(System.currentTimeMillis()); } } php如下 <? echo microtime…

C#多线程学习(一) 多线程的相关概念

什么是进程&#xff1f; 当一个程序开始运行时&#xff0c;它就是一个进程&#xff0c;进程包括运行中的程序和程序所使用到的内存和系统资源。 而一个进程又是由多个线程所组成的。 什么是线程&#xff1f; 线程是程序中的一个执行流&#xff0c;每个线程都有自己的专有寄存器…

java多线程编程基础

thread和runnable已经out了。取而代之的是callable<V>,它的结果存在future<V>中。后者有get对象可以阻塞并最终获得异步结果。FutureTask既是callable又是future。可以作为一个执行单元。 直接启动一个thread执行callable是不明智的&#xff0c;因为太多的短命的线…

Linux网络管理实 验 指 导

Linux网络管理 实 验 指 导 实验一 TCP/IP网络接口配置 一、实验目的 ● 掌握Linux下TCP/IP网络的设置方法。 ● 学会使用命令检测网络配置。 ● 学会启用和禁用系统服务。 二、项目背景 某企业新增了Linux服务器&#xff0c;在但还没有配置TCP/IP网络参数&#xff0…

开发iOS即时通讯工具参考的一些开源、框架和教程

转&#xff1a;http://www.ctolive.com/space.php?uid927&doblog&id2277 下面收集了开发即时通讯工具&#xff0c;如AIM、ICQ(Oscar 协议)以及Jabber(XMPP协议)的iOS客户端程序的一些开源&#xff0c;可以直接使用或者参考&#xff1a;Oscar协议开发库LibOrange&#…