问题驱动,issueid贯穿始终
强制每个mr必须关联于一个issue
需求:由产品或架构师拆分的功能需求
优化:自测或对现有产品的优化
bug:测试或自测产生的缺陷
依赖:开发的前置设计图,接口等
产品-需求(会被架构师拆分成功能需求)
测试-bug(测试提出的bug)
开发-需求(架构师拆分的产品的需求),优化(开发的技术优化),bug(开发自测发现的bug)
由系统检查mr信息进行规范mr信息
gitlab pre-receive hook服务端配置限制提交代码的备注长度‘
一、相关文章资料
最开始用 Google 搜索到的方案是使用 GitLab 的 Push Rules 功能,具体文档见 这里,看完了我才发现这是企业版独有的,作为比较有逼格(qiong)的我们是不可能接受这种 “没技术含量” 的方式的;后来找了好多资料,发现还得借助 Git Hook 功能,文档见 Custom Git Hooks;简单地说 Git Hook 就是在 git 操作的不同阶段执行的预定义脚本,GitLab 目前仅支持 pre-receive 这个钩子,当然他可以链式调用;所以一切操作就得从这里入手
二、pre-receive 实现
查阅了相关资料得出,在进行 push 时,GitLab 会调用这个钩子文件,这个钩子文件必须放在 /var/opt/gitlab/git-data/repositories/
在进行 push 操作时,GitLab 会调用这个钩子文件,并且从 stdin 输入三个参数,分别为 之前的版本 commit ID、push 的版本 commit ID 和 push 的分支;根据 commit ID 我们就可以很轻松的获取到提交信息,从而实现进一步检测动作;根据 GitLab 的文档说明,当这个 hook 执行后以非 0 状态退出则认为执行失败,从而拒绝 push;同时会将 stderr 信息返回给 client 端;说了这么多,下面就可以直接上代码了,为了方便我就直接用 go 造了一个 pre-receive,官方文档说明了不限制语言
package main
import (
"fmt"
"io/ioutil"
"os"
"os/exec"
"regexp"
"strings"
)
type CommitType string
const (
FEAT CommitType = "feat"
FIX CommitType = "fix"
DOCS CommitType = "docs"
STYLE CommitType = "style"
REFACTOR CommitType = "refactor"
TEST CommitType = "test"
CHORE CommitType = "chore"
PERF CommitType = "perf"
HOTFIX CommitType = "hotfix"
)
const CommitMessagePattern = `^(?:fixup!\s*)?(\w*)(\(([\w\$\.\*/-].*)\))?\: (.*)|^Merge\ branch(.*)`
const checkFailedMeassge = `##############################################################################
## ##
## Commit message style check failed! ##
## ##
## Commit message style must satisfy this regular: ##
## ^(?:fixup!\s*)?(\w*)(\(([\w\$\.\*/-].*)\))?\: (. *)|^Merge\ branch(.*) ##
## ##
## Example: ##
## feat(test): test commit style check. ##
## ##
##############################################################################`
// 是否开启严格模式,严格模式下将校验所有的提交信息格式(多 commit 下)
const strictMode = false
var commitMsgReg = regexp.MustCompile(CommitMessagePattern)
func main() {
input, _ := ioutil.ReadAll(os.Stdin)
param := strings.Fields(string(input))
// allow branch/tag delete
if param[1] == "0000000000000000000000000000000000000000" {
os.Exit(0)
}
commitMsg := getCommitMsg(param[0], param[1])
for _, tmpStr := range commitMsg {
commitTypes := commitMsgReg.FindAllStringSubmatch(tmpStr, -1)
if len(commitTypes) != 1 {
checkFailed()
} else {
switch commitTypes[0][1] {
case string(FEAT):
case string(FIX):
case string(DOCS):
case string(STYLE):
case string(REFACTOR):
case string(TEST):
case string(CHORE):
case string(PERF):
case string(HOTFIX):
default:
if !strings.HasPrefix(tmpStr, "Merge branch") {
checkFailed()
}
}
}
if !strictMode {
os.Exit(0)
}
}
}
func getCommitMsg(odlCommitID, commitID string) []string {
getCommitMsgCmd := exec.Command("git", "log", odlCommitID+".."+commitID, "--pretty=format:%s")
getCommitMsgCmd.Stdin = os.Stdin
getCommitMsgCmd.Stderr = os.Stderr
b, err := getCommitMsgCmd.Output()
if err != nil {
fmt.Print(err)
os.Exit(1)
}
commitMsg := strings.Split(string(b), "\n")
return commitMsg
}
func checkFailed() {
fmt.Fprintln(os.Stderr, checkFailedMeassge)
os.Exit(1)
}
三、安装 pre-receive
把以上代码编译后生成的 pre-receive 文件复制到对应项目的钩子目录即可;要注意的是文件名必须为 pre-receive,同时 custom_hooks 目录需要自建;custom_hooks 目录以及 pre-receive 文件用户组必须为 git:git;在删除分支时 commit ID 为 0000000000000000000000000000000000000000,此时不需要检测提交信息,否则可能导致无法删除分支/tag;最后效果如下所示
原文:https://www.cnblogs.com/franzlistan/p/12580147.html