东儿童
爱拼才会赢

我们经常在项目开发和维护过程中遇到这样的问题:在开发周期后期快结束验收时才发现了设计缺陷或流程错误;要花大量时间精力时间进行单元测试;忙中出错会将错误的版本发布到线上;花了大量的时间在项目布署上,甚至在多台服务器上的同步部署更是费时费力。现在这些问题其实都可以借助持续集成(Continuous Integration)平台得到解决。通俗一点说,持续集成平台就是对于开发人员的每一次代码提交(到SVN),都会自动地把版本库中的所有代码 check out到另一个代码副本目录,并且自动在这个代码副本中运行所指定的测试用例(Test Case),如果所有单元测试全部通过则接受这次提交,并将代码复制到Web目录,这个Web目录一般是测试环境;否则持续集成平台会通知到所有开发人员,当前版本是一个有错误的版本。

为了方便项目的开发维护,本人也构建了一个PHP环境的持续集成平台供PHP项目组使用。平台采用现在主流的Xinc+phing+phpunit+svn等开源软件构建,现在的项目开发都是基于这个平台进行的,现将构建部署经验分享出来,方便大家。在构建之前先了解一下利用Xinc+phing+phpunit+svn构建持续集成平台的工作流程,这个时候该有张图了,请看:


再上几个xinc的web管理查看界面:










我们了解了工作原理之后接着会是介绍安装这4个开源工具。在此感谢伟大的开源精神,这么好的东西,还不要钱。哎,这世道算是让我们赶上了。像phpunit和svn在linux上的安装很常见,我就不废话了。(phpunit安装请参考 phpunit3安装试用小记 svn安装请参考 单独安装配置subversion(svn)说明)这里主要是介绍一下xinc和phing的安装。

xinc的安装和配置:

安装步骤请参考: xinc的安装和配置

安装好后请创建配置文件(创建位置上文已注明),我的项目文件:

<?xml version="1.0"?>
<xinc>
<project
name="Dnbiz">
<schedule
interval="10"/>
<modificationset>
<svn
directory="/data0/htdocs/projects/coderbolg/"
/>
</modificationset>
<builders>
<phingBuilder
buildfile="/data0/htdocs/projects/coderbolg/build/build.xml"
target="test"
/>
</builders>
<publishers>
<artifactspublisher
file="/data0/htdocs/projects/coderbolg/reports"/>
</publishers>
</project>
</xinc>充分的解释一下这文件先,这个文件是重点啊。 
name 设置当前项目的名称
schedule 设置了每过多久监控SVN变化(秒) 
svn 指定一个副本目录,xinc会在监听到SVN版本库的变化后将代码签出到这个副本目录
phingBuilder 这是phing的配置文件,在副本目录下,phing是来部署项目的,等一下再说
artifactspublisher 指定了单元测试和代码覆盖率等的生成报告存放位置。xinc的web页面会读取这些文件并显示出来

配置好就放在这里好了,等我们打通了phing的脉络后再启动xinc在这个脉络上顺畅的运行。

phing的安装和配置:

cd到php代码的pear目录下执行:

pear channel-discover pear.phing.info

会有一段输出的,再执行:

pear install phing/phing

如果报什么找不到ersioncontrol/svn.php的错误,请看 解决执行phing命令报找不到versioncontrol/svn.php的错误

执行后还是会有一段输出,出现 install ok 字样时就说明已经全部安装完成,现在就可以写部署文件了。注意,phing是部署项目的,所以它的配置文件就是项目的部署文件。我一般在项目的根目录下建build目录和reports目录,build目录存放项目部署文件,reports是存放生成的单元测试和代码覆盖率报告。这两个目录会随项目一起提交,并会check out到代码副本目录,部署到web环境时则被排除在外了。

