首页 > 其他分享 >gitlab 服务端 hook,拦截糟糕的提交到仓库

gitlab 服务端 hook,拦截糟糕的提交到仓库

时间:2023-03-13 19:32:16浏览次数:39  
标签:git log format -- gitlab hook 提交 commit 服务端

背景

每当我接收一份新的代码,代码拿到手要做的第一件事就是 git log,看看这份代码的提交记录,最近提交的情况,做了些什么。但往往看到的 git log 杂乱无章,不知道每次提交到底是做了些什么。由此可见,在团队中,CHANGELOG 的重要性不言而喻,不仅有助于他人帮忙 review 代码,熟悉代码,也能高效的输出 CHANGELOG,对项目管理也至关重要。我们本文介绍使用 git 的服务端 hook 来针对 change log 进行校验,拦截不符合我们规范的提交。


服务端 hook 介绍

服务端 git hook 分为三种,分别是 pre-receive、update、post-receive,这三个步骤就是我们本地 push 完代码服务端要做的事情,如图 1 所示:

gitlab 服务端 hook,拦截糟糕的提交到仓库_git

我们可以在 pre-receive 阶段来做提交信息的校验,如果不符合我们的要求,直接返回非 0,则该推送便不会推送到 gitlab 仓库中去。


配置服务端 hook

环境配置

gitlab 版本:13.2

hook 配置

1、找到要配置仓库在 gitlab 中存储的路径,但因 gitlab 的仓库自某个版本开始采用 hash 存储,我们想要知道仓库对应的物理路径,需要到 gitlab 的 postgresql 数据库中的表 project_repositories 中,根据 project_id 能拿到对应的物理路径;

2、当拿到仓库对应的物理路径后,我们打开,目录如下:

gitlab 服务端 hook,拦截糟糕的提交到仓库_推送_02

3、hooks 中是 gitlab 示例的一些钩子,我们需要新建目录 custom_hooks,然后用 vim 新建文件 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 "modify.*")
if [ -z "$flag" ]; then
echo "[ERROR]提交信息校验未通过,需以modify开头"
exit 1
fi

python 版本的脚本如下:

#!/usr/bin/env python
# -*- encoding: utf-8 -*-


import sys, re, datetime
import fileinput
import shlex, subprocess
import dateutil.parser
import pytz




def datestring2timezone(datestring,timeznotallow='Asia/Shanghai',dateformat='%Y-%m-%d %H:%M:%S'):
"""将带有时区的时间统一化规定的时区时间
:param datestring:svn/git时间,eg:2011-01-19T05:13:13.421543Z,2018-11-09 17:38:37 +0800
:param timezone:统一时区,默认是中国时区
:param dateformat:转换成时间格式
:return:
"""
local_time = dateutil.parser.parse(datestring).astimezone(pytz.timezone(timezone)) # 解析string 并转换为北京时区
# print(local_time , type(local_time)) # datetime 类型
da = datetime.datetime.strftime(local_time, dateformat) # 将datetime转换为string
return da




print("Begin check your commit info")
"""获取用户提交的信息"""
origin_commit, curr_commit, branch = None, None, None
# 读取用户试图更新的所有引用
for line in fileinput.input():
line_list = line.strip().split()
if len(line_list) >= 3:
origin_commit, curr_commit, branch = line_list[:3]
break


# TODO: 目前2.27.0版本的git有点问题,在部署的时候需要额外注意
# git_version = subprocess.check_output(shlex.split('git --version'), shell=False)
# print("git version: {}".format(str(git_version)))
# which_git = subprocess.check_output(shlex.split('which git'), shell=False)
# print("which git: {}".format(str(which_git)))


# 获取commit的信息,用户,邮箱,msg等
commit_user = subprocess.check_output(shlex.split('git log --pretty=format:"%an" {} -1'.format(curr_commit)), shell=False)
commit_date = subprocess.check_output(shlex.split('git log --pretty=format:"%cd" {} -1'.format(curr_commit)), shell=False)
commit_msg = subprocess.check_output(shlex.split('git log --pretty=format:"%s" {} -1'.format(curr_commit)), shell=False)




