通过svn hooks功能自动更新网站代码

2017-01-23 11:47:24
通过VisualSVN、plink、rsync、bat、shell的综合运用,实现程序代码的自动发布
在网站开发过程中,我们经常会遇到程序代码发布的问题,而代码发布的方式也是多种多样、不断演变的,有比较传统的通过ftp上传代码的,有直接从源代码服务器更新的,也有现在的一些集代码管理、发布为一体的自动化系统等等。
我们以前的一个项目使用的是直接从SVN服务器更新代码,然后通过rsync同步到线上服务器的方式,大体如下:



我们的工作流程是:
1、本地代码commit提交到SVN服务器
2、SSH登录到Rsync服务器,执行一个update.sh命令,自动完成发布功能。update.sh这个shell脚本的功能就是从svn服务器update代码,然后通过rsync把代码同步到线上服务器。

为了简化工作流程,我们利用VisualSVN的hooks功能,当每次有代码提交的时候,自动登录rsync服务器然后执行update.sh,这样就省了一步人工操作了。svn的hooks(钩子)功能,就是相当于一个事件触发器,当发生了某件事情的时候,自动触发一个操作。

VisualSVN的hooks设置,在仓库选项选择管理hooks,



VisualSVN提供了几种不同的hooks,我们用到的是post-commit hook,就是说当有代码被提交的时候触发的事件,这里我们是执行一个windows批处理脚本文件,注意:命令要用双引号括起来,后面的%1 %2 %3是传递的三个参数,我们可以在post_commit_handler.bat中获得,其中%1是代码仓库的url地址,%2是最新更新的版本号。



我们的项目是由两个小的项目组成,一个小项目是后台的管理系统admin,一个是前端的api接口部分,这两个项目需要部署到不同的线上服务器。但是在SVN源码服务器上,这两个小项目都是放在一个代码仓库中的。因此,post_commit hook需要知道是提交的哪个小项目的代码。这里就需要用到svnlook dirs-changed命令,能够知道代码仓库最新更新的文件目录是什么。

我们看看post_commit_handler.bat的代码,其中的%1%2是从hook中传递过来的,参考上面的图,这段代码的意思是,如果最新更新的是vote/admin子项目的代码,就ssh登录到rsync服务器,然后执行/root/svn_vote_admin.sh,否则如果更新的是vote/api子项目,就执行svn_vote_api.sh。
plink是一个windows下的ssh客户端命令,它是putty软件提供的一个小工具,下载putty解压就可以找到。

svnlook dirs-changed %1 -r %2 |findstr /b /i "vote/admin"

IF %ERRORLEVEL% EQU 0 (
"E:\putty\plink" root@rsync_server -pw rsync_password "sh /root/svn_vote_admin.sh"
)

svnlook dirs-changed %1 -r %2 |findstr /b /i "vote/api"

IF %ERRORLEVEL% EQU 0 (
"E:\putty\plink" root@rsync_server -pw rsync_password "sh /root/svn_vote_api.sh"
)

最后就是rsync服务器里的shell script脚本,svn_vote_admin.sh,代码如下:

cd /data/svn/www.hutuseng.com/admin
svn update .

if [ $? -eq "0" ]
then
rsync -vzrtp /data/svn/www.hutuseng.com/admin/ user@www.hutuseng.com::admin --password-file=/etc/rsyncd.pass


至此,一个完整的代码提交、发布的流程就完成了,当然在实际团队应用过程中不会这么简单,会有一些其他因素的考量,这里就是提供一种技术思路,仅供参考。