Git 工作流中的 日志采集 最佳实践
前阵子项目要发版,让我整理一份更新日志。我打开 git log 一看,几百条 commit,"fix"、"update"、“改了个bug” 全混在一起,中间还夹着几十条 merge commit,看得我头大。手动整理是不可能的,这辈子都不可能手动整理的,于是就想办法把这件事自动化掉。
网上搜了一圈,什么 conventional commits、semantic-release,工具一个比一个重,配置文件写得比我业务代码还长,我就想要个变更列表而已... 最后决定用 git 原生的东西自己攒一套轻量方案,实测几个月下来够用,下面分享出来。
第一步:先把 commit message 规范起来
日志采集的前提是日志本身能看。如果团队里有人写 fix bug,有人写 修复了那个谁上次说的那个问题,那采集出来的东西基本没法用,等于白采。
我们用的是最简单的约定:commit 开头带类型前缀,feat:、fix:、docs:、refactor:、chore:,后面跟一句人话描述。不搞 scope,不搞 breaking change 标记,太复杂了没人遵守,等于没有规范。
光靠约定肯定不行,得在 hook 里卡一下。在 .git/hooks/commit-msg 里加上:
#!/bin/sh
msg=$(cat "$1")
if ! echo "$msg" | grep -qE '^(feat|fix|docs|refactor|test|chore): .+'; then
echo "commit 格式不对,参考:feat: 增加了xxx功能"
exit 1
fi
记得 chmod +x .git/hooks/commit-msg,不然 hook 不会执行。这个坑我踩过,还查了半天为什么校验没生效,最后发现是权限问题...
另外 hook 只存在本地,别人 clone 下来是没有的。可以把这个脚本放进仓库的 .githooks/ 目录,然后让大家执行一次 git config core.hooksPath .githooks,一劳永逸。
用 git log 把日志捞出来
规范有了,采集就简单了,核心就是 --pretty=format 自定义输出:
git log --pretty=format:"%h %s" v1.2.0..HEAD --no-merges
v1.2.0..HEAD 表示只取上个 tag 之后的提交,--no-merges 把 merge commit 过滤掉,不然输出里全是 Merge branch 'xxx' into dev,一点信息量都没有。
发版说明里如果只想要新功能和修复,接个 grep 就行:
git log --pretty=format:"%s" v1.2.0..HEAD --no-merges | grep -E '^(feat|fix)'
%s 是 commit 的第一行,想带作者就加 %an,想带日期就加 %ad --date=short,按需拼。
攒成一个脚本,一条命令出日志
每次手敲命令还是麻烦,我直接写了个 gen-changelog.sh 放在仓库根目录:
#!/bin/bash
LAST_TAG=$(git describe --tags --abbrev=0)
echo "## 更新内容($LAST_TAG 之后,$(date +%F) 生成)"
echo ""
echo "### 新功能"
git log --pretty=format:"- %s(%an)" "$LAST_TAG..HEAD" --no-merges | grep '^feat' | sed 's/^feat: //'
echo ""
echo "### 问题修复"
git log --pretty=format:"- %s(%an)" "$LAST_TAG..HEAD" --no-merges | grep '^fix' | sed 's/^fix: //'
跑一下 ./gen-changelog.sh > CHANGELOG.md,一份像模像样的更新日志就出来了。git describe --tags --abbrev=0 会自动找最近的 tag,不用每次手动改版本号。如果想按时间取,把范围换成 --since="2024-01-01" 之类的也行。
构建日志也顺手采一下
commit 日志之外,CI 上的构建日志也值得留底。我们的做法是在流水线脚本里把构建输出重定向到带时间戳的文件:
./build.sh 2>&1 | tee "build-$(date +%Y%m%d-%H%M%S).log"
tee 会同时输出到终端和文件,CI 界面上能看,本地也留了一份。构建挂了直接把这个文件甩给同事,比截图清楚多了。记得在 .gitignore 里加一行 *.log,不然这些日志文件哪天手一抖就被提交进去了。
最后
这套东西没什么高深的,全是 git 原生命令加几十行 shell,但实际用下来,发版整理日志从半小时变成十秒钟。工具不在重,够用就行。唯一的“维护成本”是偶尔有人 commit 格式写错被 hook 拦下来,会跑来抱怨两句,不过抱怨着抱怨着就习惯了,现在大家的 commit message 终于能看了,这波不亏。
评论
还没有评论。
发表评论
提交后评论将经过自动审核,审核通过后公开展示。