Hudson:持续集成服务器的介绍http://blog.csdn.net/heihuifeng/article/details/7258467
2013-09-13 09:47
477 查看
资料参考
hudson官网hudson wiki网站
插件介绍
转自:/article/11444234.html
介绍
什么是持续集成(Continuous Integration)
持续集成(CI)是一种实践,旨在缓和和稳固软件的构建过程。在整个软件开发生命周期内,它主要用于保证代码质量,确保尽早遇到问题(如代码缺陷),避免问题在软件开发周期晚期变复杂时才被发现。CI的作用主要有如下几个方面:软件构建自动化。
构建可持续的自动化检查。
构建可持续的自动化测试。
生成后后续过程的自动化。
组件
实现CI的上述功能,需要三个组件:用 Ant 或 Maven 等工具建立的自动构建过程。
一个代码存储库,比如 CVS 或 Subversion。
一个 CI 服务器,比如 Hudson。
hudson介绍
Hudson 是一种革命性的开放源码 CI 服务器,它从以前的 CI服务器吸取了许多经验教训。Hudson最吸引人的特性之一是它很容易配置:很难找到更容易设置的 CI 服务器,也很难找到开箱即用特性如此丰富的CI 服务器。Hudson 容易使用的第二个原因是它具有强大的插件框架 ,所以很容易添加特性。例如,一个 Hudson 插件可以随时间的推移跟踪FindBugs和代码覆盖。它还可以报告测试结果的趋势(来自 JUnit 或TestNG? )以及构建结果和对应的执行时间。有人调查过,Hudson是目前使用最多的CI服务器。
工作原理
CI系统的基本结构图
构建过程
触发构建--手动、代码更新、定制时间。更新代码--Svn、Git、CVS。
构建--执行 Shell、执行 Windows 批处理、使用Ant、使用Maven。
安装
安装sun-java6-jdk,设置环境变量JAVA_HOME安装tomcat6
安装 ant (optional)
在hudson官网下载hudson.war,放到tomcat/webapps下。访问http://localhost:8080/hudson,进入hudson的启动页面。注:使用sudo apt-get install tomcat6时,将hudson.war放在/var/lib/tomcat6/webapps目录下。
默认在/usr/share/tomcat6/.hudson下建立hudson的主目录。注意权限问题。
通用配置
系统管理
打开系统管理-系统设置,进行配置。主目录:这个目录用来保存所有的配置信息和数据。默认是当前用户目录下的.hudson。也可创建一个空目录,并将这个目录路径赋给环境变量 hudson/WEB-INF/web.xml中的HUDSON_HOME,重启hudson。
JDK:设置JDK的路径,默认是自动安装的,如果你的电脑安装过JDK那就将自动安装复选框勾掉,填写JAVA_HOME的路径即可。
Ant:设置Ant的路径ANT_HOME。
Android Emulator:针对Android项目,设置 SDK安装路径。
Xvnc-Command line:设置vncserver启动路径及参数。如:/usr/bin/vncserver :99 -geometry 800x600。
Xvnc-Base display number:设置桌面显示号的基数。如:99.
打开系统管理-管理插件,可安装插件。hudson默认的插件保存目录为:HUDSON_HOME/plugins,所以也可以直接将插件拷贝到该目录下,重启hudson即可。
HUDSON_HOME目录结构
[python] view plaincopyHUDSON_HOME |-------config.xml (hudson基础配置) |-------*.xml (其他站点范围内的配置文件) |-------userContent (此目录中的文件将被送达您的http://server/hudson/userContent/。) |-------fingerprints (存储指纹记录,关于fingerprints请查阅文件指纹识别) |-------plugins (存储插件集) |-------jobs(构建任务总目录) |-------[JOBNAME] (为每个作业定义一个子目录) |-------config.xml (作业配置文件) |-------workspace (为版本控制系统而工作的目录) |-------lastSuccessful (这个符号关联到最近的成功构建。) |-------builds
用户配置
选中系统设置-启用安全 ,进行用户配置JNLP节点代理的TCP端口选项中选择“Disable”。
访问控制-安全域
选择“Hudson专有用户数据库”:使用Hudson自己的用户列表验证, 而不是外部系统代理. 这适用于没有用户数据库小范围的设定. 建立的用户配置信息保存在HUDSON_HOUME/users下。
允许用户注册:如果勾选上,则表示允许用户自己注册一个新账号,通过点击页面右上角的注册链接进行操作。取消这个选框表示禁止任意注册新账号。 当这个选框被取消,就必须使用系统管理员来创建账号。
授权策略-安全矩阵
需要先注册一个admin用户(与角色名称相同),赋予全部的权限以便检验,否则我们将无法管理hudson。
默认会有一个匿名用户角色,表示未登录用户的访问权限,你可以不授权或只授予read权限。
添加用户/组:输入一个名称,然后点击添加,这里实际上是先建立一个角色,因为这时用户并不存在。然后注册一个相同名字的用户。
授权策略-项目矩阵授权策略
这个授权模型扩展自"安全矩阵",允许把下面的ACL(访问控制列表)矩阵附加到每个项目定义中(在Job配置页面). 就是说,除了可以在这里进行全局授权外,还可以在JOB中进行配置。
任务设置-启用项目安全:这里只能对当前的JOb进行授权配置,同样的,这里也是创建角色,用户需要自己注册或管理员进行创建。如果“系统设置”与“JOB设置”中存在相同的角色,则权限取并集。
反设置
有时候会出现这样的情况,就是虽然创建了角色,但是没有勾选上“允许用户注册”,这时就无法控制hudson了,这时可以通过如下修改,开启“允许用户注册”。
在$HUDSON_HOME环境变量对应的文件夹下config.xml,修改true 元素为false。重启hudson,这时候的Hudson又回归到无认证模式,任何人都能拥有该系统的全部权限。
创建构建任务
配置JOB_WORKSPACE
构建时使用的目录,也就是从代码仓库中取得的代码所要保存的路径,默认路径为:HUDSON_HOME/jobs/$jobname/workspacejob的配置中,所有涉及到路径的配置,都是基于JOB_WORKSPACE基础上的,配置时都是使用相对路径,也就是从这个路径开始计算。
可以在job设置中修改这个路径,找到Advanced Project Options,点击“Advanced”,勾选Use custom workspace,并设置一个绝对路径,比如/usr/local/hudson/jobname/workspace,保存。
ngux构建:svn+cppcheck+gtest
注:需要安装hudson的svn插件、cppcheck插件。新建任务
Source Code Management:设置项目的源码获取方式Subversion地址
[python] view plaincopysvn+ssh://hjhei@192.168.1.4/home/projects/svn/ngux/trunk@HEAD
Build Triggers:设置构建的触发器
Poll SCM:指定一个定时作业表达式来定义Hudson每隔多久检查一下您源代码仓库的变化。如果发现变化,就执行一次构建。
Build periodically:选项支持类似crontab格式的任务周期定制。* * * * *对应分钟,小时,月份相应的日期,月份,星期
Build:添加指令以执行构建脚本,这里添加的是shell脚本
执行cppcheck的脚本,并在ngux的目录下生成cppcheck-result.xml测试报告。
[python] view plaincopycd ./ngux cppcheck --enable=all -q --xml . 2>cppcheck-result.xml
编译执行gtest测试用例的脚本,在ngux/unittest/reports目录下生成每个类对应的xml测试报告。
[python] view plaincopycd ./ngux make clean make -j3 cd .unittest/ ./run_gtest.sh
run_gtest.sh文件内容
[python] view plaincopy#!/bin/bash TEST_ITEMS=(textviewtest imageviewtest gridviewtest pageviewtest pagenavigateviewtest panelviewtest boxlayoutviewtest pairlayoutviewtest buttonviewtest linelayoutviewtest scrollviewtest menuviewtest itemviewtest listviewtest listviewlooptest trackbarviewtest) [ -e reports/ ] || mkdir reports for item in ${TEST_ITEMS[*]} do ./$item --gtest_output=xml:$item.xml if [ -f $item.xml ]; then mv $item.xml reports/ else echo "====================build $item failed====================" continue fi done
Post-build Actions:构建完成后需要进行的处理
Publish JUnit test result report:如果构建脚本执行了JUnit测试,此选项将指示Hudson处理XML测试文档并为每次连续构建产生一份可持续的报告,依据正在进行的测试汇总处理结果。其结果是当前工作主页的一份报告,作业中的单元测试会随着时间的推移按由老至新进行陈列。
[python] view plaincopyngux/unittest/reports/*.xml
Publish Cppcheck results:发布cppcheck测试报告,同JUnit。
[python] view plaincopy**/cppcheck-result.xml
E-mail Notification:当选择此选项,可以输入一个或多个电子邮件地址[多个可用空格分隔],当Hudson完成了执行作业后,将会给它们发送通知。事件触发时将产生一份 Email,包括构建失败、构建不稳定等。这儿有一个额外的选项,当由于用户的错误提交造成Hudson决定废弃此次构建,将会发送一份专门的邮件给这位 SCM提交者,以便让他检查源代码。注:如果集成了gtest,测试用例不通过,会构建失败。
Espier构建:svn+Ant+Findbugs
注:需要安装ant、Findbugs插件、Static Analysis Collector结果分析插件、Android Emulator模拟器插件、Xvnc插件。新建任务
Source Code Management:设置项目的源码获取方式Subversion地址
[python] view plaincopysvn+ssh://hjhei@192.168.1.4/home/projects/svn/espier/branches/nowebcore/Espier@HEAD
Build Triggers:设置构建的触发器
Build Environment:
勾选Run Xvnc during build。
勾选Run an Android emulator during build,并设置模拟器的属性。
Common emulator options:勾选显示模拟器窗口。
Build:添加指令以执行构建脚本,这里使用的是Ant-build.xml。
Invoke Ant-Targets
[python] view plaincopyclean all findbugs
build.xml内容
[python] view plaincopy<?xml version="1.0" encoding="UTF-8"?> <project name="Espier" default="all" basedir="."> <property environment="env"></property> <property name="android_sdk_path" value="/opt/android-sdk-linux_x86"/> <property name="android_api_level" value="10"/> <property name="android_platform" value="${android_sdk_path}/platforms/android-${android_api_level}"/> <property name="android_jar" value="${android_platform}/android.jar"/> <property name="refjars" value="jars/common.jar:jars/framework.jar:jars/core.jar:jars/layout.jar:jars/fmsoft_guava.jar"/> <property name="classpath" value="${refjars}:${android_jar}"/> <property name="debug_keystore" value="/home/heihuijing/.android/debug.keystore"/> <property name="espier_package" value="com.fmsoft.espier"/> <target name="all" depends="Step7_jarsign"/> <target name="Step0_updateVersion"> <echo message="Update Version in AndroidManifest.xml ..."/> <exec executable="bash"> <arg line="build_version.sh"/> </exec> </target> <target name="Step1_genR" depends="Step0_updateVersion"> <echo message="Generate R.java ..."/> <mkdir dir="gen"/> <exec executable="${android_sdk_path}/platform-tools/aapt"> <arg line="package -f --auto-add-overlay -m -J gen -S res -A assets -M AndroidManifest.xml -I ${android_jar}"/> </exec> </target> <target name="Step2_aidl" depends="Step1_genR"> <echo message="Preprocess aidl ..."/> </target> <target name="Step3_compile_java" depends="Step2_aidl"> <echo message="Compile all java files ..."/> <mkdir dir="bin"/> <javac srcdir="gen:application:quicksearchbox" destdir="bin" classpath="${classpath}" debug="true" debuglevel="lines,vars,source"/> </target> <target name="Step4_dx" depends="Step3_compile_java"> <echo message="Package all classes to classes.dex ..."/> <java jar="${android_sdk_path}/platform-tools/lib/dx.jar" args="--dex --output=bin/classes.dex bin" fork="true"/> </target> <target name="Step5_compile_res" depends="Step4_dx"> <echo message="Compile all resource files ..."/> <exec executable="${android_sdk_path}/platform-tools/aapt"> <arg line="package -f -M AndroidManifest.xml -S res -A assets -F bin/ResClass -I ${android_jar}"/> </exec> </target> <target name="Step6_apkbuild" depends="Step5_compile_res"> <echo message="Build apk ..."/> <exec executable="${android_sdk_path}/tools/apkbuilder"> <arg line="bin/${ant.project.name}.apk -u -z bin/ResClass -f bin/classes.dex"/> </exec> </target> <target name="Step7_jarsign" depends="Step6_apkbuild"> <echo message="Sign the apk ..."/> <exec executable="jarsigner"> <arg line="-keystore ${debug_keystore}"/> <arg line="-keypass android -storepass android"/> <arg line="bin/${ant.project.name}.apk androiddebugkey"/> </exec> </target> <!--clean target--> <target name="clean"> <delete dir="bin"/> <delete dir="gen"/> </target> <!--findbugs target--> <taskdef name="findbugs" classname="edu.umd.cs.findbugs.anttask.FindBugsTask"/> <property name="findbugs.home" value="/home/heihuijing/tool/findbugs-1.3.9" /> <path id="findbugs.path"> <fileset dir="/home/heihuijing/findbugs-1.3.9"> <include name="**/*.jar" /> </fileset> </path> <target name="findbugs"> <findbugs home="${findbugs.home}" output="xml" outputfile="findbugs.xml"> <!--auxClasspath path="${findbugs.home}/lib/Regex.jar" /--> <sourcePath path="gen:application:quicksearchbox" /> <class location="${basedir}/bin" /> </findbugs> </target> </project>
Post-build Actions:构建完成后需要进行的处理
Publish FindBugs? analysis
results :发布FindBugs测试报告,同Junit。
Build other projects:任务完成后,可触发其他任务构建。如:espiertest。espier任务完成后,触发espiertest构建。
EspierTest? 构建:svn+Ant+JUnit
新建任务Source Code Management:设置项目的源码获取方式Subversion地址
[python] view plaincopysvn+ssh://hjhei@192.168.1.4/home/projects/svn/espier/branches/nowebcore/EspierTest@HEAD
Build Triggers:设置构建的触发器。如设置Build after other projects are built为espier,在espier构建完成后开始该任务的构建。
Build Environment:
勾选Run Xvnc during build。
勾选Run an Android emulator during build,并设置模拟器的属性。
Common emulator options:勾选显示模拟器窗口。
Build:添加指令以执行构建脚本,这里使用的是Ant-build.xml。
Invoke Ant-Targets
[python] view plaincopyuninstall reinstall run-test
build.xml内容
[python] view plaincopy<?xml version="1.0" encoding="UTF-8"?> <project name="EspierTest" default="Step7_jarsign" basedir="."> <property environment="env"></property> <property name="android_sdk_path" value="/opt/android-sdk-linux_x86"/> <property name="android_api_level" value="10"/> <property name="android_platform" value="${android_sdk_path}/platforms/android-${android_api_level}"/> <property name="android_jar" value="${android_platform}/android.jar"/> <property name="tested_project" value="/home/heihuijing/fm/android-espier/Espier"/> <property name="targetPackage" value="mobi.espier.browser"/> <!-- <property name="refjars" value="jars/common.jar:jars/framework.jar:jars/core.jar:jars/layout.jar:jars/fmsoft_guava.jar"/> --> <!-- <property name="classpath" value="${refjars}:${android_jar}"/> --> <property name="adb" value="${android_sdk_path}/platform-tools/adb"/> <property name="classpath" value="${tested_project}/bin:${android_jar}"/> <property name="debug_keystore" value="/home/heihuijing/.android/debug.keystore"/> <property name="espiertest_package" value="mobi.espier.browser.test"/> <target name="Step1_genR" > <echo message="Generate R.java ..."/> <exec executable="${android_sdk_path}/platform-tools/aapt"> <arg line="package -f --auto-add-overlay -m -J gen -S res -A assets -M AndroidManifest.xml -I ${android_jar}"/> </exec> </target> <target name="Step2_aidl" depends="Step1_genR"> <echo message="Preprocess aidl ..."/> </target> <target name="Step3_compile_java" depends="Step2_aidl"> <echo message="Compile all java files ..."/> <javac srcdir="gen:src" destdir="bin" classpath="${classpath}" debug="true" debuglevel="lines,vars,source" encoding="UTF-8" includeantruntime="false"> <classpath> <fileset dir="${tested_project}/jars" includes="*.jar" /> <!-- <fileset dir="libs" includes="*.jar" /> --> </classpath> </javac> </target> <target name="Step4_dx" depends="Step3_compile_java"> <echo message="Package all classes to classes.dex ..."/> <java jar="${android_sdk_path}/platform-tools/lib/dx.jar" fork="true"> <arg line="--dex --output=bin/classes.dex bin"/> </java> </target> <target name="Step5_compile_res" depends="Step4_dx"> <echo message="Compile all resource files ..."/> <exec executable="${android_sdk_path}/platform-tools/aapt"> <arg line="package -f -M AndroidManifest.xml -S res -A assets -F bin/ResClass -I ${android_jar}"/> </exec> </target> <target name="Step6_apkbuild" depends="Step5_compile_res"> <echo message="Build apk ..."/> <exec executable="${android_sdk_path}/tools/apkbuilder"> <arg line="bin/${ant.project.name}.apk -u -z bin/ResClass -f bin/classes.dex"/> </exec> </target> <target name="Step7_jarsign" depends="Step6_apkbuild"> <echo message="Sign the apk ..."/> <exec executable="jarsigner"> <arg line="-keystore ${debug_keystore}"/> <arg line="-keypass android -storepass android"/> <arg line="bin/${ant.project.name}.apk androiddebugkey"/> </exec> </target> <!--clean testproject target--> <target name="clean"> <delete includeEmptyDirs="true"> <fileset dir="bin"/> <fileset dir="gen"/> </delete> </target> <!--install-test-apk to emulator--> <target name="install" depends="Step7_jarsign" description="Install android-test project."> <exec executable="${adb}"> <arg line="install bin/${ant.project.name}.apk"/> </exec> </target> <!--reinstall-test-apk to emulator--> <target name="reinstall" depends="clean, Step7_jarsign" description="ReInstall android-test project."> <exec executable="${adb}"> <arg line="install -r bin/${ant.project.name}.apk"/> </exec> </target> <!--uninstall-test-apk from emulator--> <target name="uninstall" description="Uninstall android-test project"> <exec executable="${adb}"> <arg line="uninstall ${espiertest_package}"/> </exec> </target> <!--run-test--> <target name="run-test" description="run test project"> <property name="reports.dir" value="reports"/> <property name="files.dir" value="/data/data/${targetPackage}/files"/> <!-- <property name="test.runner" value="com.zutubi.android.junitreport.JUnitReportTestRunner"/> --> <property name="test.runner" value="mobi.espier.browser.test.XMLInstrumentationTestRunner"/> <echo>Cleaning up previous test reports...</echo> <exec executable="${adb}" failonerror="true"> <!-- <arg line="${adb.device.arg}" /> --> <arg value="shell" /> <arg value="rm" /> <arg value="${files.dir}/*" /> </exec> <echo>Running tests...</echo> <exec executable="${adb}" failonerror="true"> <!-- <arg line="${adb.device.arg}"/> --> <arg value="shell" /> <arg value="am" /> <arg value="instrument" /> <arg value="-w" /> <arg value="-e" /> <arg value="outfile" /> <arg value="test-results.xml" /> <!-- <arg value="-e" /> --> <!-- <arg value="multiFile" /> --> <!-- <arg value="true" /> --> <arg value="${espiertest_package}/${test.runner}" /> </exec> <echo>Downloading XML test reports...</echo> <exec executable="${adb}" failonerror="true"> <!-- <arg line="${adb.device.arg}"/> --> <arg value="pull" /> <arg value="${files.dir}" /> <arg value="${reports.dir}" /> </exec> </target> </project>
Post-build Actions:构建完成后需要进行的处理
Publish JUnit test result report:发布JUnit测试报告。
[python] view plaincopyespiertest/reports/*.xml
相关文章推荐
- Hudson:持续集成服务器工具介绍
- 持续集成篇 --Hudson持续集成服务器的安装配置与使用
- Hudson 持续集成服务器的安装配置与使用
- 持续集成篇 --Hudson持续集成服务器的安装配置与使用
- 持续集成篇_08_Hudson持续集成服务器的使用(自动化编译、分析、打包、部署)
- 持续集成篇_08_Hudson持续集成服务器的使用(远程自动化部署)
- Hudson 持续集成服务器的安装配置与使用
- 持续集成篇_07_Hudson持续集成服务器的安装与配置
- Hudson持续集成服务器软件
- Hudson 持续集成服务器的安装配置与使用
- 基于hudson搭建持续集成服务器
- 持续集成引擎Hudson介绍及下载
- Hudson 持续集成服务器的安装配置与使用
- 持续集成篇_08_Hudson持续集成服务器的使用(自动化编译、分析、打包、部署)
- Hudson持续集成服务器(windows篇)
- Dubbo实战教程--Hudson持续集成服务器的安装配置与使用
- Hudson之——持续集成服务器的安装与配置
- Hudson持续集成服务器的安装配置与使用
- Hudson配置个人持续集成服务器