reviewboard svn post-review hook

需求

希望每次提交到分支上的代码自动提交到reviewboard,通过svn post-review hook脚本实现调用rbt工具发起code review。

改进过程

  1. python和svn绑定问题

    运维同学在使用hook脚本时发现通过源码编译出来的python和svn无法关联使用,一方面是缺少python的svn库,另一方面是缺少相应动态库。

    http://stackoverflow.com/questions/1448894/subversion-python-bindings-documentation 这里有介绍通过编译安装swig就可以获取python和svn关联的脚本及动态库。

  2. 依赖1.5.2版本apr库,但是svn服务器无法升级apr库问题

    apr库由于影响范围较广,升级之后很多服务可能出现问题,后面就考虑将该脚本移出来,放到其他服务器,提供http服务让post-commit hook调用。

  3. 脚本提供branch review功能

    如上提供的脚本中更多的是将当前revision提交上去会比较好用,但是当你有一个分支,提交多次修改和code review就比较麻烦。虽然reviewboard可以在多个diff之间再做比较,但是始终无法得到最初的版本和最新的版本的一个diff。

    这里考虑先获取当前改动的branch,然后在脚本中提供获取整个branch diff的方法然后post到reviewboard,这样就对于想看整个分支改动的情况非常方便。

    4. rbt post最新的到reviewboard时卡住,发现是reviewboard在读取diff时还要获取一些repository其他信息(暂时未跟进要啥信息),所以需要配置一个svn账号
    找到reviewboard的python库路径,打开reviewboard/scmtools/svn/pysvn.py,找到_do_on_path方法,增加如下代码
    def _do_on_path(self, cb, path, revision=HEAD):
    # add
    def login(*args):
    #设置svn账号密码
    return True, 'svn账号', 'svn密码', False
    self.client.callback_get_login = login
    #add end
    if not path:
    raise FileNotFoundError(path, revision)

    第四条发现是repository里面配置的svn账号密码失效了,在admin页面可以更改。

下面开始介绍目前正在使用的模式。

部署结构

reviewboard svn post-review hook_第1张图片

1、SVN服务器上部署svn库,对应repository下的hook脚本会调用python svn hook服务

2、python svn hook服务提供http服务,接收参数repos和rev,执行rbt请求将diff发送到reviewboard

3、reviewboard服务器部署reviewboard

如果没冲突的情况都放一台机器上也OK。

配置hook

在svn仓库服务器上找到svn目录下的hooks目录,创建或修改post-commit文件,
并且添加可执行权限,post-commit内容见https://github.com/zhouyuzhy/reviewboard-hook/blob/master/hook/post-commit

python脚本

参考:https://github.com/reviewboard/reviewboard/blob/master/contrib/tools/svn-hook-postcommit-review

在该脚本基础上修改如下几点,详细内容见https://github.com/zhouyuzhy/reviewboard-hook

1、修改不依赖svn库,使用svn log解析得到author和提交msg

command = SVN_PATH + "svn log -r " + str(rev) + " -l 1 -v " + REPOSITORY +" --username " + SVN_USER + " --password "+ SVN_PASSWORD + " --non-interactive"
logData = execute(command,
               env = {'LANG': 'en_US.UTF-8'}, shell=True)
for i in range(len(logDataLines)-2-logLineCount,len(logDataLines)-2):
    log+=logDataLines[i]+"\n"
author = logDataLines[1].split(' ')[2]

2、增加branch判断,只针对branches下面的分支提交review

firstChangePath = logDataLines[3].split(' ')[4]
if firstChangePath.find('branch') < 0:
    print 'no branch found in ',rev
    return
branchSlashIndex = firstChangePath.find('/',firstChangePath.find('branches')+9,len(firstChangePath)-1)
branch = firstChangePath[0:branchSlashIndex]

3、增加branch review语法,可以将该分支下的所有修改一次提交

branchlog = ''
m = re.search(r'(?:branch)(?: )?review', log, re.M | re.I)
if m:
    command = SVN_PATH + "svn log --stop-on-copy " + REPOSITORY + branch +" --username " + SVN_USER + " --password "+ SVN_PASSWORD + " --non-interactive"
    if DEBUG:
        print command

    branchlog = execute(command,
                   env = {'LANG': 'en_US.UTF-8'}, shell=True)
    branchloglines = branchlog.splitlines()
    for branchlogline in reversed(branchloglines):
        if len(branchlogline.split('|')) == 4:
            prevrev = int(branchlogline.split(' ')[0][1:])
            break

4、修改update review语法,支持在一个语句中做publish和update review

m = re.search(r'update(?: )?(?:branch)?(?: )?review:([0-9]+)', log, re.M | re.I)
if m:
    reviewid = '--review-request-id=' + m.group(1)
else:
    reviewid = ''

5、使用python django提供http服务封装hook脚本,django自己不太会用,就用最简单的模型封装了一层

如何使用

1、在commit message中添加publish review则会自动添加新的review并且publish

2、在commit message中添加draft review则会自动添加新的review而不是publish状态

3、在commit message中添加publish/draft update review:1则会自动更新编号为1的review而不重新提交

4、在commit message中添加after revision:1则从1到当前revision全部提交review,可选,默认为一个revision

5、在commit message中添加publish branch review或者publish update branch review:1就会把整个分支的diff提交

你可能感兴趣的:(SVN,Review,reviewboar,svn-hook)