打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
cruisecontrol、ant、svn持续集成

cruisecontrol、ant、svn持续集成

自己两个多星期以来对持续集成的概念和应用有了一些了解。下面主要对自己配置持续集成的环境进行总结。(看上去简单,但是对我开始对持续集成都没什么了解的人来说确实费了不少周折)

一  本次持续集成环境的搭建所使用的工具有

 cruisecontrol、ant、svn、junit、Slik-Subversion-1.5.6-win32、svnant-1.1.0-RC2.zip

 cruisecontrol:是一种持续集成过程的框架,包括了邮件通知,ant 和各种源码控 制工具的插 件。并提供了web接口,用于查看当前和以前的创建的结果.

ant:构建工具。

svn:版本控制工具。

junit:单元测试工具。

slik-subversion:是为了调用svn的客户端命令安装的。

svnant:主要是用到它里面的lib中的jar包,它具体使用还不是很清楚

另外本次的辅助环境还有jdk,相信大家都再也熟悉不过了。

二 环境的搭建步骤:

  1. jdk的安装:根据jdk安装包的提示安装jdk。设置系统的环境变量:

a) JAVA_HOME指明JDK安装路径,就是刚才安装时所选择的路径D:"java"jdk1.5.0_08,此路径下包括libbinjre等文件夹(此变量最好设置,因为以后运行tomcat都需要依赖此变量);

b) Path使得系统可以在任何路径下识别java命令,设为%JAVA_HOME%"bin;%JAVA_HOME%"jre"bin

 c)CLASSPATH为java加载类(class or lib)路径,只有类在 classpath中,java命令才能识别,设为:.;JAVA_HOME"lib"dt.jar;JAVA_HOME%  "lib"tools.jar (要加.表示当前路径);%JAVA_HOME%就是引用前面指定的JAVA_HOME;不过本人还是比较相信绝对路径的。 

2 ant的安装:ant是集成构建工具,想必大家都不太陌生了。只需要到ant.apache.org的网站下载ant的适当版本解压缩后,配置系统的环境变量:ANT_HOME:d:"apache-ant-1.7.0,path:d:"apache-ant-1.7.0"bin 后,ant就可以在任意目录下运行了,如cmd下运行ant,显示:buildfile:build.xmldoes not exsit。。。。。

3 安装svn,因为cruisecontrol要用到svn(不知道这两个有什么先后顺序没,因为cc要用svn就先装cc喽)。svn的安装TortoiseSVN-1.5.3.13783-win32-svn-1.5.2.msi安装提示装就可以了。

4 安装tomcat ,设置系统环境变量CATALINA_HOME=c:"tomcat,CLASSPATH=C:"tomcat"common"lib(加载必要的包)。

5 cuisecontrol的安装,因为本文使用的操作系统为XP,就使用CruiseControl-2.8.2.exe安装就可以了(.exe文件还是很受大家喜欢的)。配置系统的环境变量:CC_HOME=d:"cruisecontrol

6安装slik-subversion,它会自动写入到path=D:"SlikSvn"bin"如果没有写入的话,要麻烦手动加入到系统的环境变量path中,本人曾经遇到过,cmd窗口已经打开但是配置文件执行过程中svn的命令总不能识别发现此处的路径没有加入到path中。

7下载svnant-1.1.0-RC2.zip,把lib包中的jar考到ant的jar中。

三 以上的准备工作已经基本搞定,下面就介绍一下配置文件。此次环境的搭建配置文件是很关键的,因为他们各自有自己的标签,所以还要想达到什么功能慢慢查找,(如果有时间系统学习一下就好了)。

1 ant的关键文件为build.xml(当然也可以起别的名称,自己还要改它的启动文件,就用这个名称吧)下面是一个实例:

<?xml version="1.0" encoding="UTF-8"standalone="no"?>

定义basedir当前的根目录,default默认执行的标签,name工程名
<project basedir="." default="all"name="framework">
 <property environment="env" />

