Gitlab钩子脚本
Gitlab钩子脚本
gitlab可以结合钩子脚本来对git的各个流程进行定制化操作
我们现在生产环境需要在服务器端来对客户端push上来的xml文件进行校验.
如果不满足规则,则拒绝push到服务器端.
因为公司的ORM框架统一用的Mybatis,所以指定规则的时候比较方便
主要是看
标签中是否包含了更新时间字段 updated_date 或者 update_date 或者 modify_date
服务器脚本
单独仓库脚本
对单独某个仓库制定特殊的规则
1.找到仓库位置
安装gitlab之后,可以通过查看配置文件中的‘git_data_dirs’参数来确定仓库地址
一般默认是在**/var/opt/gitlab/git-data**目录下
2.编写Shell脚本
进入需要制定规则流程的仓库地址**/var/opt/gitlab/git-data/repositories/root/githooks.git**
创建脚本文件夹 必须是custom_hooks这个名字
mkdir custom_hooks
mkdir pre-receive.d
vi start.sh
我们需要在代码push到服务端之前进行校验,就需要在pre-receive这个阶段进行校验(其它的参考文末的链接)
start.sh脚本
#!/bin/bash
export LANG="en_US.UTF-8"
REJECT=0
while read oldrev newrev refname; do
if [ "$oldrev" = "0000000000000000000000000000000000000000" ];then
oldrev="${newrev}^"
fi
files=`git diff --name-only ${oldrev} ${newrev} | grep -e ".xml$"`
if [ -n "$files" ]; then
TEMPDIR="./tmp"
for file in $files; do
#echo "${file}"
if [[ $file == *"/"* ]]; then
mkdir -p "${TEMPDIR}/${file%/*}" > /dev/null
#echo "${file}"
else
#echo "${file}"
mkdir -p "${TEMPDIR}" > /dev/null
fi
touch ${TEMPDIR}/${file}
git show $newrev:$file > ${TEMPDIR}/${file}
done;
./script/updateCheck.sh
REJECT=$?
#if [ $REJECT -eq 0 ]; then
# echo "success!"
# else echo "error!"
#fi
rm -rf $TEMPDIR
fi
done
exit $REJECT
这个脚本中需要注意的地方是 ./script/updateCheck.sh
为了以后还需要增加其它定制化流程. 这里就把脚本校验抽象出来了.
start脚本执行的环境默认是在githooks.git目录下的.
所以我们需要在仓库目录下创建一个script目录,里边写一个被调用的脚本
mkdir script
cd script/
vi updateCheck.sh
updateCheck.sh脚本内容
#!/bin/bash
TEMP_FILE='temp.sql'
REJECT=0
read_file() {
for file in $(ls -a $1); do
if [ -d $1"/"$file ]; then
if [[ $file != '.' && $file != '..' ]]; then
read_file $1"/"$file
fi
else
if [ ${file##*.} == "xml" ]; then
FLAG=0
while read line; do
if [[ $line =~ "<update" ]]; then
FLAG=1
fi
if [[ $FLAG -eq 1 ]]; then
echo $line >>$TEMP_FILE
fi
if [[ $line =~ "</update>" ]]; then
FLAG=0
result1=$(sed -n '/\<update id=/{p;:a;n;H;/<\/update>/{x;s/\n//p;z;h};ba}' $TEMP_FILE | grep -i -E 'UPDATED_DATE|UPDATE_DATE|MODIFY_DATE' | wc -l)
if [[ result1 -eq 0 ]]; then
REJECT=1
TMP_PATH=$1
echo "请修改下列文件${TMP_PATH#*/tmp}"/"${file}, update sql语句中未包含'updated_date' or 'update_date' or 'modify_date' 字段!"
#echo "请修改下列文件${file}, update sql语句中未包含'updated_date' or 'update_date' or 'modify_date' 字段!" >>test.log
echo "SQL片段:"
cat $TEMP_FILE
#echo "SQL片段:" $(cat $TEMP_FILE) >>test.log
fi
rm -rf $TEMP_FILE
fi
done <$1"/"$file
fi
fi
done
}
read_file $(pwd)"/tmp"
exit $REJECT
这个脚本主要是校验提交的xml格式文件内的
3.验证
全局脚本
如果有一些要对全部仓库的规则 则可以在全局脚本内配置
例如我们把上边的规则应用到全局仓库
1.查找全局脚本地址
一般默认是在**/opt/gitlab/embedded/service/gitlab-shell/hooks**下边的
可以通过查看配置文件中的custom_hooks_dir参数来确定位置, 记得把前边的#注释删掉让全局配置生效噢
2.编写shell脚本
可以看到有三个文件. 三个文件分别对应不同的生命周期
pre-receive是在push之前
post-receive是在push之后
update是在push之前但是和分支有关系
具体可以参考文末的git钩子链接
我们现在来修改pre-receive钩子
vi pre-receive
#!/bin/bash
export LANG="en_US.UTF-8"
REJECT=0
while read oldrev newrev refname; do
if [ "$oldrev" = "0000000000000000000000000000000000000000" ];then
oldrev="${newrev}^"
fi
files=`git diff --name-only ${oldrev} ${newrev} | grep -e ".xml$"`
if [ -n "$files" ]; then
TEMPDIR="./tmp"
for file in $files; do
#echo "${file}"
if [[ $file == *"/"* ]]; then
mkdir -p "${TEMPDIR}/${file%/*}" > /dev/null
#echo "${file}"
else
#echo "${file}"
mkdir -p "${TEMPDIR}" > /dev/null
fi
touch ${TEMPDIR}/${file}
git show $newrev:$file > ${TEMPDIR}/${file}
done;
./script/updateCheck.sh
REJECT=$?
#if [ $REJECT -eq 0 ]; then
# echo "success!"
# else echo "error!"
#fi
rm -rf $TEMPDIR
fi
done
exit $REJECT
这里要注意 钩子脚本执行的当前目录永远是提交的仓库目录
所以还是需要在当前仓库目录下边 创建/script/updateCheck.sh这个脚本
但是,也可以直接把脚本内容写到这个pre-receive钩子里边.
这样就不需要在每个仓库目录下创建这个文件了.
全局脚本和单一仓库脚本的关系
全局脚本优先级高于单一仓库脚本
同时开启的话, 会先走全局脚本,再走单一仓库脚本
客户端脚本
1.查看客户端脚本位置
我们在把项目clone到本地之后
打开win平台的隐藏文件功能
可以发现有个.git隐藏文件夹
2.编写shell文件
可以看到hooks文件夹中有很多sample文件,
如果要使用其中的某个钩子就把.sample后缀去掉即可生效.
脚本内容和上边的类似.
上边的所有钩子脚本都可以用脚本语言来写. python ruby 都可以的.非常灵活
参考:
{docsify-updated}