svn hooks实现代码同步,以及持续集成构建方案
svn post-commit hooks:
我们在开发的过程将代码提交到SVN后使用SVN的hook,通过post-commit脚本,在目标文件夹根下执行svn update操作,将更新内容同步到测试环境,这样开发调试非常方便。
现在SVN库的文件数量越来越多,svn 本地的目录已经3个多G了,几十万个文件,在目标文件夹下执行svn update进行更新速度也就越来越慢了,常常提交之后SVN客户端会等几分钟没有响应,在没有响应的时间内,无法再继续提交内容。如果使用zendstudio进行提交的话,所有保存的操作都要等这个SVN提交完成才能继续。
原post-commit内容:
--------------------------------------------
#!/bin/sh
REPOS="$1"
REV="$2"
WEB=/data/web
FRAMEWORK=/data/framework
export LC_ALL=zh_CN.UTF-8
a=`svn update $WEB $FRAMEWORK /data/conf /data/shell --username x*******i --password ******* | grep 'nginx\.conf'`
if [ -n "$a" ]
then
kill -HUP `cat /dev/shm/nginx.pid`
fi
chown -R www.www $WEB &
-----------------------------------------------
我们主要做了以下几个工作:
1、SVN更新后,同步在/data/web、/data/framework、/data/conf、 /data/shell 4个文件夹在下执行svn update命令进行同步更新操作。
2、如果/data/conf/nginx.conf文件修改了,那么重启nginx。
3、将所有/data/web目录下的文件所有者和组都变成www。
原因在于:
1、提交的SVN的时候,4个文件在根下进行更新,文件数量巨大响应非常慢。
2、chown的操作也是比较浪费。
解决的想法:
对有变化的文件进行 svn update 这样更有效率。
解决的思路:
1、得到本次提交更新的文件。
2、在目标目录中更新指定的文件。
3、同时将指定文件所有者和组变成www。
4、使用PHP程序当shell来完成这样的工作。
最后的成果是巨大的,现在svn提交已经是飞一样的快了,要知道svn 本地的目录已经3个多G了,几十万个文件。
实现步骤:
1、得到更新的文件。
通过分析我们发现post-commit脚本有两个变量
# 库的路径
REPOS="$1"
# 新提交的版本号
REV="$2"
通过这样的操作就可以得到本次更新的内容与文件。
changed=$(svnlook changed -r $REV $REPOS)
2、将得到的本次更新的内容提交给PHP脚本来处理,分析哪些文件发生变化。
/usr/local/php/bin/php-cgi -q /data/shell/svn_post_commit_resources.php "$changed" &
用PHP分析出哪些文件发生变化后,构造shell命令,由PHP调用shell命令进行更新。
3、相关脚本:
最新的post-commit文件内容:
-------------------------------------
#!/bin/sh
# 库的路径
REPOS="$1"
# 新提交的版本号
REV="$2"
WEB=/data/web
FRAMEWORK=/data/framework
export LC_ALL=zh_CN.UTF-8
changed=$(svnlook changed -r $REV $REPOS)
log=$(svnlook log -r $REV $REPOS)
n=$'\n'
/usr/local/php/bin/php-cgi -q /data/shell/svn_post_commit_resources.php "$changed" &
--------------------------------------
处理更新内容,执行更新命令的PHP脚本文件 svn_post_commit_resources.php 的内容:
-----------------------------------------
<?php
$files = explode("\n", $argv[1]);
if (!is_array($files)) {$files=(array)$files;};
foreach ($files as $v)
{
// 取文件名
$f_tem = trim(substr($v, 2));
// 取最顶层目录名
$d_tem = substr($f_tem, 0, strpos($f_tem, '/'));
if (!in_array($d_tem, array('web', 'framework', 'conf', 'shell'))) {
continue;
}
// SVN copy 对应的文件
$f_name = '/data/' . $f_tem;
$cmd = "svn update '$f_name' --username x****i --password K****$;chown www.www '$f_name'";
exec($cmd);
if (strpos($f_tem, 'nginx.conf')) {
exec("kill -HUP `cat /dev/shm/nginx.pid`");
}
}
exit();
?>
svn持续集成:
需要搭建持续集成开发环境。简单的说,持续集成就是要干这么一件事:持续集成与SVN配合,开发人员将代码上传到SVN上指定的文件夹下,持续集成cruisecontrol(简称CC)会自动从SVN上checkout代码,自动进行编译链接,生成可执行文件,而PM(也就是实验室管我们的老师)则通过web前端登录到CC服务器,从而查看每个‘码农’的每天代码的更改情况。可以说,CC为一个软件项目的整合提供了一个很好的平台。
废话少说,开始搭CC(Linux下),首先需要SVN的支持,我们假设SVN已经搭好了,并且所有码农的代码放在http://192.168.0.2/SVN/SMSSystem这个文件夹下。首先保证已经预装了Apahe , JDK , ANT(ANT可以不用自己装,在cruisecontrol)的代码包中有ANT,只需修改环境变量即可,SVN的客户端(CC要与SVN配合使用)。
首先,下载CC的压缩包cruisecontrol-bin-2.8.3.zip,解压包
cd cruisecontrol-bin-2.8.3 进入目录, 修改config.xml文件,在我这个项目中,修改的结果如下:
<cruisecontrol>
<project name="SMSSystem"> # 工程名
<listeners>
<currentbuildstatuslistener file="logs/${project.name}/status.txt"/> # log信息
</listeners>
<bootstrappers>
<svnbootstrapper localworkingcopy="projects/${project.name}"/> #svn的地址
</bootstrappers>
<modificationset quietperiod="30">
<svn localworkingcopy="projects/${project.name}"/> #隔30秒查看SVN的修改情况
</modificationset>
<schedule interval="120"> # 隔120秒重新编译,但是SVN代码不变则不执行
<ant anthome="apache-ant-1.7.0" buildfile="projects/${project.name}/build.xml" target="make"/>
</schedule>
<log>
<merge dir="projects/${project.name}/target/test-results"/>
</log>
<publishers>
<onsuccess>
<artifactspublisher dest="artifacts/${project.name}" file="projects/${project.name}/target/${project.name}"/>
</onsuccess>
</publishers>
</project>
</cruisecontrol>
接着,我们要手动将SVN checkout一次(第一次必须要手动来checkout,以后就不用了)。
cd project #这个地方是放工程的地方
svn co http://192.168.0.2/SVN/SMSSystem
接着在SMSSystem文件夹下加入以下的build.xml(我们的开发是Linux + GCC)
<project name="SMSSystem" default="all">
<target name="all" depends="clean, make"/>
<target name="make">
<exec executable="make" failonerror="true" >
</exec>
</target>
<target name="clean">
<exec executable="make" failonerror="true" >
<arg value="clean"/>
</exec>
</target>
</project>
接着退到CC的主目录,执行./cruisecontrol.sh,CC服务就打开了,你可以通过web查看
http://192.168.0.3:8080/dashboard
几点说明:
1、所有的工程都要放在project这个文件夹下面
2、CC启动会去找config.xml ,启动后会通过ant命令去找每一个工程底下的build.xml
3、CC的安装不难,启动前在shell下键入javac , java , ant 都要保证成功,不能出现command not found
4、CC可以同时加入多个工程,只要保证每个工程底下有正确的build.xml,并且每个工程都配到config.xml里就可以了
钩子配置完毕后要在web目录中先检出一次: svn checkout svn://192.168.0.110/doc /var/www/html/doc
(转自:http://blog.csdn.net/caiyichaobupt/article/details/5442588)

浙公网安备 33010602011771号