【转】CruiseControl的部署


来自http://tech.ccidnet.com/art/3565/20030303/480549_1.html


      ANT是用过的最好的 Build工具.CruiseControl则通过不断检查SCM (VSS, ClearCase, StarTeam, etc), 一旦发现改动, 调用ANT进行编译, 部署, 实现即时的集成. 一旦编译失败, 则立刻自动发Email给"始作俑"者, 提醒其修正代码. CC自带了一个Web应用, 可是随时查看编译状况和历史状况(包括自从前一次Build, 有哪些文件,是谁做了改动, Build失败的原因, Build的成果(自定义的, 比如最后的打包文件, 自动生成的JavaDoc) 总之, 通过集成Ant和CC, 尽量避免了Daily Build容易Broken的缺点, 而且自动化程度更高. 另外Ant和CC都分别有.net版本, 在下一个.net项目中, 还打算使用它们来进行集成控制.
安装CruiseControl
       和AntHill一样,使用CruiseControl构建持续集成系统,需要Tomcat,Ant,CVSNT和WinCVS的支持(参见 AntHill:构建Nightly Build系统)。安装CruiseControl很简单,下载cruisecontrol-2.2.zip(参见持续集成资源),解压到安装目录 C:\BuildServer,即可完成安装。
     安装Tomcat4.1到C:\BuildServer目录,并在C:\BuildServer目录创建workingCopy子目录,作为 CruiseControl的工作目录。BuildServer的目录结构如下图所示,其中CruiseControl的启动脚本 cruisecontrol.bat(或cruisecontrol.sh)位于BuildServer\cruisecontrol-2.2\main \bin目录下。

准备构建目录结构
    1.创建CruiseControl的日志目录:C:\BuildServer\cruisecontrol-2.2\main\logs\frameworkProject。
    2.创建CVS的工作目录:C:\BuildServer\workingCopy\frameworkProject。
    3.创建工作目录的代码库目录:C:\BuildServer\workingCopy\frameworkProject\lib。
    4.创建工作目录的单元测试报告目录:C:\BuildServer\workingCopy\frameworkProject\reports\junit\data。
    5.创建工作目录的jar文件存放目录:C:\BuildServer\workingCopy\frameworkProject\dist。
    
初始化代码工作目录
       在C:\BuildServer\workingCopy\frameworkProject目录下,使用WinCVS CheckOut src模块:cvs co src。
    
准备项目的依赖代码库
       把构建项目的依赖代码库复制到C:\BuildServer\workingCopy\frameworkProject\lib。完成之后的目录结构如上图所示。
    
编写项目构建脚本
       构建脚本build.xml和build-cc.xml位于C:\BuildServer\workingCopy\frameworkProject目 录下。其中build.xml是项目的Ant构建脚本,而build-cc.xml负责帮助CruiseControl从CVS服务器上update源代 码到本地的工作目录,然后调用build.xml构建项目。
  
  build-cc.xml

<?xml version="1.0"?>
<project name="CruiseControlWrapperForFrameworkProject" default="build" basedir=".">
<target name="update">
  <!-- update the working copy from the cvs -->
  <exec executable="cvs">
   <arg line="-d :pserver:talent:talent @10.75.140.128:/cvsroot update src"/>
  </exec>
</target>
  <target name="build" depends="update">

  <ant antfile="build.xml" target="jar"/>
</target>
</project>


  build.xml
<?xml version="1.0"?>
<project name="frameworkProject" default="compile">
    <description>
        This is our framework project which we're putting on CruiseControl
    </description>
        <target name="setup" depends="setup.properties, setup.paths" />
    <target name="setup.properties">
        <property name="src.main" value="src" />
        <!--<property name="src.test" value="src/test" />-->
        <property name="classes" value="classes"/>
        <property name="classes.main" value="${classes}/main" />
        <!--<property name="classes.test" value="${classes}/test" />-->
        <property name="libs" value="lib" />
        <property name="dist" value="dist" />
        <property name="reports" value="reports" />
        <property name="reports.junit.data" value="${reports}/junit/data" />
    </target>
    <target name="setup.paths">
        <path id="classpath.main">
            <pathelement location="${classes.main}" />
        </path>
        <path id="classpath.lib">
         <fileset dir="${libs}">
          <include name="**/*.jar" />
         </fileset>
        </path>
    </target>
    <target name="clean" depends="setup">
        <delete dir="${classes}" failοnerrοr="false" />
        <delete dir="${reports}" failοnerrοr="false" />
        <delete dir="${dist}" failοnerrοr="false" />
    </target>
    <target name="compile" depends="setup, compile.main" />
    <target name="compile.main" depends="setup">
        <mkdir dir="${classes.main}" />
        <javac srcdir="${src.main}" destdir="${classes.main}">
         <classpath refid="classpath.lib" />
        </javac>
    </target>
    <target name="compile.tests" depends="setup">
        <mkdir dir="${classes.test}" />
        <javac srcdir="${src.test}"
               destdir="${classes.test}"
               classpathref="http://blog.163.com/yang_jianli/blog/classpath.lib" />
    </target>
    <target name="test" depends="compile">
        <delete dir="${reports.junit.data}" failοnerrοr="false" />
        <mkdir dir="${reports.junit.data}" />
        <junit printsummary="yes" haltonfailure="no"
               failureproperty="tests.failed">
            <classpath refid="classpath.lib" />
            <formatter type="xml" />
            <batchtest fork="yes" todir="${reports.junit.data}"
                       failureproperty="tests.failed">
                <fileset dir="${src.test}">
                    <include name="**/*Test*.java" />
                    <exclude name="**/AllTests.java" />
                </fileset>
            </batchtest>
        </junit>
        <fail if="tests.failed" message="Some unit tests failed" />
    </target>
    <target name="jar" depends="compile, test">
        <mkdir dir="${dist}" />
        <jar destfile="${dist}/framework.jar" basedir="${classes.main}" />
    </target>
    <target name="all" depends="jar" />
</project>


配置CruiseControl
  config.xml
      下 面以一个简单的config.xml文件为例,说明CruiseControl的配置方法。配置文件config.xml位于 C:\BuildServer\cruisecontrol-2.2\main\bin目录下,和启动脚本cruisecontrol.bat放在一起。
<?xml version="1.0"?>
<cruisecontrol>
<project name="frameworkProject">
  <dateformat format="yyyy/MM/dd HH:mm:ss" />
  <bootstrappers>
   <currentbuildstatusbootstrapper file="../logs/currentbuild.txt" />
  </bootstrappers>
  <modificationset quietperiod="60" >
   <cvs LocalWorkingCopy="../../../workingCopy/frameworkProject/src"/>
  </modificationset>
  <schedule interval="3600" >
   <ant antWorkingDir="../../../workingCopy/frameworkProject" buildfile="build-cc.xml" />
  </schedule>
  <log dir="../logs/frameworkProject">
   <merge dir="../../../workingCopy/frameworkProject/reports/junit/data"/>
  </log>
  <publishers>
   <currentbuildstatuspublisher file="../logs/currentbuild.txt" />
   <artifactspublisher dir="../../../workingCopy/frameworkProject/dist" dest="../logs/frameworkProject" />
   <htmlemail mailhost="talenttech.com.cn"
    returnaddress="buildmaster@talenttech.com.cn"
    subjectprefix="[Talent Build Server]"//自己替换[]
buildresultsurl="http://10.75.140.128:9000/cruisecontrol/buildresults/ ;frameworkProject"
logdir="C:\BuildServer\cruisecontrol-2.2\main\logs\frameworkProject"
            xsldir="C:\BuildServer\cruisecontrol-2.2\reporting\jsp\xsl"
css="C:\BuildServer\cruisecontrol-2.2\reporting\jsp\css\cruisecontrol.css">
    <failure address="liutao@talenttech.com.cn" />
    <success address="liutao@talenttech.com.cn" />
    <success address="wangkai@talenttech.com.cn" />
    <success address="wangchuang@talenttech.com.cn" />
    <success address="wu.gaofeng@126.com" />
   </htmlemail>
  </publishers>
</project>
</cruisecontrol>


<cruisecontrol>
       <cruisecontrol>是配置文件的根元素,它可以拥有一个或多个<project>子元素。本例中它拥有一个项目名为frameworkProject。

<project>
       <project>元素是一个完整的build任务,包括检查配置管理库是否有新的修改,构建项目并发布项目构建结果。它告诉 CruiseControl构建什么,何时构建,如何构建以及如何发布构建报告。它有一个必需的属性name和一个可选属性 buildafterfailed。
       属性buildafterfailed定义了当构建失败时,是否要继续进行,缺省是"true"。
<project> 元素的子元素包 括,<bootstrappers>,<modificationset>,<schedule>,<log>,<publishers>,<dateformat> 和<plugin>,其中<modificationset>和<schedule>是必需的元素。

<dateformat>
       <dateformat>用于定义日期的格式,缺省格式是:MM/dd/yyyy HH:mm:ss。

<bootstrappers>
       <bootstrappers>元素是启动任务Plugin的容器, 用于定义构建任务启动前需要执行的任务。常用的Plugin包括:
        1. <currentbuildstatusbootstrapper>,定义一个CruiseControl的构建状态信息文件。 CruiseControl的Build Result JSP从该文件读取状态信息并显示在页面上。属性file用于指定构建状态文件目录和文件名。
        2. <cvsbootstrapper>,用于在项目构建开始前从CVS服务器上update指定的文件。通常可以用于更新项目的构建脚本。属性 localWorkingCopy指定CVS本地工作目录,属性file指定需要update的文件名,相对于属性localWorkingCopy指定 的目录。
       3. <svnbootstrapper>,用于在项目构建开始前从SVN服务器上update指定的文件。通常可以用于更新项目的构建脚本。属性 localWorkingCopy指定SVN本地工作目录。

<modificationset>
       <modificationset>元素用于告诉CruiseControl是否需要构建项目,即配置管理库的代码是否存在更新。
它拥有两个可选属性requiremodification和quietperiod。
       属性requiremodification,告诉CruiseControl,在配置管理库没有代码更新的情况下,是否需要构建。缺省为"true",即没有更新则无须进行构建。
       属性quietperiod,告诉CruiseControl,最新一次代码提交后CruiseControl需要等待的时间(秒)。用于防止CruiseControl在开发人员提交代码时进行项目构建。缺省为"60"秒。
       在本例中使用<cvs>来检查和工作目录相关的代码在CVS配置管理库是否有更新。<cvs>使用"cvs log"命令来检查最新更新工作目录和当前代码库的差异。
  
<schedule>
       到目前为止,以上的配置文件内容已经定义了CruiseControl构建什么以及何时构建。
<schedule>元素 告诉 CruiseControl每隔多长时间(秒)启动一次构建任务。它有一个可选的属性interval,用于定义以秒为单位的时间间隔。缺省为"300" 秒。
       在本例中,属性interval设为"3600",这意味着CruiseControl每隔一个小时使用<modificationset>定义的任务检查一次代码库。
       <schedule>元素拥有三个子元素<ant>,<maven>和<parse>。
       <ant>子元素告诉CruiseControl何时或每隔几次运行Ant来构建项目。
       在本例中,antWorkingDir属性设定Ant的工作目录,buildfile属性设定构建脚本build file的目录。
       属性multiple告诉CruiseControl每隔几次执行一次本<ant>任务。
       除此之外,还可以指定Ant的运行时间(time属性),build file的target(target属性,不设定则为build file的缺省target)。
       请参见CruiseControl的配置文档(位于${CruiseControl_Home}/main/docs目录下)。
  
<log>
       <log>元素设定CruiseControl日志文件的存放目录,并通过<merge>子元素指定合并什么样的XML文件(构建过程中产生的文件)到CruiseControl的日志文件中。
       <merge>子元素的pattern属性定义匹配的文件名模式,缺省为".xml";dir属性用于指定一个目录,这个目录下所有匹配模式的文件将合并到CruiseControl的日志文件中。
  
<publishers>
       <publishers>元素用于指定构建任务结束后,CruiseControl如何发布项目构建结果。项目构建结果的发布方式可以是Email,网页,复制代码库到指定的目录,或是发布代码库到FTP服务器。
       在本例中,共有<currentbuildstatuspublisher>,<artifactspublisher>和<htmlemail>三个publisher。
       <currentbuildstatuspublisher> publisher把下次构建的时间写入指定文件,文件名由file属性设定。
       <artifactspublisher> publisher元素把项目构建产品复制到指定的目录,dir属性定义源目录,dest定义目标目录的父目录(实际目录还要加上构建时的时间戳,如:父目录/19890604203828)。
       <htmlemail> publisher把构建结果以HTML格式通过Email发布。缺省情况下,HTML格式的Emai和CruiseControl Web应用的构建结果JSP页面相同。
       本例中<htmlemail>的属性和子元素的作用很容易理解,更多的配置项参见联机文档。

创建CruiseControl的Web应用
    1. 在C:\BuildServer\cruisecontrol-2.2\reporting\jsp目录下运行build war命令;
    2. 提示设置user.log.dir属性时,输入C:\BuildServer\cruisecontrol-2.2\main\logs;
    3. 提示设置user.build.status.file属性时,输入currentbuild.txt;
    4. 提示设置cruise.build.artifacts.dir属性时,输入/artifacts/frameworkProject;
    5. Web应用构建完成后,可以在C:\BuildServer\cruisecontrol-2.2\reporting\jsp\dis目录下找到cruisecontrol.war文件;
    6. 把cruisecontrol.war复制到tomcat的webapps目录下,发布CruiseControl的Web应用;

启动CruiseControl
       使用C:\BuildServer\cruisecontrol-2.2\main\bin目录下cruisecontrol.bat启动CruiseControl。用法如下:
C:\BuildServer\cruisecontrol-2.2\main\bin>cruisecontrol [options]
       命令cruisecontrol的选项包括:
-port [number]      JMX服务器的Http Controller的端口;缺省为8000
-rmiport [number]   JMX服务器的RMI Controller的端口;缺省为1099
-xslpath directory    JMX的XSL文件存放目录;
-configfile file       配置文件的路径;缺省为当前目录下的config.xml文件
-debug             将CruiseControl内部的日志级别调整到DEBUG
       只有指定port和/或rmiport属性时,JMX服务器才启动。如果要修改port参数(不使用缺省的8000端口),必须要修改reporting /jsp目录下的controlpanel.jsp文件,然后再重新创建和发布CruiseControl的Web应用;也可以直接修改 Tomcat\webapps\cruisecontrol目录下的controlpanel.jsp页面。

CruiseControl的Web界面
       在浏览器地址栏输入:http://BuildServer-IP:9000/cruisecontrol/,可以访问CruiseControl的Web应用
       在左侧区域,按时间顺序列出最新Build结果的连接。如果Build结果超过10个,左侧区域只显示10个连接,其余的Build结果可以在下面的下拉框中找到。上图中因为Build结果少于10个,所以下拉框是空的。
       当点击右上角的Control Panel按钮时,如果出现错误,则是因为没有使用CruiseControl的JMX支持。要启动JMX支持,请看下节内容。

使用JMX控制台
       要使用CruiseControl的JMX控制台很简单,只需在启动cruisecontrol时指定JMX Server的Http Controller端口即可:cruisecontrol -port 8000。
       进入CruiseControl的Web应用界面,点击右上角的Control Panel按钮,则出现CruiseControl的"JMX Control Panel"。
       可以通过JMX控制面板在运行时修改配置,而不需要重启CruiseControl。点击CruiseControl Project MBean,尝试它的管理功能。
       例如,可以修改MBean的"BuildInterval"属性,来更改项目构建的时间间隔;修改ConfigFileName,则可以更改 CruiseControl的配置文件;点击MBean的build操作"invoke"按钮,则可以强制启动项目构建任务。

持续集成资源
    1. 持续集成:http://www.martinfowler.com/articles/continuousIntegration.html
    2. AntHill:http://www.urbancode.com/projects/anthill/
    3. CruiseControl:http://cruisecontrol.sourceforge.net/
    4. CVSNT:http://www.cvsnt.org/
    5. WinCVS中文版:http://www.8848software.com/wincvs/
    6. Driving On CruiseControl Part1:
       http://www.javaranch.com/journal/200409/DrivingOnCruiseControl_Part1.html
    7. Driving On CruiseControl Part2:
       http://www.javaranch.com/journal/200410/DrivingOnCruiseControl_Part2.html
    8. Scheduled Builds:http://www.pragmaticprogrammer.com/starter_kit/au/scheduled.pdf

     Java代码规范检查工具很多,CheckStyle是其中最有名的,它的Eclipse插件,使用非常方便。我在最近的项目中,之所以选择JCSC,是 因为JCSC不但可以检查代码规范,而且给出了NCSS(Non Commenting Source Statements)和CCN(Cyclomatic Complexity Number),前者近似等于Java的有效代码行,后者则用于评价类方法的复杂度。

      下面的安装配置延续我的Blog,CruiseControl:持续集成工具的例子。

安装JCSC
1、从SourceForge下载JCSC.zip
2、将JCSC.zip解压到D:\BuildServer目录
3、添加JCSC_HOME系统环境变量,本例中为D:\BuildServer\jcsc
4、添加JCSC_HOME/bin到系统路径

配置ANT
1、把JCSC_HOME/jcsc/lib的jar文件复制到/ANT_HOME/lib

配置CruiseControl
1、把JCSC_HOME/lib的jar文件复制到DEFAULT_CCDIR/main/lib
2、修改cruisecontrol.bat,在cruisecontrol.jar之前添加%LIBDIR%\JCSC.jar,在类路径后面添加%LIBDIR%\xercesImpl.jar
3、复制/JCSC_HOME/html/xml/xsl/cruisecontrol/jcsc.xsl文件到TOMCAT_HOME//webapps/cruisecontrol/xsl目录
4、修改TOMCAT_HOME//webapps/cruisecontrol/xsl/jcsc.xsl文件,把JCSC Details的链接改成"/cruisecontrol/jcsc/index.html"
5、在TOMCAT_HOME/webapps/cruisecontrol/buildresults.jsp页面中添加


6、在webapps/cruisecontrol目录下创建jcsc目录
7、复制JCSC_HOME/html/xml目录下的xsl子目录和index.html文件到webapps/cruisecontrol/jcsc目录
8、复制JCSC_HOME/html/web/jcsc-result/rules.jcsc.xml文件到webapps/cruisecontrol/jcsc目录

9、把JCSC生成的overview.xml合并到CruiseControl的log.xml文件。修改CruiseControl的config.xml文件,如
<log dir="../logs/frameworkProject">
  <merge dir="../../../workingCopy/frameworkProject/reports/junit/data" />
  <merge file="D:\BuildServer\tomcat-4.1.31\webapps\cruisecontrol\jcsc\overview.xml" />
</log>

修改ANT的构建脚本build.xml
1、添加JCSC属性
   <!-- jcsc home config -->
    <property name="jcsc.home" value="D:\BuildServer\jcsc" />
    <property name="jcsc.log.dir" value="D:\BuildServer\tomcat-4.1.31\webapps\cruisecontrol\jcsc" />
    <property name="jcsc.rules.dir" value="D:\BuildServer\tomcat-4.1.31\webapps\cruisecontrol\jcsc\rules.jcsc.xml" />

2、定义JCSC的ANT Task
  
 <taskdef name="jcsc" classname="rj.tools.jcsc.ant.JCSCTask" />

3、<target name="clean">中添加删除JCSC日志文件的任务
<delete failοnerrοr="false">
        <fileset dir="${jcsc.log.dir}" includes="*.xml" excludes="xsl,rules.jcsc.xml,index.html" />

    </delete>
4、添加JCSC Target
  
 <target name="jcsc">
  <jcsc rules="${jcsc.rules.dir}" destdir="${jcsc.log.dir}">
   <fileset dir="${src.main}" includes="**/*.java" />
  </jcsc>
</target>

5、调用JCSC Task
<target name="all" depends="clean, jar, test, coverage.report, jcsc" />


使用Rules Editor修改Rules文件
1、运行JCSC_HOME\bin\ruleseditor.bat命令,使用Rules Editor编辑Rules定义文件,可以编辑Open Brace'{' On New Line,Class/I-Face Header等选项
2、也可以直接修改rules.jcsc.xml文件

集成在CruiseControl的JCSC报告如下图所示。



在htmlmail邮件中集成JCSC报告
要 在CruiseControl的htmlmail邮件中集成JCSC报告,需要修改CruiseControl的代码。在 HTMLEmailPublisher类的String[] xslFileNames变量中加入jcsc.xsl,即可在htmlmail中包含JCSC报告的概要部分。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值