定义tomcat的安装目录
 <property name="TOMCAT_DIR" location="D:/Tomcat5.5" />

定义debug的级别
 <property name="debuglevel" alue="source,lines,vars"/>

为了引用tomcat固有包方便所以增加次属性
 <property name="coolink.dist.path"location="D:/Tomcat 5.5/webapps/txsd/WEB-INF"/>

指定要编译的工程目录
 <property name="CLASS_DIR" location="D:/CruiseControl/projects/framework"/>
 <property name="target" value="1.5"/>
 <property name="source" value="1.5"/>

编译时候所使用的类路径,id为引用的名称
 <path id="Apache Tomcat v5.5 [Apache Tomcatv5.5].libraryclasspath">
  <pathelement location="${TOMCAT_DIR}/common/lib/commons-el.jar"/>
  ....
  <pathelement location="${TOMCAT_DIR}/common/lib/servlet-api.jar"/>
 </path>
 <path id="Web App Libraries.libraryclasspath">
  <pathelement location="${coolink.dist.path}/lib/activation.jar"/>
  .............
  <pathelement location="${coolink.dist.path}/lib/xmlParserAPIs.jar"/>
 </path>
  <path id="ant.svn.classpath">
  <fileset dir="D:/CruiseControl/apache-ant-1.7.0/lib">
   <include name="*.jar" />
  </fileset>
 </path>
 <taskdef name="svn" classname="org.tigris.subversion.svnant.SvnTask">
  <classpath refid="ant.svn.classpath"/>
 </taskdef>
 <path id="txsd.classpath">
  <path refid="Apache Tomcat v5.5[Apache Tomcat v5.5].libraryclasspath" />
  <path refid="Web App Libraries.libraryclasspath"/>
 </path>

clean操作,如果build之前不执行此操作,build检查到原有的class文件就不再编译。
 <target name="clean">
     <delete file="${CLASS_DIR}/longcon-framework.jar"/>
     <delete dir="target"quiet="true" />
  <delete dir="${CLASS_DIR}/source/classes"/>
 </target>

要build模块的名称build-framework看来可以随便起名字,但是有人说必须和模块名称一致,至今还不知道为什么
 <target name="build-framework">
  <echo message="${ant.project.name}:${ant.file}" />
  <mkdir dir="${CLASS_DIR}/source/classes"/>
  <copy includeemptydirs="false"todir="source/classes">
   <fileset dir="${CLASS_DIR}/source"excludes="**/*.launch, **/*.java" />
  </copy>
  <javac debug="true" debuglevel="${debuglevel}"destdir="${CLASS_DIR}/source/classes" source="${source}"target="${target}" encoding="UTF-8">
   <src path="${CLASS_DIR}/source"/>
   <exclude name="**/.svn/**"/>
   <classpath refid="txsd.classpath"/>
  </javac>
 </target>

单元测试的部分
 <target name="test">
  <mkdir dir="target/test-classes"/>
  <javac encoding="UTF-8" srcdir="${CLASS_DIR}/test"destdir="target/test-classes">
   <classpath>
    <pathelement location="${CLASS_DIR}/source/classes"/>
    <path refid="ApacheTomcat v5.5 [Apache Tomcat v5.5].libraryclasspath"/>
         <path refid="Web App Libraries.libraryclasspath"/>
   </classpath>
  </javac>

  <mkdir dir="target/test-results"/>
  <junit haltonfailure="no" printsummary="on">
   <classpath>
    <pathelement location="${CLASS_DIR}/source/classes"/>
    <pathelement location="${coolink.dist.path}/lib/junit.jar"/>
    <pathelement location="target/test-classes"/>
   </classpath>
   <formatter type="brief"usefile="false" />
   <formatter type="xml"/>
   <batchtest todir="target/test-results">
    <fileset dir="target/test-classes"includes="**/*.class" />
   </batchtest>
  </junit>
 </target>

