Git钩子脚本如何检查发布管理

wen 实用脚本 1

本文目录导读:

Git钩子脚本如何检查发布管理

  1. 环境准备:项目配置文件
  2. 核心钩子场景与脚本示例
  3. 高级发布管理钩子组合
  4. 推荐的完整发布流程钩子配置
  5. 注意事项与最佳实践
  6. 最终示例:结合 Husky 的发布检查脚本

Git 钩子脚本可以通过在 Git 操作的关键节点(如提交、推送、合并)执行自定义检查,来实现发布管理(Release Management)的自动化质量控制,以下是几种核心的检查策略和脚本实现思路。

核心检查目标通常包括:

  1. 版本号一致性:确保代码版本号(如 package.jsonVERSION 文件)与 Git Tag 或分支名匹配。
  2. 变更日志检查:确保本次发布有对应的 CHANGELOG.md 记录。
  3. 代码质量与安全:运行测试、代码风格检查、依赖安全审计。
  4. 分支策略合规:确保只能从特定的分支(如 develop)合并到发布分支(如 releasemain)。

环境准备:项目配置文件

为了让脚本更灵活,建议在项目根目录创建一个 .releaserc 或类似配置文件(release-config.json),定义版本号文件、路径等。

示例 release-config.json:

{
  "versionFile": "package.json",
  "changelogFile": "CHANGELOG.md",
  "releaseBranchPattern": "release/*",
  "mainBranch": "main",
  "developBranch": "develop"
}

核心钩子场景与脚本示例

Pre-commit 钩子 — 检查版本号文件是否未提交修改

适用时机:在创建发布分支后,对版本号文件进行修改并提交时。

脚本 .git/hooks/pre-commit (需要 chmod +x):

#!/bin/bash
# 检查本次提交是否修改了版本号文件,如果修改了,需确保有对应的 CHANGELOG 更新
# 读取配置 (简化示例,未读取JSON)
VERSION_FILE="package.json"
CHANGELOG_FILE="CHANGELOG.md"
# 检查暂存区是否包含版本号文件
if git diff --cached --name-only | grep -q "$VERSION_FILE"; then
    # 检查暂存区是否也包含了 CHANGELOG 文件
    if ! git diff --cached --name-only | grep -q "$CHANGELOG_FILE"; then
        echo "❌ 错误: 你修改了 $VERSION_FILE,请同时更新 $CHANGELOG_FILE 并提交。"
        exit 1
    fi
fi
exit 0

Pre-push 钩子 — 检查分支合规性与版本号验证

适用时机:开发者将发布分支推送到远程时,这是发布管理中最常用且最重要的钩子。

脚本 .git/hooks/pre-push:

