如何将Ant下Web项目迁移到Hudson实现持续化集成开发
http://hudson-ci.org/download/war得到最新版本的Hudosn,
http://hudson-ci.org/download/plugins/下得到cvs, emma插件(cvs.hpi, emma.hpi)。建议安装为Jboss/Tomcat下的web应用而不是用java直接启动hudson,这样可以对端口,配置升级方便点。当然jdk的安装是必需的。
把hudson.war或者hudson.zip解压缩到$JBOSS_HOME/server/all/deploy, 目录名改为hudson.war, 把cvs,emma插复制到$JBOSS_HOME/server/all/deploy/hudson.war/WEB-INF/plugins/里。把$JBOSS_HOME/server/all/deploy/jbossweb-tomcat55.sar/server.xml(JBOSS版本不同tomcat目录可能不同)修改端口为80(默认为8080):<Connector port="80" address="${jboss.bind.address}"。$JBOSS_HOME/bin/jboss_init_readhat.sh start启动JBOSS,浏览器访问
http://HUDSON_SERVERIP/hudson/,应该可以登陆hudson界面。
首先,我们访问系统配置,完成基本的配置项。
1. 安全配置:我为了简单方便,采用unix用户组/数据库方式来实现用户认证,这样只要有hudson服务器登陆账号的就可以管理hudson。它还支持hudson专有用户数据库,LDAP,servlet容器等认证方式。另外授权策略也是可以配置的,有安全矩阵,登陆所有,匿名所有,项目矩阵等授权策略。我为了简单方便,采用登陆所有的方式,即登陆用户可以做所有操作,非登陆用户是只读模式。
注:/root/.hudson/config.xml是保存hudson全局配置的文件,其中的<authorizationStrategy class="hudson.security.ProjectMatrixAuthorizationStrategy"/>表示项目矩阵授权策略,
<authorizationStrategy class="hudson.security.FullControlOnceLoggedInAuthorizationStrategy"/>表示登陆所有的认证方式。如果< authorizationStrategy />没有,则默认为匿名所有的认证模式。所以如果保存了错误的认证方式导致root无法再进入系统配置页面,就可以注释掉< authorizationStrategy />项,然后redeploy hudson(比如加空格在$JBOSS/server/all/deploy/hudson.war/WEB-INF/web.xml文件中。
2. 全局变量:主要可以用来配置cvs的用户名,因为ant里task用到环境变量来实现cvs的按用户检出。
3. JDK: 主要配置jdk的JAVA_HOME。
4. Ant: 主要配置ant的ANT_HOME。
5. Cvs: 主要配置cvs执行文件路径和.cvspass文件路径。
6. Shell: 配置shell执行文件路径如/bin/bash。
7. E-mail提醒:smtp服务器地址,邮件域名后缀,发件人地址,hudson url。如果不想发邮件提醒,让smtp服务器地址为空即可。
项目配置:
新建任务,任务名通常为你的项目名,然后进入项目配置。
1. 高级项目选项:你应该改工作空间为你的ant的check-out项目根目录。
2. 源代码管理(假设cvs):你选上cvs,然后输入CVSROOT(格式如::pserver:USERNAME@CVSSERVER:PORT:/REP-PATH),模块名,分支名。
3. 构建触发器:有“在其他项目构建完成后构建”,“远程触发构建”,“周期性构建”,“SCM投票”等方式,通常选“周期性构建”,schedule的格式为MIN HOUR DAY MONTH WEEKDAY支持*,/,,,-字符组合。-表示范围,*表示任意,/表示间隔数,,表示多个组合。
4. 构建选项:可以添加之前执行的shell script在命令行输入框中,选择ant版本,提供ant的任务名(否则就是build.xml的默认任务名), build file如果不在项目工作空间根目录下请输入具体路径。添加java options为-Xms64m –Xmx512m以防止build时out of memory error。构建后行为主要用于单元测试和覆盖率分析报表生成。勾选Publish Junit test result report, 然后提供测试报表xml文件集合的路径如UnitTest/**/*Test.xml(通常应该放在项目工作空间之下的某个目录,否则可能不被hudson找到)。勾选Record Emma coverage report,然后提供覆盖率分析报表xml文件的路径如EMMATest/coverage/coverage.xml(通常应该放在项目工作空间之下的某个目录,否则可能不被hudson找到),health reporting的阀值设置分类,方法,代码块,行4级。都有好和及格两类阀值可以配置。
5. E-mail提醒:可以设置项目构建的收件人,以及是否发送邮件为每次不稳定构建(单元测试未通过等),是否发送单独邮件给中断构建的开发者。
附项目原有的build.xml:
<?xml version="1.0"?>
<project name="ProjectName" default="all" basedir=".">
<property file="build.properties"/>
<property environment="env" />
<property name="xms" value="-Xms512m"/>
<property name="xmx" value="-Xmx768m"/>
<property name="module" value="projectName" />
<property name="test.dir" value="${project.dir}/UnitTest" />
<property name="emmatest.dir" value="${project.dir}/EMMATest" />
<path id="classpath">
<pathelement location="${emma.jar}"/>
<pathelement location="${emma_ant.jar}"/>
<fileset dir="${project.webinf.dir}/lib">
<include name="*.jar" />
</fileset>
</path>
<target name="clean" description="Removes build artifacts">
<delete dir="${project.classes.java.dir}" />
<delete dir="${project.classes.test.dir}" />
<delete dir="target"/>
<delete dir="${test.dir}"/>
<delete dir="${emmatest.dir}" />
</target>
<!—commented for hudson integration with CVS
<target name="checkoutcvs" description="Check CVS">
<cvs command=" checkout -r branchName " cvsroot=":pserver:${env.cvsUser}@cvsServer:/cvs/repo" dest="." package="${module}/java"/>
<cvs command=" checkout -r branchName " cvsroot=":pserver:${env.cvsUser}@engcvsserv3.corp.webex.com:/cvs/repo" dest="." package="${module}/web"/>
</target>
-->
<target name="init" description="Initializes build artifacts">
<mkdir dir="target"/>
<mkdir dir="${emmatest.dir}" />
<mkdir dir="${cc.webinf.dir}" />
<copy todir="${cc.webinf.dir}" >
<fileset file="${tar.webinf.dir}/web.xml" />
</copy>
</target>
<!--EMEA-->
<!-- directory that contains emma.jar and emma_ant.jar: -->
<!-- path element used by EMMA taskdef below: -->
<path id="emma.lib" >
<pathelement location="${emma.jar}" />
<pathelement location="${emma_ant.jar}" />
</path>
<taskdef resource="emma_ant.properties" classpathref="emma.lib" />
<target name="emma.compile.java">
<mkdir dir="${project.classes.java.dir}" />
<javac excludes="**/*.dtd" destdir="${project.classes.java.dir}" debug="${javac.debug}" fork="true" memoryMaximumSize="512m">
<src path="${project.src.java.dir}"/>
<classpath>
<path refid="classpath"/>
</classpath>
</javac>
</target>
<target name="emma.compile.test">
<mkdir dir="${project.classes.test.dir}" />
<mkdir dir="${test.dir}" />
<copy file="${project.webinf.dir}/web.xml" todir="${test.dir}"/>
<javac destdir="${project.classes.test.dir}" debug="${javac.debug}">
<src path="${project.src.test.dir}/${test.src.path}"/>
<classpath>
<path refid="classpath"/>
<pathelement location="${project.classes.java.dir}"/>
</classpath>
</javac>
</target>
<target name="makeWarPackage">
<war destfile="target/projectName.war" webxml="${project.webinf.dir}/web.xml" >
<zipfileset dir="${project.webinf.dir}" prefix="WEB-INF">
<exclude name="cvs/"/>
<exclude name="classes/"/>
</zipfileset>
<zipfileset dir="${project.style.dir}" prefix="${war.style.prefix}">
<exclude name="cvs/"/>
</zipfileset>
<zipfileset dir="${project.script.dir}" prefix="${war.script.prefix}">
<exclude name="cvs/"/>
</zipfileset>
<zipfileset dir="${project.images.dir}" prefix="${war.images.prefix}">
<exclude name="cvs/"/>
</zipfileset>
<fileset dir="${project.dir}/web">
<filename name="*.*"/>
</fileset>
<classes dir="${project.classes.java.dir}"/>
<zipfileset dir="${project.src.java.dir}" prefix="${test.dir}/classes">
<exclude name="cvs/"/>
<exclude name="**/*.java"/>
</zipfileset>
</war>
</target>
<target name="copyToTarget">
<mkdir dir="${test.dir}/classes/java" />
<copy todir="${test.dir}/classes/java">
<fileset dir="${project.classes.java.dir}" />
</copy>
<mkdir dir="${test.dir}/classes/test" />
<copy todir="${test.dir}/classes/test">
<fileset dir="${project.classes.test.dir}" />
</copy>
<!-- copy properity file of ${test.dir} -->
<copy todir="${test.dir}">
<fileset dir="${project.webinf.dir}">
<include name="**/*.xml" />
<include name="**/*.properties" />
<include name="**/*.xsd" />
<include name="**/*.sh" />
</fileset>
</copy>
<!-- copy properity file of src -->
<copy todir="${test.dir}/classes/java">
<fileset dir="${project.dir}/java/src">
<include name="**/*.xml" />
<include name="**/*.properties" />
<include name="**/*.xsd" />
<include name="**/*.sh" />
</fileset>
</copy>
<!-- copy test case data file of test -->
<copy todir="${test.dir}/classes/test">
<fileset dir="${project.dir}/java/test">
<include name="**/*.xml" />
<include name="**/*.properties" />
<include name="**/*.xsd" />
<include name="**/*.sh" />
<include name="**/*.xls" />
</fileset>
</copy>
</target>
<target name="emma.instr" depends="copyToTarget">
<mkdir dir="${emmatest.dir}/outinstr" />
<mkdir dir="${emmatest.dir}/coverage" />
<emma enabled="${emma.enabled}" >
<instr instrpath="${test.dir}/classes/java/${instr.src.path}"
destdir="${emmatest.dir}/outinstr/${instr.src.path}"
metadatafile="${emmatest.dir}/coverage/metadata.emma"
merge="true">
</instr>
</emma>
</target>
<target name="emma.test">
<mkdir dir="${emmatest.dir}/junitreport" />
<junit printsummary="yes" haltonerror="no" haltonfailure="no"
fork="yes">
<classpath>
<path refid="classpath"/>
<path refid="emma.lib"/>
<pathelement path="${test.dir}/classes/test"/>
<pathelement path="${emmatest.dir}/outinstr"/>
<pathelement path="${test.dir}/classes/java"/>
<pathelement path="${test.dir}"/>
</classpath>
<jvmarg value="-Demma.coverage.out.file=${emmatest.dir}/coverage/coverage.emma"/>
<jvmarg value="-Demma.coverage.out.merge=true"/>
<jvmarg value="${xms}"/>
<jvmarg value="${xmx}"/>
<formatter type="plain"/>
<formatter type="xml"/>
<batchtest fork="yes" todir="${test.dir}/classes/test">
<fileset dir="${test.dir}/classes/test">
<include name="**/*Test.class"/>
</fileset>
</batchtest>
</junit>
<delete file="${test.dir}/classes/test/log4j.xml" />
<delete file="${test.dir}/classes/test/win_no_cache.xml" />
<!--
<junitreport todir="${emmatest.dir}/junitreport">
<fileset dir="${test.dir}/classes/test">
<include name="TEST-*.xml"/>
</fileset>
<report format="frames" todir="${emmatest.dir}/junitreport/html"/>
</junitreport>
-->
</target>
<target name="emma.report ">
<copy todir="${emmatest.dir}/coverage/ " overwrite="true">
<fileset file="${emmatest.dir}/coverage/metadata.emma" />
</copy>
<emma enabled="${emma.enabled}" >
<report sourcepath="${project.src.java.dir}"
depth="method">
<fileset dir="${emmatest.dir}/coverage/ " >
<include name="*.emma" />
</fileset>
<xml outfile="${emmatest.dir}/coverage/coverage.xml" depth="method"
columns="name,class,method,block,line"/>
<!--html outfile="${emmatest.dir}/coverage/coverage.html"
depth="method"
columns="name,class,method,block,line"/ -->
</report>
</emma>
</target>
<target name="tearDown">
<delete dir="${cc.webinf.dir}" />
</target>
<target name="all" depends="clean,init,emma.compile.java,emma.compile.test,emma.instr, emma.test, emma.report, makeWarPackage, tearDown" />
本文转自 dannyy1026 51CTO博客,原文链接:
http://blog.51cto.com/dannyyuan/404295