172173.com

在做版本更新的时候,需要SVN做一些自动化的事情,比如提交前自动更新;提交一些文件后关联着提交另一些。所以需要写一点自动化脚本。

1.什么是svn钩子

官方说法:
钩子是通过版本库事件触发,例如新版本的创建或一个未版本化属性的修改。一些钩子(叫做“pre hooks”)在事件发生前运行,可以用来报告发生了什么以及防止它发生。还有一些钩子(“post hooks”)在版本库事件之后发生,只是用来报告。每个钩子能够获得事件的足够信息,例如提出的(或完成的)版本库修改细节,还有触发事件的用户名。

svn钩子分为:服务器钩子和客户端钩子。

svn服务器钩子:

  • 经常提到的svn hooks是一组“外挂”脚本程序,是svn提供的一组由svn事件触发的特别有用的程序。这些程序在服务器端执行,可以提供svn之外的一些附加功能。钩子可以调用批处理文件、可执行文件或者一些类似于perl、python等的脚本。

svn客户端钩子:

  • 如果使用tortoise svn(海龟svn,常用的svn客户端),它也提供钩子机制,这些和svn hooks有本质区别,它是在本地(客户端)执行的。

2.svn服务端hooks分类9种

A类-关于锁定的2种:

  • post-lock:对文件进行加锁操作之后执行该脚本
  • pre-lock:对文件进行加锁操作之前执行该脚本

B类-关于解锁的2种:

  • post-unlock:对文件进行解锁操作之后执行该脚本
  • pre-unlock:对文件进行解锁操作之前执行该脚本

C类-关于提交的3种:

  • post-commit:在提交完成,成功创建版本之后执行该钩子,提交已经完成,不可更改,因此本脚本的返回值被忽略。
  • pre-commit:在 Subversion transaction 完毕之后,在提交之前,执行该脚本
  • start-commit:在客户端还没有向服务器提交数据之前,即还没有建立Subversion transaction(缩写为txn)之前,执行执行该脚本

D类-关于属性的2种:

  • post-revprop-change:在修改 revision 属性之后,执行该脚本。因为修改稿已经完成,不可更改,因此本脚本的返回值被忽略(不过实际上的实现似乎是该脚本的正确执行与否影响属性修改)
  • pre-revprop-change:在修改 revision 属性之前,执行该脚本

3.svn钩子脚本

pre-commit脚本

客户端提交前规则检查:

  • 功能1:提交的文件名不能包含空格
  • 功能2:提交的注释必须大于10个字符
    • 11代表注释必须大于10个字符,因为末尾有个\n算一个字符
    • 一个汉字代表16个字符,如果需要至少输入4个汉字,那么数字需要改成48

钩子默认变量说明:
REPOS=”$1” ,表示仓库绝对路径
TXN=”$2”,提交的版本号
例如:/data/svn_data/sadoc 17-17

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
[[email protected] hooks]# cat pre-commit
#!/bin/sh
# PRE-COMMIT HOOK
REPOS="$1"
TXN="$2"
SVNLOOK=/usr/bin/svnlook

# -------------------------------------------------------------------------------------------------
# count commited file num
check=$($SVNLOOK changed -t $TXN $REPOS |awk 'NF!=2{for(i=2;i<=NF;i++)if(i!=NF)printf $i" ";if(i=NF)printf $i","}')
# compare files
if [ "$check" != "" ]
then
check_del=$($SVNLOOK changed -t $TXN $REPOS | awk '{for(i=1;i<NF;i++)if($i=="D")print $1}')
if [ "$check_del" == "" ]
then
echo "The file name contains spaces.Please fix it and try again!." 1>&2
echo "不允许文件名存在空格!" 1>&2
exit 1
fi
fi

# -------------------------------------------------------------------------------------------------
# Make sure that the log message contains some text.
#SVNLOOK=/usr/local/subversion-1.8.11/bin/svnlook
SVNLOOK=/usr/bin/svnlook
LOGMSG=`$SVNLOOK log -t "$TXN" "$REPOS" | grep "[a-zA-Z0-9]" | wc -c`
if [ "$LOGMSG" -lt 11 ];
then
echo "Log message can't be empty! you must input more than 10 chars as comment!." 1>&2
echo "注释必须大于10个字符!" 1>&2
exit 1
fi

exit 0

post-commit

  • 在svn客户端执行commit提交后执行改钩子脚本
  • 实现svn提交成功后,自动发布到yd jeknins测试环境
  • 注意,根据svn实际的路径来更改脚本的传参值,$p必须为Jenkins项目名称
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
[[email protected] hooks]# cat post-commit
#!/bin/bash
# Writer: 858zjc
# Date: 20170523
# 云顶自动发布用,SVN有提交就自动触发jenkins构建并发布到测试环境
# 每个一级子目录代表一个项目


REPOS="$1"
REV="$2"

#SVNLOOK="/usr/bin/svnlook"
SVNLOOK="/usr/local/subversion-1.8.11/bin/svnlook"
CURL="/usr/bin/curl"

dirs=()
for i in `${SVNLOOK} dirs-changed -r "$REV" "$REPOS"`;
do
d=$(awk -F '/' '{print $2}' <<< $i) # 通过调整$2列,来调整绝对路径匹配svn项目名=Jenkins项目名
dirs=("${dirs[@]}" "${d}")
done


projects=($(awk -vRS=' ' '!a[$1]++' <<< ${dirs[@]}))

for p in "${projects[@]}";
do
${CURL} -XGET "http://admin:[email protected]:8080/job/${p}/buildWithParameters?token=b6c2901e49894712ef149dc1b92b15a2&cause=SVN+trigger+build&deploy_server=test"
done

exit 0

pre-revprop-change

  • 在修改 revision 属性之前,执行该脚本
  • 用于svn备服务器,svn主执行svnsync init时,此钩子必须存在,可以为空。

 评论