Web项目的开发过程中我们经常会有这样的需求:当我们向svn服务器commit修改的代码后,能够即时的体现在测试站点上。其实svn已经为我们提供了这样的接口,那就是hooks。
当我们创建一个svn repository之后,我们可以看到它的repository结构,有一个hooks文件夹,里面有一些.tmpl文件。这是一些示例脚本,我们可以用这些示例脚本作为范本来修改满足自己的项目需求。
下面描述一下我们的项目需求和实现:
我们的svn代码服务器和web测试服务器是两个不同的服务器,其中svn代码服务器是ubuntu-server系统,web测试服务器是centos。我们要在svn代码服务器收到开发人员commit的变更之后即时的通知(通过ssh连接到测试服务器)web测试服务器使之自动从svn代码服务器获取svn变更(svn update)。所以我们创建了一个post-commit的hook。这个hook脚本使用了expect,在ubuntu中可以通过"sudo apt-get install expect"来安装。
参考了这篇博文,利用博文中提供的脚本,我做了一些小的修改,最后是下面这样的:
-
#!/usr/bin/expect -f
-
## AUTHOR: Meitar Moscovitz
-
# DATE : Thu Jun 21 16:32:42 EDT 2007#
-
-
set HOST my.web.server #服务器地址
-
set USER someuser #用户名
-
set PASS xxx #密码
-
-
# the working copy we're going to update
-
set WC /path/to/working/copy #测试web的svn副本路径
-
set LOG /path/to/log/file #日志输出(可以查看到最后一次svn update的revision)
-
-
# the path to the svn executable on the remote web server
-
set SVNBIN /usr/bin/svn
-
-
# our network is slow, set a long timeout
-
set timeout 30
-
-
##### DO NOT EDIT PAST THIS LINE! #####
-
# POST-COMMIT HOOK#
-
# The post-commit hook is invoked after a commit. Subversion runs
-
# this hook by invoking a program (script, executable, binary, etc.)
-
# named 'post-commit' (this file) with the
-
# following ordered arguments:#
-
# [1] REPOS-PATH (the path to this repository)
-
# [2] REV (the number of the revision just committed)#
-
# Note that Subversion does not provide this program with an environment
-
# of any kind. That means this program lacks a current working directory,
-
# a home directory, a $PATH, and so on.
-
-
set REPOS [lindex $argv 0]
-
set REV [lindex $argv 1]
-
-
# Define error codes
-
set E_NO_SSH 1 ;# can't find a usable SSH on our system
-
set E_NO_CONNECT 2 ;# failure to connect to remote server (timed out)
-
set E_WRONG_PASS 3 ;# password provided does not work
-
set E_UNKNOWN 25 ;# unexpected failure
-
-
# find the SSH binary on our system
-
if {[file executable /usr/bin/ssh]} {
-
set SSHBIN /usr/bin/ssh
-
} elseif {[file executable /usr/local/bin/ssh]} {
-
set SSHBIN /usr/local/bin/ssh
-
} else {
-
send_error "Can't find a usable SSH on this system.\n"
-
exit $E_NO_SSH
-
}
-
-
spawn $SSHBIN $USER@$HOST "$SVNBIN update -r HEAD --force $WC >> $LOG"
-
-
expect {
-
"continue connecting (yes/no)? " { send "yes\r"; exp_continue; }
-
-nocase "password:" { send "$PASS\r"; }
-
timeout {
-
send_error "\nWe have timed out after $timeout seconds while trying to connect to $HOST!\n";
-
exit $E_NO_CONNECT;
-
}
-
}
-
-
expect {
-
-nocase "password:" { ;# if we are asked for the password again, then we have provided the wrong password
-
send_error "\nCan not log in to $HOST because the password provided for user $USER has been rejected.\n";
-
exit $E_WRONG_PASS;
-
}
-
-re "revision (\[0-9]+)." {
-
if {$REV == $expect_out(1,string)} {
-
send_user "\nSuccessfully updated $WC on $HOST to revision $REV.\n"
-
} else {
-
send_user "\nUpdated repository to revision $expect_out(1,string), but svn reports that we are at revision number $REV.\n"
-
send_error "CAUTION: Repository updated to revision $expect_out(1,string), but committed revision $REV.\n"
-
}
-
}
-
#将下面几行注释掉的原因是因为我发现#其实这个hook脚本已经成功使web测试服务器更新(svn update)了working copy但是还是会抛出这个错误!
-
#而且这个错误也会在svn客户端(比如:TortoiseSVN)的commit动作的最后出现!
-
# default {
-
# send_error "An unexpected error has occured. The process at spawn ID $spawn_id has produced the following output:\n"
-
# send_error $expect_out(buffer)
-
# exit $E_UNKNOWN
-
# }
-
}
好了,另外要注意一下这个post-commit脚本文件要具备关联用户(比如:www-data)的可执行权限。可以直接输入"./post-commit"测试一下结果。
文章来自:http://hi.baidu.com/devylee/item/247db2d0aead56362b35c7f1
阅读(4529) | 评论(0) | 转发(0) |