校验原因 在企业内部进行代码提交时, commit 中会存在提交者的 username 与 email
但该 username 与 email 是提交者在 Git 客户端自己设置的
如果提交者忘记设置或者设置错误, 并将 commit push 到远程服务后
当协作者需要寻找该 commit 提交者时, 错误的 username 与 email 会对协作者造成障碍
为解决这个问题, 需要在 GitLab 使用 Server Hooks 对 commit 进行校验, 只有 username 与 email 与 GitLab 中的一致才允许 push, 否则拒绝 push 并提示修改
准备工作 如需对 commit 的 username 与 email 进行校验, 那么需要在校验脚本中获取 push 者的 username 与 email
通过 GitLab Server Hooks 文档可知存在 GL_USERNAME
环境变量, 该变量的值为 push 者的 GitLab 的 username, 但是缺乏 email 相关环境变量
为获取 push 者的 email, 需使用 GitLab 提供的 Users API 进行获取
通过 API 文档可知只有 admin 用户才返回用户 email, 所以需要先使用 admin 账号生成一个 TOKEN
这个 TOKEN 只是用来获取获取用户 email, 故创建时选择 read_user 的范围即可
校验用户名与邮箱 hook GitHub 的 platform-samples 项目提供了一个 commit-current-user-check.sh 的 hook, 我们可以将该脚本下载下来, 进行修改即可
以下是修改后的 commit-current-user-check.sh
文件
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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 #!/usr/bin/env bash TOKEN="GitLab admin user read_user TOKEN" GITLAB_URL=http://127.0.0.1 get_name_and_email="import sys, json; try: obj=json.load(sys.stdin); print(obj[0]['name']+':'+obj[0]['email']) except: print('error')" GITLAB_NAME_EMAIL=`curl -s --header "Private-Token: ${TOKEN} " "${GITLAB_URL} /api/v4/users?username=${GL_USERNAME} " | PYTHONIOENCODING='UTF-8' python3 -c "${get_name_and_email} " ` if [ "${GITLAB_NAME_EMAIL} " == "error" ]; then echo "Push 异常: GitLab 获取用户信息异常, 请通知管理员进行排查" exit 1 fi GITLAB_USER_NAME=${GITLAB_NAME_EMAIL%:*} GITLAB_USER_EMAIL=${GITLAB_NAME_EMAIL#*:} zero_commit="0000000000000000000000000000000000000000" excludeExisting="--not --all" while read oldrev newrev refname; do if [ "$newrev " = "$zero_commit " ]; then continue fi if [ "$oldrev " = "$zero_commit " ]; then span=`git rev-list $newrev $excludeExisting ` else span=`git rev-list $oldrev ..$newrev $excludeExisting ` fi for COMMIT in $span ; do AUTHOR_USER=`git log --format=%an -n 1 ${COMMIT} ` AUTHOR_EMAIL=`git log --format=%ae -n 1 ${COMMIT} ` COMMIT_USER=`git log --format=%cn -n 1 ${COMMIT} ` COMMIT_EMAIL=`git log --format=%ce -n 1 ${COMMIT} ` if [[ ${COMMIT_USER} != ${GITLAB_USER_NAME} ]]; then echo -e "Push 异常: ${COMMIT} 的 committer (${COMMIT_USER} ) 不是 GitLab 中的中文名 (${GITLAB_USER_NAME} )" exit 30 fi if [[ ${COMMIT_EMAIL} != ${GITLAB_USER_EMAIL} ]]; then echo -e "Push 异常: ${COMMIT} 的 committer 的邮箱 (${COMMIT_EMAIL} ) 不是 GitLab 中的邮箱 (${GITLAB_USER_EMAIL} )" exit 50 fi done done exit 0
配置 hook 由该 hook 功能可知其类型应为 pre-receive
我们按照 GitLab 全局配置 Server Hook 文档 将 commit-current-user-check.sh
放在 server hook 的 pre-receive.d
目录下
并添加可执行权限与配置所属者为 git 用户即可
配置 hook 由该 hook 功能可知其类型应为 pre-receive
我们按照 GitLab 全局配置 Server Hook 文档 将 commit-current-user-check.sh
放在 server hook 的 pre-receive.d
目录下
并添加可执行权限与配置所属者为 git 用户即可
1 2 chmod u+x commit -current -user -check.sh chown git:git commit -current -user -check.sh
参考资料 GitLab Server Hooks 文档
GitLab API 文档
GitLab Personal access tokens 文档
GitLab Users API 文档
赞赏
感谢鼓励