⚠️ Alpha内测版本警告:此为早期内部构建版本,尚不完整且可能存在错误,欢迎大家提Issue反馈问题或建议
Skip to content

8.4.4 代码提交前自动检查——防误提交

.gitignore 是第一道防线,pre-commit 检查是第二道——双重保险防止敏感文件进入仓库。

为什么需要 pre-commit 检查

场景问题解决方案
忘记添加 .gitignore新文件类型被提交自动扫描敏感模式
绕过 .gitignoregit add -f 强制添加hook 拦截
大文件意外提交仓库变臃肿文件大小检查
敏感信息硬编码密钥写在代码里模式匹配检查

使用 husky 配置 pre-commit

安装配置

bash
# 初始化 husky
pnpm add -D husky
pnpm exec husky init

创建敏感文件检查脚本

创建 scripts/check-secrets.sh

bash
#!/bin/bash

# 检查是否有敏感文件被暂存
SENSITIVE_PATTERNS=(
  "\.env$"
  "\.env\.local$"
  "\.pem$"
  "\.key$"
  "id_rsa"
  "\.p12$"
  "credentials\.json"
  "firebase.*\.json"
)

STAGED_FILES=$(git diff --cached --name-only)
FOUND_ISSUES=0

for file in $STAGED_FILES; do
  for pattern in "${SENSITIVE_PATTERNS[@]}"; do
    if [[ $file =~ $pattern ]]; then
      echo "❌ 敏感文件被暂存: $file"
      FOUND_ISSUES=1
    fi
  done
done

if [ $FOUND_ISSUES -eq 1 ]; then
  echo ""
  echo "请使用 'git reset HEAD <file>' 移除敏感文件"
  echo "如果确实需要提交,请使用 'git commit --no-verify'"
  exit 1
fi

echo "✅ 敏感文件检查通过"

配置 pre-commit hook

编辑 .husky/pre-commit

bash
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

# 敏感文件检查
bash scripts/check-secrets.sh

# lint-staged(如果配置了)
pnpm exec lint-staged

检查硬编码的密钥

使用 gitleaks

bash
# 安装 gitleaks
brew install gitleaks

# 在 pre-commit 中添加检查
gitleaks protect --staged

配置 .gitleaks.toml

toml
title = "Gitleaks Config"

[[rules]]
description = "AWS Access Key"
regex = '''AKIA[0-9A-Z]{16}'''
tags = ["aws", "key"]

[[rules]]
description = "OpenAI API Key"
regex = '''sk-[a-zA-Z0-9]{48}'''
tags = ["openai", "key"]

[[rules]]
description = "Generic Password"
regex = '''(?i)(password|pwd|pass)\s*[:=]\s*['"][^'"]{8,}['"]'''
tags = ["password"]

大文件检查

bash
#!/bin/bash
# scripts/check-file-size.sh

MAX_SIZE=5000000  # 5MB

STAGED_FILES=$(git diff --cached --name-only)

for file in $STAGED_FILES; do
  if [ -f "$file" ]; then
    SIZE=$(wc -c < "$file")
    if [ $SIZE -gt $MAX_SIZE ]; then
      echo "❌ 文件过大: $file ($(( SIZE / 1000000 ))MB)"
      echo "考虑使用 Git LFS 或添加到 .gitignore"
      exit 1
    fi
  fi
done

echo "✅ 文件大小检查通过"

CI 层面的检查

即使本地绕过了 hook,CI 也要有最后一道防线。

GitHub Actions 检查

yaml
# .github/workflows/security.yml
name: Security Check

on: [push, pull_request]

jobs:
  secrets-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Gitleaks Scan
        uses: gitleaks/gitleaks-action@v2
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

  check-ignored-files:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Check for sensitive files
        run: |
          SENSITIVE_FILES=$(find . -type f \( \
            -name ".env" \
            -o -name ".env.local" \
            -o -name "*.pem" \
            -o -name "*.key" \
            -o -name "id_rsa" \
          \) 2>/dev/null)
          
          if [ -n "$SENSITIVE_FILES" ]; then
            echo "::error::Found sensitive files in repository:"
            echo "$SENSITIVE_FILES"
            exit 1
          fi

完整 pre-commit 配置

bash
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

echo "🔍 Running pre-commit checks..."

# 1. 敏感文件检查
echo "Checking for sensitive files..."
bash scripts/check-secrets.sh || exit 1

# 2. 大文件检查
echo "Checking file sizes..."
bash scripts/check-file-size.sh || exit 1

# 3. 密钥扫描(如果安装了 gitleaks)
if command -v gitleaks &> /dev/null; then
  echo "Scanning for secrets..."
  gitleaks protect --staged || exit 1
fi

# 4. 代码格式化和 lint
echo "Running lint-staged..."
pnpm exec lint-staged || exit 1

echo "✅ All pre-commit checks passed!"

验收清单

  • [ ] 配置了敏感文件的 pre-commit 检查
  • [ ] 可选:配置了 gitleaks 密钥扫描
  • [ ] 可选:配置了大文件检查
  • [ ] 配置了 CI 层面的安全扫描