Git钩子脚本如何检查健壮性门禁

wen 实用脚本 2

本文目录导读:

Git钩子脚本如何检查健壮性门禁

  1. 核心检查项设计
  2. 完整 pre-commit 脚本示例
  3. pre-push 脚本(更严格的检查)
  4. 配置管理最佳实践
  5. 常见问题处理
  6. 推荐配置模板

Git钩子脚本检查“健壮性门禁”通常指在代码提交前(pre-commit)或推送前(pre-push)自动运行一系列静态分析、单元测试或安全检查,以下是实现这一目标的完整方案:

核心检查项设计

代码质量门禁

# pre-commit 示例:检查代码风格和潜在错误
#!/bin/bash
set -e
echo "🔍 开始代码质量检查..."
# ESLint/TSLint 检查(JavaScript/TypeScript)
if [ -f "node_modules/.bin/eslint" ]; then
    npm run lint || {
        echo "❌ 代码风格检查未通过"
        exit 1
    }
fi
# Pylint/Flake8 检查(Python)
if command -v flake8 &> /dev/null; then
    flake8 . --max-line-length=120 || {
        echo "❌ Python 代码规范检查未通过"
        exit 1
    }
fi
# Checkstyle(Java)
if [ -f "gradlew" ]; then
    ./gradlew checkstyleMain || {
        echo "❌ Java 代码风格检查未通过"
        exit 1
    }
fi

单元测试门禁

# 运行单元测试 - 覆盖率要求
run_tests() {
    local min_coverage=80  # 最低覆盖率要求
    if [ -f "package.json" ]; then
        npm test -- --coverage --coverageThreshold="{\"global\":{\"lines\":$min_coverage}}"
    elif [ -f "pytest.ini" ]; then
        pytest --cov=. --cov-fail-under=$min_coverage
    elif [ -f "build.gradle" ]; then
        ./gradlew jacocoTestReport
    fi
    if [ $? -ne 0 ]; then
        echo "❌ 单元测试未通过或覆盖率不足 $min_coverage%"
        exit 1
    fi
}

安全扫描门禁

# 依赖安全扫描
check_security() {
    echo "🔒 运行安全扫描..."
    # npm 审计
    if [ -f "package-lock.json" ]; then
        npm audit --audit-level=high || {
            echo "❌ 发现高危安全漏洞"
            exit 1
        }
    fi
    # Bandit (Python)
    if command -v bandit &> /dev/null; then
        bandit -r . -ll || {
            echo "❌ 发现 Python 安全漏洞"
            exit 1
        }
    fi
    # OWASP Dependency Check (Java)
    if [ -f "pom.xml" ]; then
        mvn org.owasp:dependency-check-maven:check || exit 1
    fi
}

静态分析门禁

# 静态代码分析
run_static_analysis() {
    echo "📊 运行静态代码分析..."
    # SonarQube (需要配置)
    if command -v sonar-scanner &> /dev/null; then
        sonar-scanner -Dsonar.qualitygate.wait=true || {
            echo "❌ SonarQube 质量门禁未通过"
            exit 1
        }
    fi
    # Infer (Facebook)
    if command -v infer &> /dev/null; then
        infer -- pom.xml || exit 1
    fi
}

完整 pre-commit 脚本示例

