Featured image of post 用於自動化的 Git Hooks:超越程式碼質量Featured image of post 用於自動化的 Git Hooks:超越程式碼質量

用於自動化的 Git Hooks:超越程式碼質量

探索用於自動化的 Git 掛鉤,涵蓋預提交、預先推送、提交訊息掛鉤、husky、lint-staged、自訂腳本、共享掛鉤和 CI 等效項。

介紹

Git 掛鉤是可執行腳本,在 Git 生命週期中的特定積分處自動執行。雖然許多開發人員僅將它們與程式碼格式化和 linting 聯繫起來,但它們的潛力遠遠超出了工作流程自動化、專案管理和團隊協作。本文探討如何利用 Git hook 來實現全面的自動化策略。

了解 Git Hook

Git 掛鉤駐留在每個儲存庫的 .git/hooks/ 目錄中。它們是用任何語言(bash、Python、Node.js 或 Ruby)編寫的標準可執行腳本。鉤子分為兩類:在開發人員的機器上運行的客戶端鉤子(預提交、預推送、提交訊息),以及在遠端儲存庫上執行的伺服器端鉤子(預接收、更新、後接收)。

鉤子生命週期按時間順序跟隨 Git 操作。在提交期間,掛鉤會依照下列順序執行:pre-commitcommit-msgpost-commit。對於推送,順序為 pre-push(客戶端)→ pre-receiveupdatepost-receive(伺服器)。

與 Husky 設定 Hook

透過將腳本放置在 .git/hooks/ 中來手動管理掛鉤對於團隊來說是不切實際的,因為 Git 不追蹤該目錄。 Husky 透過允許在儲存庫中配置掛鉤並在團隊中共享來解決這個問題。

Husky v9+ 的安裝非常簡單:

npx husky init

這將建立一個 .husky/ 目錄,其中掛鉤腳本是純文字檔案:

# .husky/pre-commit
npx lint-staged

對於 CI 環境,可以透過設定 HUSKY=0 來跳過鉤子:

HUSKY=0 git push

整合 lint-staged

Lint-staged 僅在暫存檔案上執行 linter,從而保持快速的預提交檢查:

{
  "lint-staged": {
    "*.{ts,tsx}": ["eslint --fix", "prettier --write"],
    "*.{css,scss}": ["stylelint --fix", "prettier --write"]
  }
}

預提交掛鉤:第一道防線

預提交掛鉤在每次提交之前執行,非常適合快速、本地化檢查。

檢查類型工具目的
絨毛ESLint、stylelint執行程式碼風格標準
格式化更漂亮,dprint一致地自動格式化程式碼
類型檢查打字稿 --noEmit及早發現類型錯誤
秘密偵查Secretlint,松露Hog防止憑證外洩
檔案驗證自訂腳本封鎖大檔案或 TODO 提交

全面的預提交配置:

# .husky/pre-commit
npx lint-staged
npx tsc --noEmit
npx secretlint "**/*"

效能至關重要 - 預提交掛鉤應在五秒鐘內完成,以避免中斷開發流程。


預推掛鉤:CI 安全網

預推送掛鉤在程式碼到達遠端儲存庫之前運行,這使得它們非常適合長時間運行的驗證:

# .husky/pre-push
npm test
npm run build
npm audit

分支命名驗證確保整個團隊的一致性:

#!/bin/sh
branch=$(git rev-parse --abbrev-ref HEAD)
if ! echo "$branch" | grep -qE '^(feature|bugfix|hotfix)/[A-Z]+-[0-9]+-'; then
  echo "Error: Branch name must match feature/ABC-123-description"
  exit 1
fi

使用 commitlint 進行提交訊息掛鉤

強制執行傳統的提交訊息可確保一致的、可解析的歷史記錄。將 commitlint 與 Husky 一起使用:

# .husky/commit-msg
npx --no -- commitlint --edit $1

commitlint.config.js 中配置 commitlint:

module.exports = {
  extends: ['@commitlint/config-conventional'],
  rules: {
    'subject-max-length': [2, 'always', 50],
    'body-max-line-length': [2, 'always', 72],
  },
};

有效的提交訊息遵循 <type>(<scope>): <description> 格式:

feat(auth): implement OAuth 2.0 refresh token rotation
fix(api): handle null pointer in user deserialization
docs(readme): update installation instructions

提交後和合併後掛鉤

合併後掛鉤對於依賴管理特別有用。當鎖定檔案變更時自動安裝更新的依賴項:

# .husky/post-merge
changed=$(git diff HEAD~1 --name-only)
if echo "$changed" | grep -q "pnpm-lock.yaml"; then
  pnpm install
fi

CI 等效策略

最穩健的模式可確保鉤子和 CI 運行相同的檢查。提取兩個環境呼叫的共享腳本:

#!/bin/sh
# scripts/validate.sh - called by both hooks and CI
npm run lint
npm run typecheck
npm test

本地鉤子應該在可能的情況下發出警告或自動修復,而 CI 則嚴格執行。這創建了一個安全網:開發人員在推送之前發現問題,而 CI 捕獲任何漏掉的東西。


結論

Git hooks 是一個強大的自動化層,其功能遠遠超出了程式碼格式化的範圍。將 Husky 與 lint-staged 結合起來為大多數項目提供了建議的基線。預推送鉤子在程式碼到達 CI 之前添加了一個安全網,並且 commitlint 確保了乾淨、可解析的提交歷史記錄。最終目標是提供無縫的開發人員體驗,其中自動化處理重複檢查,使團隊能夠專注於邏輯和設計。