Hudson 是一个可扩展的持续集成引擎。
主要用于:
1.持续、自动地构建/测试软件项目,如CruiseControl与DamageControl。
2.监控一些定时执行的任务。
Hudson拥有的特性包括:
- 易于安装-只要把hudson.war部署到servlet容器,不需要数据库支持。
- 易于配置-所有配置都是通过其提供的web界面实现。
- 集成RSS/E-mail/IM-通过RSS发布构建结果或当构建失败时通过e-mail实时通知。
- 生成JUnit/TestNG测试报告。
- 分布式构建支持-Hudson能够让多台计算机一起构建/测试。
- 文件识别- Hudson能够跟踪哪次构建生成哪些jar,哪次构建使用哪个版本的jar等。
- 插件支持-Hudson可以通过插件扩展,你可以开发适合自己团队使用的工具。
本篇结合国信CRM项目开发来说明一下hudson的搭建
公司内部hudson访问URL:http://192.168.2.20:8180/hudson/
一、hudson启动
从官网(http://hudson-ci.org/)下载最新的hudson.war包,放到tomcat下的webapps目录下
用解压缩软件打开hudson.war文件,找到WEB-INF/web.xml打开并编辑HUDSON_HOME的路径
启动Tomcat就可以通过Web页面访问了(如:http://192.168.2.20:8180/hudson/)。
二、hudson系统配置
启动后系统的基本配置,点击左侧系统管理菜单按钮选择系统设置子菜单
设置JDK路径
设置Ant工具路径
*由于java自带的编译器编译工程代码会出错,这里需要用到eclipse自带的编译器
把eclipse的plugins文件夹中的下面几个文件拷贝到ant的lib文件下
jdtCompilerAdapter.jar 从org.eclipse.jdt.core_3.6.2.v_A76_R36x.jar里面解压出来即可
设置邮件服务器,任务执行出错时可以发邮件提醒
三、创建一个构建任务
选择左侧新建任务按钮,设定任务名称和任务选项(此处选构建一个自由风格的软件项目)点击OK
设定SVN,将前后台代码工程URL添加到设定中,点击Update credentials输入svn访问密码验证访问权限
Local module directory (optional)处指定工程代码存放目录,建议使用工程的名字,./表示当前任务的根目录
编译触发器设定,hadsun可以自动触发编译任务可以指定在其他任务编译完成后触发,也可以定时触发等等
指定编译方式,hudson支持多重编译选择,这边选择ant编译方式
这边Ant Version选择系统配置中的ant环境即可,默认会调用工程下面的build.xml文件也可以自己指定,可以指定ant执行的Targets默认执行build.xml文件里面设置的Target
四、编写Ant执行文件
在后台工程根目录创建build.xml
<?xml version="1.0" encoding="UTF-8" ?>
<project name="ear" default="startJBoss" basedir=".">
<property name="earName" value="gsear" />
<property name="warName" value="GSCRM" />
<property environment="env" />
<property name="app.dir" value="${basedir}" />
<property name="guosen-dev.dir" value="${basedir}\guosen" />
<property name="ear.dir" value="${guosen-dev.dir}\${earName}.ear" />
<property name="war.dir" value="${ear.dir}\${warName}.war" />
<property name="src.dir" value="${app.dir}\src" />
<property name="fb.home" value="D:\Adobe\AdobeFlashBuilder4\FlashBuilderC.exe" />
<property name="findbugs.home" value="D:\findbugs-2.0.0" />
<property name="checkstyle.home" value="D:\checkstyle-5.5" />
<property name="fb.buildFile" value="E:\FbWorkspace\build.xml" />
<property name="fb.workspace" value="E:\FbWorkspace" />
<property name="classes.dir" value="${app.dir}\WebContent\WEB-INF\classes" />
<property name="swf.dir" value="${app.dir}\WebContent\clientd" />
<property name="webcontent.dir" value="${app.dir}\WebContent" />
<!--property name="jboss.home" value="${env.JBOSS_HOME}" /-->
<property name="jboss.home" value="D:\jboss-6.1.0.Final" />
<property name="jaa.home" value="D:\Java\jdk1.6.0_21"/>
<property name="jboss.server.config" value="default" />
<!-- 设定Java编译器 -->
<property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/>
<taskdef name="findbugs" classname="edu.umd.cs.findbugs.anttask.FindBugsTask"/>
<!-- 引入ant的<checkstyle>命令 checkstyletask.properties文件在jar包中 -->
<!--
<taskdef resource="checkstyletask.properties" classpath="${checkstyle.home}/checkstyle-5.5-all.jar" />
-->
<path id="build.classpath" description="编译时classpath">
<fileset dir="${webcontent.dir}\WEB-INF\lib">
<include name="*.jar" />
</fileset>
<fileset dir="${jboss.home}" casesensitive="true">
<include name="**/*.jar" />
</fileset>
<pathelement location="${classes.dir}" />
</path>
<target name="clean" description="清理旧文件">
<!--verbose=true 显示删除文件信息-->
<delete file="${app.dir}/${earName}.ear"/>
<delete file="${app.dir}/${warName}.war"/>
<delete dir="D:\VirtualE\FbWorkspace\GSCRMC"/>
<delete dir="${classes.dir}" />
<delete dir="${swf.dir}" />
</target>
<target name="prepare" depends="clean" description="创建classes文件夹" >
<mkdir dir="${classes.dir}" />
<mkdir dir="${swf.dir}" />
<mkdir dir="D:\VirtualE\FbWorkspace\GSCRMC"/>
</target>
<target name="compile" depends="prepare" description="编绎BL">
<javac includeantruntime="false" target="1.6" source="1.6" srcdir="${src.dir}" destdir="${classes.dir}" encoding="UTF-8" debug="on" deprecation="on" optimize="off" >
<classpath refid="build.classpath" />
<compilerarg value="-Xlint:unchecked"/>
</javac>
<copy todir="${classes.dir}">
<fileset dir="${src.dir}" >
<include name="**/*.xml" />
<include name="**/*.dtd" />
<include name="**/*.html" />
<include name="**/*.properties" />
</fileset>
</copy>
</target>
<!-- 定义FindBugs执行计划 -->
<target name="findbugs" depends="compile" description="FindBugs插件">
<findbugs home="${findbugs.home}" output="xml" outputFile="${app.dir}/findbugs.xml">
<auxClasspath>
<fileset dir="${webcontent.dir}/WEB-INF/lib">
<include name="*.jar" />
</fileset>
<fileset dir="${findbugs.home}/lib">
<include name="*.jar" />
</fileset>
</auxClasspath>
<sourcePath path="${src.dir}" />
<class location="${classes.dir}" />
</findbugs>
</target>
<!-- 定义checkstyle执行计划 -->
<!--
<target name="cs" description="CheckStyle插件">
指定检查规范为GS_java_check.xml(默认checkstyle_checks.xml)
fileset指的要检查的文件;formatter type指结果返回格式
<checkstyle failonviolation="false" config="${checkstyle.home}\checkstyle_checks.xml">
<fileset dir="${src.dir}" includes="**/*.java" />
<formatter type="plain" />
<formatter type="xml" toFile="${app.dir}/checkstyle_result.xml" />
</checkstyle>
</target>
-->
<!-- 调用FlashBuilderC命令行编译前台工程 -->
<target name="compileFlex" depends="findbugs" description="编绎PL">
<echo message="${basedir}/../GSCRMC" />
<copy todir="E:\FbWorkspace\GSCRMC">
<fileset dir="${basedir}/../GSCRMC"/>
</copy>
<exec executable="cmd" failοnerrοr="true">
<arg value="/c" />
<arg value="${fb.home}" />
<arg value="--launcher.suppressErrors" />
<arg value="-noSplash" />
<arg value="-application" />
<arg value="org.eclipse.ant.core.antRunner" />
<arg value="-data" />
<arg value="${fb.workspace}" />
<arg value="-file" />
<arg value="${fb.buildFile}" />
<arg value="main" />
</exec>
</target>
<target name="web-war" depends="compileFlex" description="创建WAR包">
<war destfile="${app.dir}/${warName}.war" webxml="${webcontent.dir}/WEB-INF/web.xml">
<fileset dir="${webcontent.dir}">
<!--include name="*.jsp"/-->
<!--exclude name="WEB-INF/web.xml"/-->
<!--exclude name="WEB-INF/lib/**"/-->
<exclude name="WEB-INF/lib/*jdt*"/>
</fileset>
</war>
</target>
<target name="ear" depends="web-war" description="创建EAR布包">
<!--ear destfile="${app.dir}/${earName}.ear" appxml="">
<fileset dir="${app.dir}">
<include name="${warName}.war"/>
</fileset>
</ear-->
<zip destfile="${app.dir}/${earName}.ear">
<fileset dir="${app.dir}">
<include name="${warName}.war"/>
</fileset>
</zip>
</target>
<target name="unzip-web-war" depends="ear" description="创建国信开发平台zip包">
<delete dir="${guosen-dev.dir}" />
<delete file="${ear.dir}.zip" />
<mkdir dir="${guosen-dev.dir}" />
<mkdir dir="${ear.dir}" />
<mkdir dir="${war.dir}" />
<unzip dest="${war.dir}">
<fileset dir="${app.dir}">
<include name="${warName}.war"/>
</fileset>
</unzip>
<zip destfile="${guosen-dev.dir}\${earName}.zip">
<fileset dir="${guosen-dev.dir}">
<include name="${earName}.ear/**" />
</fileset>
<fileset dir="${app.dir}">
<include name="changelog.txt" />
</fileset>
</zip>
</target>
<target name="stopJBoss" depends="unzip-web-war" description="停止JBOSS服务">
<exec executable="cmd" failοnerrοr="false">
<arg value="/c" />
<arg value="net" />
<arg value="stop" />
<arg value="JBAS61SVC" />
</exec>
</target>
<target name="deploy" depends="stopJBoss" description="Deploy ear包">
<delete file="${jboss.home}/server/${jboss.server.config}/deploy/${earName}.ear" />
<delete dir="${jboss.home}/server/${jboss.server.config}/deploy/${earName}.ear" />
<copy file="${app.dir}/${earName}.ear" todir="${jboss.home}/server/${jboss.server.config}/deploy" />
</target>
<target name="startJBoss" depends="deploy" description="开始JBOSS服务">
<exec executable="cmd" failοnerrοr="false">
<arg value="/c" />
<arg value="net" />
<arg value="start" />
<arg value="JBAS61SVC" />
</exec>
</target>
</project>
五、FlEX工程编译的注意点(只需做一次就可以)
在架设hudson的服务器上安装FlashBuilder并且引入当前需要编译flex工程
创建flex工程编译xml在FlashBuilder的工作空间下面创建编译前台工程的ant编译xml文件
<?xml version="1.0"?>
<project default="main">
<target name="main">
<fb.exportReleaseBuild project="GSCRMC" destdir="D:\hudsonhome\jobs\GSCRM\workspace\GSCRM\WebContent\clientd"/>
</target>
</project>
注:在上面的build.xml文件里面会指定这个文件,请查看fb.buildFile配置设置
由于flex编译的时候会和后台对应工程关联,具体表现是会解析后台services-config.xml文件
所以要按照前台工程的设定,拷贝相应的后台工程放到指定的后台eclipse空间中