#!/bin/bash
# .git/hooks/pre-commit
set -euo pipefail
# 配置
MIN_COVERAGE=80
FAIL_ON_WARNING=true
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM)
echo "========================================"
echo "  开始执行 Git 健壮性门禁检查"
echo "========================================"
# 1. 语法检查
check_syntax() {
    echo "[1/5] 语法检查..."
    for file in $STAGED_FILES; do
        case "$file" in
            *.js|*.jsx|*.ts|*.tsx)
                npx eslint --quiet "$file" || exit 1
                ;;
            *.py)
                python -m py_compile "$file" || exit 1
                ;;
            *.java)
                javac -version > /dev/null 2>&1 && javac "$file" || exit 1
                ;;
        esac
    done
}
# 2. 单元测试(仅跑受影响的测试)
run_affected_tests() {
    echo "[2/5] 运行单元测试..."
    if [ -f "jest.config.js" ]; then
        # 仅测试受变更影响的模块
        affected_modules=$(echo "$STAGED_FILES" | grep -E '\.(js|ts)$' | sed 's/\.[^.]*$//')
        if [ -n "$affected_modules" ]; then
            npx jest --findRelatedTests $affected_modules --coverage || exit 1
        fi
    fi
}
# 3. 代码规范检查
check_code_style() {
    echo "[3/5] 代码规范检查..."
    if command -v prettier &> /dev/null; then
        npx prettier --check $STAGED_FILES || {
            echo "格式错误,使用 npx prettier --write 自动修复"
            exit 1
        }
    fi
}
# 4. 大文件检查(防止过大文件提交)
check_file_size() {
    echo "[4/5] 文件大小检查..."
    local max_size=1048576  # 1MB
    for file in $STAGED_FILES; do
        size=$(stat -c%s "$file" 2>/dev/null || echo 0)
        if [ "$size" -gt "$max_size" ]; then
            echo "❌ 文件 $file 超过 1MB"
            exit 1
        fi
    done
}
# 5. 密钥泄露检查
check_secrets() {
    echo "[5/5] 密钥泄露检查..."
    if command -v detect-secrets &> /dev/null; then
        detect-secrets scan $STAGED_FILES || exit 1
    elif command -v trufflehog &> /dev/null; then
        trufflehog --files $STAGED_FILES || exit 1
    else
        # 简单正则检查
        grep -E -i "(password|secret|token|api_key)" $STAGED_FILES && {
            echo "⚠️ 发现可能的敏感信息"
            exit 1
        }
    fi
}
# 执行所有检查
check_syntax
run_affected_tests
check_code_style
check_file_size
check_secrets
echo "========================================"
echo "✅ 所有健壮性检查通过!"
echo "========================================"

pre-push 脚本(更严格的检查)

#!/bin/bash
# .git/hooks/pre-push
set -euo pipefail
# 推送时执行更完整的检查
echo "🚀 推送前全面验证..."
# 1. 全量测试
if [ -f "gradlew" ]; then
    ./gradlew clean test || exit 1
fi
# 2. 集成测试
if [ -f "docker-compose.yml" ]; then
    docker-compose run --rm integration-tests || exit 1
fi
# 3. 构建检查
if [ -f "pom.xml" ]; then
    mvn clean verify || exit 1
fi
# 4. 安全扫描
if [ -f "package-lock.json" ]; then
    npm audit --audit-level=moderate || exit 1
fi
# 5. 质量网关(集成sonarqube)
if command -v sonar-scanner &> /dev/null; then
    sonar-scanner -Dsonar.qualitygate.wait=true || exit 1
fi
echo "✅ 推送前检查通过,可以推送!"

配置管理最佳实践

跳过检查(紧急修复时)

# 允许绕过(需谨慎使用)
SKIP_CHECKS="" git commit -m "紧急修复"
# 或设置环境变量
export CI=true  # 部分工具会跳过检查

性能优化

# 增量检查(仅检查变更文件)
changed_files=$(git diff --name-only --cached)
# 并行执行检查
run_parallel() {
    pids=""
    for check in "$@"; do
        $check &
        pids+=" $!"
    done
    for pid in $pids; do
        wait $pid || exit 1
    done
}

团队统一管理(使用 Husky)

// package.json
{
  "husky": {
    "hooks": {
      "pre-commit": "npm run lint-staged && npm test -- --coverage=80",
      "pre-push": "npm run full-test && npm audit"
    }
  },
  "lint-staged": {
    "*.{js,ts,vue}": ["eslint --fix", "prettier --write"],
    "*.py": ["black --check", "flake8"]
  }
}

自定义跳过机制

# 支持通过 commit message 标记跳过
if [[ "$(head -1 .git/COMMIT_EDITMSG)" == *"[skip ci]"* ]]; then
    echo "🔄 跳过CI检测"
    exit 0
fi

常见问题处理

钩子执行失败排查

# 查看详细错误
bash -x .git/hooks/pre-commit
# 临时禁用钩子
git commit --no-verify

跨平台兼容

# 使用 shebang 指定解释器
#!/usr/bin/env bash
# 检测操作系统
case "$(uname -s)" in
    Darwin*)  # macOS
        stat -f%z "$file"
        ;;
    Linux*)   # Linux
        stat -c%s "$file"
        ;;
esac

推荐配置模板

检查项 工具 优先级 执行阶段
语法检查 ESLint/Pylint pre-commit
代码格式化 Prettier/Black pre-commit
单元测试 Jest/Pytest pre-commit
测试覆盖率 Istanbul/Coverage pre-push
安全扫描 npm audit/Bandit pre-push
密钥检测 detect-secrets pre-commit
文件大小 自定义命令 pre-commit

这样配置的 Git 钩子系统可以在开发流程早期拦截问题,显著提高代码库的健壮性,记住根据团队实际情况调整检查的严格程度和覆盖范围。

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