打包放到指定目录
 <target name="jar">
  <jar destfile="${CLASS_DIR}/longcon-framework.jar"encoding="UTF-8" update="false"excludes="**/*Test*.class">
   <fileset dir="${CLASS_DIR}/source/classes"/>
  </jar>
  <copy includeemptydirs="false"todir="${coolink.dist.path}/lib">
   <fileset file="${CLASS_DIR}/longcon-framework.jar"excludes="**/*.launch, **/*.java" />
  </copy>
 </target>

调用svn命令,这与三中的步骤7有密切的联系
<target name="commit">
 <svn username="aaa" password="aaa">
         <commitfile="${coolink.dist.path}/lib/longcon-framework.jar"message="${msg.commit}"  />
     </svn>
 </target>
 <target name="all"  depends="clean,build-framework,jar,commit"/>

</project>
注释:

a设置编译所需要的类路径可以用:                     <classpath>
      <pathelement path="${classpath}"/>
      <fileset dir="lib">
        <includename="**/*.jar"/>
      </fileset>
      <pathelement location="classes"/>
      <dirset dir="build">
        <includename="apps/**/classes"/>
        <excludename="apps/**/*Test*"/>
      </dirset>
      <filelist refid="third-party_jars"/>

   </classpath>

b <target name="test" depends="clean">depends表示依赖关系
 2 cruisecontrol的config文件,CC启动的时候会自动寻找此文件,当然你可以通过修改启动文件修改config.xml名称,只要两处一致就能找到,下面是一个config文件的实例:

<cruisecontrol>//cc的固有标签,cc中可以有多个project

 <project name="framework">// 工程名称

<plugin name="labelincrementer" classname="net.sourceforge.cruisecontrol.labelincrementers.SVNLabelIncrementer"/>
       <labelincrementerworkingcopypath="projects/${project.name}"/>// 显示svn的版本号

listeners:监听器,来报告cc的此项目的运行信息
  <listeners>
   <currentbuildstatuslistener file="logs/${project.name}/status.txt"/>
  </listeners>

bootstrappers从svn源码控制程序更新本地版本,据说还有向其它插件提供当前创建的状态

  <bootstrappers>
   <svnbootstrapper localWorkingCopy="projects/${project.name}"username="luojing" password="luojing"/>
  </bootstrappers>
  <bootstrappers>//向ant提供当前信息
   <antbootstrapper anthome="apache-ant-1.7.0"buildfile="projects/${project.name}/build.xml"target="jar" />
  </bootstrappers>
  <modificationset quietperiod="30">// 通过svn更新原代码
   <!-- touch any file in connectfourproject to trigger a build -->
   <svn localWorkingCopy="projects/${project.name}"username="luojing" password="luojing"/>
  </modificationset>

<schedule interval="28800">设定检查编译build版本的时间单位s
   <ant anthome="apache-ant-1.7.0"buildfile="projects/${project.name}/build.xml"/>
  </schedule>
  <log>//显示单元测试信息
   <merge dir="projects/${project.name}/framework/target/test-results"/>
  </log>
  <publishers>//发布版本
   <onsuccess>//成功,并生成有时间戳的目录
    <artifactspublisher dest="D:/CruiseControl/artifacts/${project.name}"file="projects/${project.name}/longcon-framework.jar"/>
   </onsuccess>
   <onfailure>//失败发送邮件到响应的人员
    <htmlemail buildresultsurl="http://localhost:8080/cruisecontrol/buildresults/${project.name}"mailhost="邮件服务器" password="密码" username="用户名"defaultsuffix="@**.com.cn" returnname="PetClinicContinuous Integration" returnaddress="sunny@**.com.cn"charset="UTF-8" skipusers="true"xsldir="webapps/cruisecontrol/xsl" css="webapps/cruisecontrol/css/cruisecontrol.css">
     <always address="接收邮件方的邮箱"/>
    </htmlemail>
   </onfailure>
  </publishers>
 </project>
 <project name="site">
  <listeners>
   <currentbuildstatuslistener file="logs/${project.name}/status.txt"/>
  </listeners>

  <bootstrappers>
   <svnbootstrapper localWorkingCopy="projects/${project.name}"username="sunny" password="sunny"/>
  </bootstrappers>
  <bootstrappers>
   <antbootstrapper anthome="apache-ant-1.7.0"buildfile="projects/${project.name}/build.xml"target="jar" />
  </bootstrappers>
        <modificationset>//设置只有framework工程成功了才执行此次的操作,体现了project的依赖关系
          <buildstatus logdir="logs/framework"/>
        </modificationset>
 </project>
