本文目录导读:

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 钩子系统可以在开发流程早期拦截问题,显著提高代码库的健壮性,记住根据团队实际情况调整检查的严格程度和覆盖范围。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播