CruiseControl
1 CruiseControl概述
1.1 什么是CruiseControl
CruiseControl(以下简称cc)是一个持续集成的框架,它包括邮件通知,ant和其他源码控制工具等插件。cc的web接口可以提供浏览项目当前和之前的构建情况的界面。
1.2 什么是持续集成
持续集成最先由Martin Fowler和Matthew Foemmel提出。软件获得成功的构建在程序开发中是重要的部分。不管它是否重要,我们经常会感到惊讶:我们的程序不能正常工作。我们需要一个完成自动的和可以重用的构建,包括可以一天运行很多遍的测试。这些可以让每个程序员每天开发的东西成为整体,因而可以减少整体问题。
1.3 持续集成组成部分
1.4 持续构建
cc的核心部分,不停的构建,通知用户并可以使用各种的发布方法。
1.5 构建报告
可以生成项目构建报告,允许用户以浏览器的方式进行访问构建结果。
1.6 cc Dashboard
可以让你直观的看到项目的状态。
2 搭建cc服务器
2.1 下载
我们可以从下面的地址得到cc:
http://sourceforge.net/project/showfiles.php?group_id=23523&package_id=16338
本文使用的版本为2.8
2.2 打开cc服务器
我们下载了cruisecontrol-bin-2.8后,运cruisecontrol-bin-2.8目录下的cruisecontrol.bat文件,再访问http://localhost:8080,因为cc内置了jetty,因此我们可以直接访问。可以看下以下画面:
点击第三行的连接,可以看到cc内置的一个项目。
现在,我们的cc服务器已经准备完成了。
注:下载的cruisecontrol-bin-2.8可放在任意目录,但不得放在有中文的目录。否则会有如下错误:
CruiseControl home is not set or could not be located.
3 构建自己的项目
下面,我们以maven2为例进行持续集成。使用svn作为版本控制工具,svn服务器搭建可参见另外一篇文章: SVN服务器搭建http://www.crazyit.org/thread-2280-1-1.html
3.1 新建一个maven2项目
略。可参看maven2的相关文档。
注:建maven2项目的时候尽量避免在eclipse的workspace下,因为怕发生混乱,因为本文中,cc服务器,svn服务器,程序员开发机器均为同一台机器。
pom.xml内容如下:
复制内容到剪贴板
代码:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.angus</groupId>
<artifactId>test-svn</artifactId>
<version>0.0.1-SNAPSHOT</version>
</project>
3.2 将maven2项目导进svn
具体请看: SVN服务器搭建http://www.crazyit.org/thread-2280-1-1.html
3.3 将maven2项目checkout进cc
现在,我们将已经放进svn服务器的maven2项目放进我们的cc服务器。
进入cruisecontrol-bin-2.8/projects目录,新建一个项目名的目录,因为我们上面建的项目为test-svn,因此我们在cruisecontrol-bin-2.8/projects下新建一个test-svn的目录。
以下为projects目录和test-svn的目录:
但是,这样cc并不知道该项目需要构建和需要怎样构建,我们需要修改cruisecontrol-bin-2.8目录下的config.xml文件。
config.xml配置如下:
复制内容到剪贴板
代码:
<cruisecontrol>
<project name="test-svn">
<listeners>
<currentbuildstatuslistener file="logs/${project.name}/status.txt"/>
</listeners>
<bootstrappers>
<svnbootstrapper localWorkingCopy="projects/${project.name}" />
</bootstrappers>
<modificationset quietperiod="30">
<!-- touch any file in connectfour project to trigger a build -->
<svn localWorkingCopy="projects/${project.name}"/>
</modificationset>
<schedule interval="300">
<maven2 mvnscript="D:/apache-maven-2.0.9/bin/mvn.bat"
pomfile="projects/${project.name}/pom.xml"
goal="clean package"/>
</schedule>
<log>
<merge dir="projects/${project.name}/target/surefire-reports"/>
</log>
<publishers>
<onsuccess>
<artifactspublisher dest="artifacts/${project.name}" file="projects/${project.name}/target/${project.name}.jar"/>
</onsuccess>
</publishers>
</project>
</cruisecontrol>
需要注意的元素说明:
复制内容到剪贴板
代码:
svnbootstrapper:指定从svn checkout出来的项目在cc中的位置。
modificationset quietperiod:指定项目的变更轮询的时间间隔,默认为30秒,即30秒cc检查一次项目是否有更新。
schedule interval:指执行构建的时间间隔,默认为300秒,即300进行一次构建。但默认情况下,如果项目没有新的变化,那么是不会进行构建的。
maven2:
mvnscript:mvn.bat所在位置
pomfile:需要执行构建的pom.xml所在位置,即项目的pom.xml所在位置。
goal:构建的目标,具体请参看maven2的生命周期。
log merge:项目是否发生变更的标准。cc会检查该目录是否发生变化而判断是否进行构建。
artifactspublisher:
dest:运行的项目。
file:运行项目的文件,jar,war等。
3.4 构建异常
注:当我们在构建的时候,会出现以下异常:
复制内容到剪贴板
代码:
[cc]三月-01 21:31:03 Project
- exception publishing results with net.sourc
eforge.cruisecontrol.publishers.OnSuccessPublisher for project test-svn
net.sourceforge.cruisecontrol.CruiseControlException: target file D:/cruisecontr
ol-bin-2.8/projects/test-svn/target/test-svn.jar does not exist
原因是找不到我们所打的jar包,因此,我们可以在pom.xml中定义打包规则,因为我们用maven打成的包是带版本的,因此可以定义打包规则,将版本号去掉。在pom.xml中加入如下配置即可:
复制内容到剪贴板
代码:
<build>
<finalName>test-svn</finalName>
</build>
接下来,开启我们的cc服务器(运行cruisecontrol.bat)
打开浏览器:http://localhost:8080,点击/cruisecontrol
看到如下界面:
为了测试我们的项目是否会构建,我们可以在项目中写测试代码。
先在eclipse中checkout test-svn项目。注:可以使用subeclipse插件。
在项目中新建一个单元测试,代码如下:
复制内容到剪贴板
代码:
public class FirstTest {
@Before
public void setUp() {
}
@After
public void tearDown() {
}
@Test
public void testCI() {
System.out.println("###################");
System.out.println("###################");
System.out.println("###################");
System.out.println("###################");
System.out.println("MY TEST");
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
System.out.println("构建时间: " + sdf.format(date));
}
}
简单的打印代码,我们直接提交代码。
我们再去看我们的cc服务器,可以选等上5分钟让它自己进行构建,也可以在
http://localhost:8080/cruisecontrol/中点击build按钮进行手动构建。
等它构建完后,我们点击test-svn进去查看test-svn的构建情况,如下图:
这样,我们的cc总算搭建完成了。
4 发送邮件
4.1 配置
上面的cc已经搭建成功了,但是,为了让开发者或者项目的其他角色能尽快了解项目构建的情况,在构建完成后,可以向项目参与人发送邮件。
在上面的基础上,修改config.xml,代码如下:
复制内容到剪贴板
代码:
<publishers>
<onsuccess>
<artifactspublisher dest="${artifactdir}/${project.name}"
file="${checkoutdir}/${project.name}/target/${project.name}.jar"/>
</onsuccess>
<email mailhost="smtp.163.com" username="iloveshasha86" password="yourpassword" returnaddress="iloveshasha86@163.com" skipusers="false" subjectprefix="[CruiseControl]" buildresultsurl="http://localhost:8080/cruisecontrol/buildresults/${project.name}">
<always address="yangenxiong@163.com"/>
<always address="vincyen@163.com"/>
</email>
</publishers>
4.2 元素说明
我们向publishers元素中加了一个email元素,主要元素及属性描述如下:
主要或者常用属性描述:
复制内容到剪贴板
代码:
mailhost:host of your email.
username:发送人的用户名。
password:发送人邮箱密码。
returnaddress:发送人的邮箱地址。
subjectprefix:邮件主题前缀。
buildresultsurl:构建结果的地址。
主要或者常用子元素描述:
复制内容到剪贴板
代码:
always:无论构建结果如何,都会向address发送邮件。
success:构建成功才会向address发送邮件。
failure:构建失败时才会向address发送邮件,如果构建结果为fixed,reportWhenFixed属性为true的时候,会发送,如果为false,则不会发送。
还有子元素mavenmapper,可以向在pom.xml中定义的developer发送。具体请查看maven2文档。
4.3 邮件结果
重新将项目构建一次,构建成功后,进入我们的邮箱,可以看到如下结果:
5 意见
就像文章开头说的那样:我们需要一个完成自动的和可以重用的构建,包括可以一天运行很多遍的测试。
持续集成究竟集成些什么呢?仅仅是普通的编译或者打包吗?其实真正的意义在于测试,不停的运行测试并发现问题。因此,测试才是持续集成的核心,哦,说错了,应该是完善的测试,测试覆盖率起码达到90%以上的代码(业务代码)。没有测试去搞cc,意义并不是很大。
SVN服务器搭建
1 SVN简介
SVN是现在流行的一个版本控制系统,可以超越时间的管理文件和目录。文件保存在中央版本库,除了能记住文件和目录的每次修改外,版本库非常像普通的文件服务器。你可以将文件恢复到过去的版本,并且可以通过检查历史知道数据做了哪些修改,谁做的修改。
2 SVN优势
2.1 目录版本控制
CVS只能追踪单个文件的历史,但是ubversion实现了一个“虚拟”文件系统,可以追踪整个目录树的修改,文件和目录都是版本控制的,结果就是可以在客户端文件和目录执行和目录执行移动和复制命令。
2.2 原子提交
提交要么完全进入版本库,要么一点都没有,这允许开发者以一个逻辑块提交修改。
2.3 版本控制的元数据
每个文件和目录都有一组附加的“属性”,你可以发明和保存任意的键/值对,属性是版本控制的,就像文件内容。
2.4 可选的网络层
Subversion在版本库访问方面有一个抽象概念,利于人们去实现新的网络机制,Subversion的“高级”服务器是Apache网络服务器的一个模块,使用HTTP的变种协议WebDAV/DeltaV通讯,这给了Subversion在稳定性和交互性方面很大的好处,可以直接使用服务器的特性,例如认证、授权、传输压缩和版本库浏览等等。也有一个轻型的,单独运行的Subversion服务器,这个服务器使用自己的协议,可以轻松的用SSH封闭。
2.5 高效的分支和标签
分支与标签的代价不与工程的大小成比例,Subversion建立分权与标签只是复制项目,使用了一种类似于硬链接的机制,因而这类操作通常只会花费很少并且相对固定的时间,以及很小的版本库空间。
2.6 良好的维护能力
Subversion没有历史负担,它由一系列良好的共享C库实现,具有定义良好的API,这使Subversion非常容易维护,可以轻易的被其他语言和程序使用。
注:以上来源于《TortoiesSVN Windows下的一种Subversion客户端》。
3 安装Subversion
先从http://subversion.tigris.org/ 中下载最新版本的SVN服务器,本文使用的版本为1.5.3。
3.1 设置环境变量
安装好SVN服务器后,设置环境变量:
复制内容到剪贴板
代码:
PATH : C:/Program Files/Subversion/bin
也就是安装SVN服务器目录的下的bin目录。
在命令行下输入svn help,可以看到SVN的帮助信息。证明你的SVN服务器端已经安装好的。
3.1.1 创建你自己的SVN库
在你的操作系统中,随便新建一个目录,用于存放Subversion的库,这个库主要是存放你需要用版本控制的所有项目。当然,你也可以创建多个库用于存放多个项目,主要看具体情况。例如:E:/svnSpace
4 建立第一个SVN项目
本文测试的项目名字叫做test-svn,因此,在命令行中输入命令:
复制内容到剪贴板
代码:
svnadmin create E:/svnSpace/test-svn
其中,E:/svnSpace为你库的目录,test-svn为你的项目名称。
这样,你就建立了一个svn项目了。到E:/svnSpace/test-svn目录下,我们会发现svn帮我建立的一些相关文件。
4.1 设置用户信息及权限
4.1.1 权限
以上面新建的项目为例,到E:/svnSpace/test-svn/conf目录下,打开svnserve.conf文件,修改下面的一些配置信息:
复制内容到剪贴板
代码:
[general]
anon-access = read
auth-access = write
以上两个选择控制通过验证和未通过验证的用户是否有权使用这个项目的库,上面两个配置为默认配置。
复制内容到剪贴板
代码:
password-db = passwd
上面的选项为库指向配置用户和密码的文件。默认为passwd,即与svnserve.conf在同一目录下的passwd文件。
复制内容到剪贴板
代码:
realm = test-svn
上面的选项指定用户在库中的权限范围,如果两个库有同样的权限范围,那么可以使用同一份passwd文件,默认值为项目的名称。
4.1.2 用户与密码
修改用户和密码,我们打开E:/svnSpace/test-svn/conf 目录下的passwd文件:
复制内容到剪贴板
代码:
[users]
admin = yangenxiong
yangenxiong = yangenxiong
设定了两个有权限读取并写入svn库的两个用户及密码。
5 导入项目
5.1 启动服务器
准备工作做完后,我们启动svn服务器:
在命令行中输入:
复制内容到剪贴板
代码:
svnserve -d -r E:/svnSpace
命令窗口处于等待,表明我们的svn服务器已经启动。
5.2 导入项目
刚刚新建的test-svn项目,我们现在随便找个地方新建一个项目,例如:新建一个F:/test-svn的目录。
我们再打开一个命令窗口,输入命令:
复制内容到剪贴板
代码:
svn import F:/test-svn svn://localhost/test-svn -m "initialimport"
按提示输入密码与用户后,我们的项目已经进入版本控制了。
在任意目录进行checkout,即可以将项目下载。
注:可以使用svn的客户端工具进行checkout。