</cruisecontrol>

四 启动CC可以实现集成编译、集成构建、单元测试的功能,对于持续构建这是最简单不过了,要继续努力学习哦。

五 持续集成使用了一段时间发现了源代码目录总是不能自动更新,认真查找发现是因为自己对标签<svnbootstrapper>的理解不正确,现在就是在ant的build.xml中调用svn的提交命令来解决的,不知道思路是否正确,请大家指教。

下面就更清晰的介绍一下常用的标签把。

CC配置文件范connectfour范例Config.xml如下:

<cruisecontrol>
    <project name="connectfour">

       <listeners>
           <currentbuildstatuslistener file="logs/${project.name}/status.txt"/>
        </listeners>

       <bootstrappers>
           <antbootstrapper anthome="apache-ant-1.7.0"buildfile="projects/${project.name}/build.xml"target="clean" />
        </bootstrappers>

       <modificationset quietperiod="30">
           <!-- touch any file in connectfour project to triggera build -->
           <filesystem folder="projects/${project.name}"/>
        </modificationset>

       <schedule interval="300">
           <ant anthome="apache-ant-1.7.0" buildfile="projects/${project.name}/build.xml"/>
        </schedule>

       <log>
           <merge dir="projects/${project.name}/target/test-results"/>
        </log>

       <publishers>
           <onsuccess>
               <artifactspublisher dest="artifacts/${project.name}"file="projects/${project.name}/target/${project.name}.jar"/>
           </onsuccess>
        </publishers>

    </project>
</cruisecontrol>

<cruisecontrol>根元素是<cruisecontrol>,该元素很简单,没什么需要配置的属性。

目前CC支持多项目(multiproject),因此可以有多个并行的<project>元素。支持的子元素包括:
 <project>
     <property/>
     <plugin/>
     <dateformat/>
     <labelincrementer/>
     <listeners>
        <cmsynergysessionmonitor/>
        <currentbuildstatusftplistener/>
        <currentbuildstatuslistener/>
        <currentbuildstatuspagelistener/>
        <lockfilelistener/>
     </listeners>
     <bootstrappers>

        <accurevbootstrapper/>
        <alienbrainbootstrapper/>
        <antbootstrapper/>
        <clearcasebootstrapper/>
        <clearcaseviewstrapper/>
        <cmsynergybootstrapper/>
        <currentbuildstatusbootstrapper/>
        <currentbuildstatusftpbootstrapper/>
        <cvsbootstrapper/>
        <execbootstrapper/>
        <gitbootstrapper/>
        <harvestbootstrapper/>
        <lockfilebootstrapper/>
        <mercurialbootstrapper/>
        <p4bootstrapper/>
        <plasticscmbootstrapper/>
        <snapshotcmbootstrapper/>
        <starteambootstrapper/>
        <surroundbootstrapper/>
        <svnbootstrapper/>
        <tfsbootstrapper/>
        <vssbootstrapper/>
     </bootstrappers>
     <modificationset>

        <accurev>
        <alienbrain/>
        <alwaysbuild/>
        <buildstatus/>
        <clearcase/>
        <cmsynergy/>
        <compound>
           <targets/>
           <triggers/>
        </compound>
        <cvs/>

        <darcs/>
        <filesystem/>
        <forceonly/>
        <git/>
        <harvest/>
        <httpfile/>
        <mavensnapshotdependency/>
        <maven2snapshotdependency/>
        <mercurial/>
        <mks/>
        <p4/>
        <plasticscm/>
        <pvcs/>
        <snapshotcm/>
        <starteam/>
        <store/>
        <surround/>
        <svn/>
        <tfs/>
        <timebuild>
        <ucm>
        <veto/>
        <vss/>
        <vssjournal/>
     </modificationset>
     <schedule>

        <ant/>
        <maven/>
        <maven2/>
        <pause/>
        <nant/>
        <phing/>
        <rake/>
        <exec/>
        <composite/>
     </schedule>
     <log>

        <merge/>