<?xml version="1.0"?>
<project
name="Coderbolg"
basedir="/data0/htdocs/projects/v2.1"
default="test">
<target
name="get">
<svnupdate
svnpath="/usr/bin/svn"
username="zhuwanchun"
password="014622"
repositoryurl="http://192.168.1.12/svn/projects/coderbolg/trunk/v2.1/"
todir="."
/>
</target>
<target
name="deploy">
<copy
todir="/data0/htdocs/coderbolg"
overwrite="true">
<fileset
dir=".">
<include
name="application/**"
/>
<include
name="data/**"
/>
<include
name="library/Custom/**"
/>
<include
name="public/**/**"
/>
<include
name="scripts/**"
/>
<include
name="tests/**"
/>
<exclude
name="data/**"
/>
<exclude
name="build/**"
/>
<exclude
name="reports/**"
/>
<exclude
name="library/Zend/**"
/>
<exclude
name="public/index.php"
/>
</fileset>
</copy>
</target>
<target
name="test"
depends="get">
<coverage-setup
database="reports/coverage/coverage.db">
<fileset
dir="tests">
<include
name="**/*Test.php"
/>
<include
name="*Test.php"
/>
</fileset>
</coverage-setup>


<phpunit
codecoverage="true"
failureproperty="failure.unittest"
>
<batchtest>
<fileset
dir="tests">
<include
name="**/*Test.php"
/>
<include
name="*Test.php"/>
</fileset>
</batchtest>
<formatter
type="xml"
todir="reports/test"
outfile="test.unit.report.xml"
/>
</phpunit>


<phpunitreport
infile="reports/test/test.unit.report.xml"
format="frames"
todir="reports/test"
/>


<coverage-report
outfile="reports/coverage/coverage.xml">
<report
todir="reports/coverage"
styledir="/usr/local/webserver/php/lib/php/data/phing/etc"/>
</coverage-report>


<if>
<equals
arg1="${failure.unittest}"
arg2="true"
/>
<then>
<fail
message="Failed for unit test [FAILURE]!"
/>
</then>
<else>
<phingcall
target="deploy"
/>
</else>
</if>
</target>
</project>

phing的配置文件是由target组成的,从指定的target开始执行,如果当前target依赖于另一个target,则先执行另一个target。在project结点的default就是指定默认执行的target为test。在xinc 的配置文件中phingBuilder结点的target也是指定当调用phing的配置文件时要执行的target为test。现在我们看看名为test的target,这个target依赖于名为get的target,则先执行get。我们看看get里的内容,它就是调用svnupdate命令从指定版本库中更新代码到代码副本中。更新完之后再回到test中,这里会调用phpunit测试我们的tests目录下的所有单元测试文件。单元测试跑完之后生成结果报告和代码覆盖率报告。接着有个if命令,它会根据单元测试的结果决定显示报错信息还是调用执行deploy。如果所有的单元测试都通过则执行deploy,它会根据要求将文件和目录复制到web目录(/data0/htdocs/coderbolg)中供人访问了。这里的deploy可以复制代码到远程服务器,不过需要PHP支持SSH2扩展  ,配置如下:

<target name="publish">
<scp
username="root"
password="123456"
host="216.21.34.32"
todir="/data0/htdocs/coderbolg">
<fileset
dir=".">
<include
name="**/*.php"
/>
<include
name="**/*.ini"
/>
<include
name="**/*.csv"
/>
</fileset>
</scp>
</target>

具体的配置细节请看phing的手册。http://www.phing.info/docs/guide/current/

接着进入bulid目录,执行phing命令,如果到命令执行结束还是显示着绿色的部署信息而没有红色的报错信息则说明项目手动部署成功。既然是持续集成嘛自然是自动部署了。现在phing的脉络打通,接着就是xinc大显身手的时候了。 执行service xinc start来启动xinc。这个时候xinc就会定时扫描项目配置目录,执行里面的配置文件。这个配置文件会自动调用靠phingBuilder来调用phing命令的。而且利用artifactspublisher命令将phing生成的单元测试报告和代码覆盖率报告的访问地址显示到xinc的web页面上供开发人员查阅。就像上面截图那样了。

好了,整个持续集成平台就算构建好了。以后每当开发人员提交了代码,都会自动运行已经写好的单元测试,通过之后再部署上来。呵呵……很方便的。希望本文对你有帮助。

 

转自:http://www.coderbolg.com/content/133.html

posted on 2011-05-29 21:12  哎!无悔  阅读(778)  评论(1编辑  收藏  举报