#!/bin/bash
# 参数: 远程名称 远程URL
remote="$1"
url="$2"
# 读取标准输入获取本地/远程引用信息
while read local_ref local_sha remote_ref remote_sha
do
    # 只检查推送的引用是否为分支,且不是删除操作
    if [[ "$local_ref" =~ ^refs/heads/ && "$remote_sha" != "0000000000000000000000000000000000000000" ]]; then
        branch_name="${local_ref#refs/heads/}"
        # 1. 检查是否向 main 或 release 分支推送
        if [[ "$branch_name" == "main" || "$branch_name" == "release"* ]]; then
            echo "🔒 禁止直接推送至 $branch_name 分支"
            echo "   请通过 Pull Request 合并到该分支"
            exit 1
        fi
        # 2. 如果是 release/* 分支推送,检查版本号和 Tag
        if [[ "$branch_name" == release/* ]]; then
            echo "🚀 检测到发布分支推送: $branch_name"
            # 提取版本号 (假设分支名格式为 release/v1.2.3)
            version_from_branch=$(echo "$branch_name" | cut -d'/' -f2)
            # 读取 package.json 中的版本号 (使用 node 或 awk)
            version_from_file=$(node -p "require('./package.json').version")
            if [[ "$version_from_branch" != "v$version_from_file" && "$version_from_branch" != "$version_from_file" ]]; then
                echo "❌ 错误: 分支名版本 ($version_from_branch) 与 package.json 版本 ($version_from_file) 不匹配"
                exit 1
            fi
            # 选择: 检查 CHANGELOG
            if ! grep -q "$version_from_branch" CHANGELOG.md; then
                echo "❌ 错误: CHANGELOG.md 中未找到版本 $version_from_branch 的更新记录"
                exit 1
            fi
            echo "✅ 发布分支检查通过"
        fi
    fi
done
exit 0

Post-commit 钩子 — 版本号自动校验与 Tag 前置检查

适用时机:在提交完成后,检查是否满足打 Tag 的条件。

脚本 .git/hooks/post-commit (辅助角色):

#!/bin/bash
# 获取当前分支名
branch=$(git rev-parse --abbrev-ref HEAD)
# 只在 release 分支上执行
if [[ "$branch" == release/* ]]; then
    version=$(node -p "require('./package.json').version")
    echo "🔔 提示: 当前分支 '$branch' (版本 $version)"
    echo "   如果你打算为本次发布打 Tag,请确保:"
    echo "   1. 所有测试已通过 (运行 npm test)"
    echo "   2. CHANGELOG.md 已更新完整"
fi
exit 0

高级发布管理钩子组合

为了确保发布流程的严谨性,推荐使用 Prepare-commit-msgCommit-msg 钩子来标准化提交信息,以便自动化生成变更日志。

Commit-msg 钩子 — 强制提交信息包含 Issue 或 Change 类型

脚本 .git/hooks/commit-msg:

#!/bin/bash
commit_message_file="$1"
commit_message=$(cat "$commit_message_file")
# 检查提交信息格式 ( "fix: #123 修复登录bug")
# 用于 release 分支的提交,必须包含类型前缀
if ! echo "$commit_message" | grep -qE "^(feat|fix|chore|docs|refactor|test):"; then
    echo "❌ 提交信息格式错误,必须包含类型前缀: feat, fix, chore, docs, refactor, test"
    echo "   示例: fix: #123 修复登录页面崩溃"
    exit 1
fi
exit 0

推荐的完整发布流程钩子配置

执行阶段 钩子名 主要职责 失败时后果
提交前 pre-commit 运行单元测试、代码格式化检查 不允许提交
提交时 commit-msg 检查提交信息格式(类型+描述) 不允许提交
推送前 pre-push 检查分支合规、版本号一致性、CHANGELOG 推送中断
合并后 post-merge (可选) 自动打 Tag、触发 CI/CD 仅提示

注意事项与最佳实践

  1. 钩子共享性差.git/hooks 目录默认不提交到 Git 仓库,团队需要手动配置或使用工具(如 huskypre-commit)来统一管理。
  2. 脚本健壮性
    • 使用 #!/bin/bash 而不是 #!/bin/sh,因为 bash 支持更多条件判断和数组特性。
    • 使用 set -e 让脚本在遇到错误时立即退出。
    • 对所有外部输入(如分支名)进行转义或正则匹配。
  3. 跳过钩子:提供紧急跳过机制,但严格限制。
    • 使用 git commit -n 跳过 pre-commit 钩子。
    • 使用 git push --no-verify 跳过 pre-push 钩子。
    • 最佳实践:记录跳过行为,例如在 CI/CD 环境变量中设置 SKIP_RELEASE_CHECK=1 作为替代方案。
  4. 使用工具简化管理
    • Husky (Node.js项目):npx husky add .husky/pre-push "bash scripts/check-release.sh"
    • pre-commit (Python/多语言):通过 .pre-commit-config.yaml 配置。
  5. 与 CI/CD 协同:Git 钩子负责本地快速检查(难以绕过),但最终的质量门禁(如 Tag 签名、二进制构建)应在 GitHub Actions / GitLab CI 中执行。

最终示例:结合 Husky 的发布检查脚本

使用 Husky 简化后,你的 ./husky/pre-push 文件内容如下(假设脚本在 scripts/ 目录):

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
# 运行发布检查脚本
bash scripts/check-release.sh

scripts/check-release.sh 则包含上述 pre-push 的完整逻辑。

通过以上配置,Git 钩子脚本能够有效拦截不规范的操作,确保发布版本的版本号、变更日志和分支策略严格一致,从而提升代码发布的稳定性和可追溯性。

上一篇Git钩子脚本如何检查变更管理

下一篇当前分类已是最新一篇

抱歉,评论功能暂时关闭!