<gzip/>
<delete/>
     </log>
     <publishers>

        <antpublisher/>
        <artifactspublisher/>
        <clearcasebaselinepublisher/>
        <cmsynergybaselinepublisher/>
        <cmsynergytaskpublisher/>
        <compoundpublisher/>
        <currentbuildstatuspublisher/>
        <currentbuildstatusftppublisher/>
        <email/>
        <execute/>
        <ftppublisher/>
        <htmlemail/>
        <http>
        <jabber/>
        <onfailure/>
        <onsuccess/>
        <rss/>
        <sametimeannouncement/>
        <scp/>
        <sfeedocman/>
        <sfeefrs/>
        <sfeetracker/>
        <socket/>
        <weblog>
        <x10/>
        <xsltlogpublisher/>
        <yahoopublisher/>
     </publishers>
   </project>

 子元素过多所以详情可以参看官方文档的说明。

这里只介绍几个常用的子元素:

<bootstrappers>:<bootstrappers>在创建之前会运行,相当于一个预处理的作用,<bootstrappers>下面每个子元素都是独立的,因此可以同时配置多个bootstrappers。

CC提供的bootstrappers包括两种,一种用于向其他插件提供项目当前创建的状态,还有一种是从某个源码控制系统更新本地文件,其中最常用的就是<currentbuildstatusbootstrapper>和<svnbootstrappers>。<currentbuildstatusbootstrapper>指定了状态文件的位置,主要是用来访问项目当前创建的状态,CC的<currentbuildstatusbootstrapper>会将创基爱你的状态写入这个文件。

<svnbootstrapper>的作用有点难理解,因为我们每次项目的创建都应该基于最新的代码,因此在创建之前就要获得最新的项目文件,如果使用的是ant来完成这个任务,那么buildfile本身在创建开始之前发生了变化,我们是不是应该先更新这个buildfile,然后才通过buildfile来对项目进行构建呢?<svnbootstrapper>就是为从源码控制系统更新buildfile文件而设计的(还有一种替代的使用方法是使用wrapper buildfile,这样就不用使用<svnbootstrapper>了,wrapperbuildfile也是推荐的方法,<modificationset>部分会进行详细的讨论)。

<modificationset>:包括了SourceControl插件的配置信息,用于检查各个源码控制系统中是否发生变化,<schedule>会用到这里的配置信息,如果检测到变化,会触发创建过程。

<modificationset>的属性quietperiod(单位为秒)定义了一个时间值。如果CC检查到了变化,会自检查到变化的源码控制系统的最后一次checkin 的时间开始等待,等待时间由quietperiod决定,等待结束之后才触发创建(build)过程,主要是防止有人在checkin的过程当中就触发创建过程(可能check in只做了一半,这个时候触发创建显然是不正确的).

下面是一个modificationset的例子:

<modificationset quietperiod="30">
           <svn localworkingcopy="projects/SFA"/>
</modificationset>


|

posted on 2009-11-05 17:50 找个美女做老婆 阅读(1022) 评论(0)  编辑  收藏

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
ivy安装
lua脚本实现自动生成APK包
ant初步使用
Sun技术社区 - Java,Solaris,SunONE,JES,StarSuite技术论坛 - Ant应用2
Apache Ant使用进阶
Ant打可执行jar包指南
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服