背景
每当我们接收一份新的版本,代码拿到手要做的第一件事就是查看 git log,看看这份代码的提交记录,最近代码做什么修改。如果我们看到 git log 杂乱无章,如果不知道每次提交的代码到底是做了什么,那么对于我们来说是比较痛苦的事情。所以说,规范的 CHANGELOG 不仅有助于他人帮忙 review 代码,也能高效的输出 Release Note,对版本管理也至关重要。
所以我们可以考虑使用 Gitlab 的服务端 hook 来针对git change log 进行校验,拦截不符合我们规范的提交到仓库。
方案设计
服务端 git hook 分为三种,分别是:
- pre-receive(推送前)
- update
- post-receive(推送后)
这三个步骤就是我们本地 push 完代码服务端要做的事情,如图所示:
我们可以在 pre-receive(推送前)阶段来做提交信息的校验,如果不符合我们的要求,直接返回,则该推送便不会推送到 GitLab 仓库中去。
实践落地
环境说明
gitlab版本:14.3.3
hook 配置
第一步,找到要配置仓库在 gitlab 中存储的路径,但因 gitlab 的仓库自某个版本开始采用 hash 存储,我们想要知道仓库对应的物理路径,可以通过管理员账号拿到对应的物理路径;
这里以某工程举例:
第二步,当拿到仓库对应的相对物理路径后,我们打开,目录如下:
[root@vm-gitlab 785f3ec7eb32f30b90cd0fcf3657d388b5ff4297f2f9716ff66e9b69c05ddd09.git]# pwd
/srv/gitlab/data/git-data/repositories/@hashed/78/5f/785f3ec7eb32f30b90cd0fcf3657d388b5ff4297f2f9716ff66e9b69c05ddd09.git
[root@vm-gitlab 785f3ec7eb32f30b90cd0fcf3657d388b5ff4297f2f9716ff66e9b69c05ddd09.git]# ls -l
总用量 24
drwxr-sr-x 2 libstoragemgmt polkitd 6 12月 14 14:32 branches
-rw-r--r-- 1 libstoragemgmt polkitd 126 12月 14 14:32 config
-rw-r--r-- 1 libstoragemgmt polkitd 73 12月 14 14:32 description
-rw-r--r-- 1 libstoragemgmt polkitd 21 12月 14 14:32 HEAD
drwxr-sr-x 2 libstoragemgmt polkitd 4096 12月 14 14:32 hooks
drwxr-sr-x 2 libstoragemgmt polkitd 33 12月 14 20:00 info
-rw-r--r-- 1 libstoragemgmt polkitd 1308 12月 14 15:06 language-stats.cache
drwxr-sr-x 4 libstoragemgmt polkitd 30 12月 14 20:00 objects
-rw-r--r-- 1 libstoragemgmt polkitd 103 12月 14 15:06 packed-refs
drwxr-sr-x 2 libstoragemgmt polkitd 6 12月 15 20:00 refs
第三步,hooks 中是 gitlab 示例的一些钩子,我们这里首先新建目录 custom_hooks,然后用再创建文件 pre-receive(推送前),pre-receive 文件内容如下(脚本语言为 shell),同时修改 pre-receive 文件的权限。
修改文件权限:
chmod +777 pre-receive
#!/bin/bash
echo "开始提交信息检查..."
# 从标准输入获取本次提交的commit id及分支的信息
read normalInput
ARR=($normalInput)
parentCommitId=${ARR[0]}
currentCommitId=${ARR[1]}
branch=${ARR[2]}
echo "您提交的分支为:$branch"
# 获取coomit的信息,用户,邮箱,msg等
user=$(git log --pretty=format:"%an" $currentCommitId -1)
echo "提交者为:$user"
commitDate=$(git log --pretty=format:"%cd" $currentCommitId -1)
echo "提交日期为:$commitDate"
msg=$(git log --pretty=format:"%s" $currentCommitId -1)
echo "提交的注释为:$msg"
flag=$(echo $msg | grep -E "fix.*|add.*|del.*|update.*|temp.*|test.*|revert.*|Merge.*")
if [ -z "$flag" ]; then
echo "[ERROR]提交信息校验未通过,需以 fix|add|del|update|temp|test|revert 开头"
exit 1
fi
第四步,在本地尝试推送,推送显示如下,如果不符合规范则无法提交成功。
第五步,我们再次查看目录如下:
踩坑
gitlab 的不同版本,所安装的 git 版本也会不一致,不同版本的 git 相同的命令的输出也有可能不一致,这点需要特别注意。
git log --no-merges --date-order -1