# 针对merge request的请求,取最新一条非merge request的提交信息进行判断
RULE_MERGE_REQUEST = r'^Merge branch .*(into|.*)'
if re.search(RULE_MERGE_REQUEST, str(commit_msg), flags=0):
# 获取最新一条非merge request的commit的信息,用户,邮箱,msg等
commit_user = subprocess.check_output(shlex.split('git log --no-merges --date-order --pretty=format:"%an" -1'), shell=False)
commit_date = subprocess.check_output(shlex.split('git log --no-merges --date-order --pretty=format:"%cd" -1'), shell=False)
commit_msg = subprocess.check_output(shlex.split('git log --no-merges --date-order --pretty=format:"%s" -1'), shell=False)


start_date = "2021-07-07 19:00:00"
# 提交日期大于给定的开始时间才校验
if start_date >= datestring2timezone(commit_date):
sys.exit(0)




if not re.search(r'^JIRA-[0-9]{4,6}', str(commit_msg), flags=0):
print("ERROR:Comment must start with DPT-<ID>. E.g.: DPT-1234")
sys.exit(1)


sys.exit(0)

4、在本地尝试推送,推送显示如下,如果不符合规范则无法提交成功

gitlab 服务端 hook,拦截糟糕的提交到仓库_服务端_03


踩坑

1、gitlab 的不同版本,所安装的 git 版本也会不一致,不同版本的 git 相同的命令的输出也有可能不一致,这点需要特别注意,例如获取非合并请求最新的日志命令,在 git 2.27.0 版本下似乎并不生效。

git log --no-merges --date-order -1

更多

如探索更多关于服务端 hook 的功能,可以与第三方系统,例如 jira 等做交互,打造属于自己团队更适用的工具。


标签:git,log,format,--,gitlab,hook,提交,commit,服务端
From: https://blog.51cto.com/u_11900639/6118112

相关文章

  • Jenkins pipeline vs GitLab pipeline
    前言在整个软件开发过程中,大致有如下的几个工作流程阶段:计划 ->编码->构建->集成->测试->交付->部署 ->运营从上面的工作流程阶段可以看到,整个软件开发周期是......
  • GitLab基本设置-新增用户
    场景在上面将Gitlab部署后的效果如下 注:关注公众号霸道的程序猿获取编程相关电子书、教程推送与免费下载。实现刚搭建完首次登录需要设置root账户的密码。使用root账户登......
  • kafka服务端搭建 无zookeeper
    前言kafka2.8以后得版本可以不依赖zookeeper搭建kafka集群,本文选用kafka3.3.1版本搭建kafka服务端,搭建环境:CentOS7、JDK17无JDK环境参考搭建:​​https://blog.51cto.com/u_......
  • Jenkins&Gitlab持续集成、交付、布署
    1、术语介绍1.1、集成、交付、布署<->CI、CD、CD全称持续集成(ContinuousIntegration)持续交付(ContinuousDelivery)持续布署(ContinuousDeployment)1.2、DevOps介绍......
  • Docker部署gitlab
    Linux环境:centos7.6一、安装git1.安装git yuminstall-ygit2.查看git版本gitversion--3.设置git的账户信息gitconfig--globaluser.name"pss"gitconfig--gl......
  • uni-app:发布为h5站点时服务端的api配置
    一,开发环境中对接口跨域的配置manifest.json中添加"h5":{"devServer":{"https":false,"disableHostCheck":true,......
  • gitlab克隆不显示端口
    1、修改配置文件/opt/gitlab/embedded/service/gitlab-rails/config/gitlab.yml##更改所需端口  2、重启gitlab-ctl restart ......
  • React Hooks源码深度解析
    作者:京东零售郑炳懿前言ReactHooks是React16.8引入的一个新特性,它允许函数组件中使用state和其他React特性,而不必使用类组件。Hooks是一个非常重要的概念,因为它们提......
  • React Hooks源码深度解析
    作者:京东零售郑炳懿前言​​ReactHooks​​是​​React​​16.8引入的一个新特性,它允许函数组件中使用​​state​​和其他React特性,而不必使用类组件。​​Hooks​​......
  • gitlab 配置 ssh keys
    gitlab 配置sshkeys1、生成id_rsa.pubssh-keygen-trsa-C‘email’ 2、.ssh文件夹目录在c:\users\用户名\下,找到id_rsa.pub文件并复制里面的内容  3......