引言:為什么我們需要代碼提交前的「安全檢查」?
作為開發(fā)者,你有沒有遇到過這些情況?
不小心把調(diào)試代碼提交到了遠(yuǎn)程倉庫
代碼格式混亂導(dǎo)致團(tuán)隊協(xié)作出現(xiàn)分歧
因為一個簡單的語法錯誤,CI/CD 流水線反復(fù)失敗
甚至無意中把敏感信息(如密鑰)推送到了公開倉庫
這些看似小問題,卻常常浪費團(tuán)隊大量時間和精力。今天我們要聊的 pre-commit 工具,就是解決這些問題的「代碼提交守門員」。
一、pre-commit 是什么?它如何保護(hù)你的代碼質(zhì)量?
理解 pre-commit 的核心概念
pre-commit 是一個 Git 鉤子管理工具,它能在你執(zhí)行 git commit 命令時,自動運行一系列檢查腳本,只有通過這些檢查,代碼才能被成功提交。
簡單來說,它就像是你代碼提交前的一道「安檢門」,幫助你在代碼進(jìn)入版本控制系統(tǒng)前就發(fā)現(xiàn)并解決潛在問題。
pre-commit 的工作原理
它利用 Git 的 pre-commit 鉤子機(jī)制,在代碼提交前攔截操作,運行配置好的檢查項(如代碼格式化、語法檢查、靜態(tài)分析等),幫助開發(fā)者在本地就發(fā)現(xiàn)并解決問題。
具體流程是這樣的:
你執(zhí)行 git commit 命令
pre-commit 鉤子被觸發(fā)
pre-commit 工具運行你配置的所有檢查項
如果所有檢查都通過,commit 操作繼續(xù)執(zhí)行
如果有任何檢查失敗,commit 操作被中止,你需要修復(fù)問題后重新提交
使用 pre-commit 的三大好處
提前發(fā)現(xiàn)問題:在代碼進(jìn)入遠(yuǎn)程倉庫前就解決大多數(shù)質(zhì)量問題,避免把問題帶入后續(xù)流程
統(tǒng)一團(tuán)隊規(guī)范:確保所有提交的代碼都符合團(tuán)隊約定的標(biāo)準(zhǔn),減少代碼審查時關(guān)于格式的討論
減少 CI/CD 失?。罕苊庖虻图夊e誤導(dǎo)致的流水線反復(fù)構(gòu)建,提高開發(fā)效率
二、如何在 Windows 下快速上手 pre-commit?
安裝 pre-commit(Windows 版本)
在 Windows 系統(tǒng)上安裝 pre-commit 非常簡單,只需要幾個步驟:
- 確保已安裝 Python pre-commit 是一個 Python 工具,所以首先需要確保你的系統(tǒng)上已經(jīng)安裝了 Python。你可以通過在命令提示符(CMD)或 PowerShell 中運行以下命令來檢查:
python --version
如果沒有安裝 Python,可以訪問 Python 官方網(wǎng)站 下載最新版本的安裝包,并在安裝時勾選「Add Python to PATH」選項。
- 使用 pip 安裝 pre-commit 打開命令提示符(CMD)或 PowerShell,運行以下命令:
pip install pre-commit
- 驗證安裝是否成功 安裝完成后,運行以下命令來驗證:
pre-commit --version
如果能看到版本號信息,說明 pre-commit 已經(jīng)成功安裝。
創(chuàng)建并配置 pre-commit 配置文件
- 初始化 pre-commit 進(jìn)入你的 Git 項目目錄,在命令提示符或 PowerShell 中運行:
pre-commit install
這個命令會在你的項目的 .git/hooks 目錄下創(chuàng)建 pre-commit 鉤子腳本。
- 創(chuàng)建配置文件 在項目根目錄下創(chuàng)建一個名為
.pre-commit-config.yaml的文件。這是 pre-commit 的核心配置文件,用于定義要運行的檢查項。
一個簡單的配置文件示例:
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
- 理解配置文件結(jié)構(gòu)
repos:包含一個或多個 Git 倉庫,這些倉庫提供 pre-commit 鉤子repo:鉤子倉庫的 URLrev:要使用的鉤子倉庫版本hooks:要使用的鉤子列表id:鉤子的唯一標(biāo)識符
常用的 pre-commit 鉤子推薦
以下是一些在日常開發(fā)中非常實用的 pre-commit 鉤子:
通用檢查類
trailing-whitespace:刪除行尾的空白字符
end-of-file-fixer:確保文件以換行符結(jié)尾
check-yaml:檢查 YAML 文件的語法是否正確
check-added-large-files:避免意外將大文件引入到倉庫
代碼格式化類
black:自動格式化 Python 代碼,確保代碼風(fēng)格一致
black 是一個 Python 代碼格式化工具,它的主要功能是自動格式化 Python 代碼,確保代碼風(fēng)格一致。 注意black只能修復(fù)代碼中的格式問題,不能修復(fù)代碼中的語法錯誤。
安裝依賴:
pip install black==23.3.0
pre-commit 配置如下:
- repo: https://github.com/psf/black
rev: 23.3.0
hooks:
- id: black
isort:自動排序 Python 導(dǎo)入語句
isort 用于自動排序和格式化 Python 文件中的導(dǎo)入語句。它的主要功能包括:
-
分類導(dǎo)入:自動將導(dǎo)入分為三類
標(biāo)準(zhǔn)庫導(dǎo)入
第三方庫導(dǎo)入
本地模塊導(dǎo)入
字母排序 :在每個類別內(nèi)按字母順序排序?qū)?/p>
格式化 :處理導(dǎo)入的格式,如合并相同模塊的導(dǎo)入
安裝依賴:
pip install isort==5.12.0
運行isort:
# 檢查并修改導(dǎo)入語句
isort HelloWorld.py
# 檢查但不修改
isort --check HelloWorld.py
pre-commit 配置如下:
- repo: https://github.com/pycqa/isort
rev: 5.12.0
hooks:
- id: isort
語法檢查類
flake8:檢查 Python 代碼中的語法錯誤和風(fēng)格問題
flake8 主要是一個代碼質(zhì)量檢查工具,它的核心功能是檢測代碼中的語法錯誤、編碼規(guī)范問題、潛在的邏輯問題和代碼質(zhì)量問題,但不提供自動修復(fù)這些問題的能力。 注意:
若有語法錯誤,flake8 會報告錯誤位置和類型,并停止后續(xù)檢測,因此報告語法錯誤時可能還有其他未檢測到的問題。
如果風(fēng)格問題已經(jīng)被black修復(fù),flake8就不會再報告這些問題了,因此推薦將black和flake8結(jié)合使用,使用時要注意先后順序。
安裝依賴:
pip install flake8==6.0.0
檢測語法和代碼風(fēng)格:
# 檢測 flake8_test.py 中的語法錯誤和風(fēng)格問題
flake8 flake8_test.py
# --show-source 顯示錯誤的代碼位置
flake8 --show-source flake8_test.py
pre-commit 配置如下:
- repo: https://github.com/pycqa/flake8
rev: 6.0.0
hooks:
- id: flake8
安全檢查類
detect-secrets:檢測代碼中是否包含敏感信息(如 API 密鑰、密碼等)
detect-secrets 是 Yelp 開發(fā)的一個工具,用于掃描代碼倉庫中可能包含的敏感信息,如 API 密鑰、密碼、證書等。它使用多種啟發(fā)式規(guī)則來識別潛在的敏感信息,并可以幫助團(tuán)隊避免將敏感信息意外提交到代碼倉庫中。
注意:它不是 100% 準(zhǔn)確的,可能會產(chǎn)生誤報或漏報,因此仍然需要人工審查。
安裝依賴:
pip install detect-secrets==1.5.0
檢測敏感信息:
detect-secrets scan
當(dāng)運行 pre-commit run detect-secrets --all-files 時,如果檢測到大量敏感信息(尤其是在 lock 文件中),這是正?,F(xiàn)象,因為這些文件通常包含許多看起來像敏感信息的高熵字符串。 解決方法:
跳過 lock 文件
添加基線文件
跳過 lock 文件
- 可以使用
--exclude-files參數(shù)來排除特定文件
detect-secrets scan --exclude-files "package-lock.json|pnpm-lock.yaml|yarn.lock"
-
在 .pre-commit-config.yaml 中有兩種方式:
添加排除規(guī)則,跳過 lock 文件
使用--exclude-files參數(shù)來排除特定文件
- repo: https://github.com/Yelp/detect-secrets
rev: v1.5.0
hooks:
- id: detect-secrets
# 跳過lock文件,因為它們通常包含大量看起來像敏感信息的高熵字符串
exclude: |
(?x)^(
package-lock.json|
pnpm-lock.yaml|
yarn.lock
)$
# 也可以使用--exclude-files參數(shù)來排除特定文件
args: [--exclude-files, "package-lock.json|pnpm-lock.yaml|yarn.lock"]
添加基線文件
- 初始化基線文件(baseline),記錄當(dāng)前已知的敏感信息,這樣后續(xù)的檢查只會關(guān)注新添加的敏感信息:
# 掃描當(dāng)前目錄下所有被Git跟蹤的文件
detect-secrets scan > .secrets.baseline
# 掃描當(dāng)前目錄下 所有文件 ,包括未被Git跟蹤的文件
detect-secrets scan --all > .secrets.baseline
- 將當(dāng)前代碼狀態(tài)與已有的基線文件進(jìn)行比較,檢測是否引入了新的敏感信息:
detect-secrets scan --baseline .secrets.baseline
- 在
.pre-commit-config.yaml中為detect-secrets鉤子添加參數(shù),指定使用這個 baseline 文件:
- repo: https://github.com/Yelp/detect-secrets
rev: v1.5.0
hooks:
- id: detect-secrets
args: [--baseline, .secrets.baseline]
這樣,pre-commit 就只會報告 baseline 文件中未記錄的新敏感信息,避免每次運行都報告大量已知的誤報,不僅僅是 lock 文件,其他已知的敏感信息也會過濾不再報告。
三、pre-commit 的進(jìn)階技巧與最佳實踐
在團(tuán)隊中推廣 pre-commit
當(dāng)你在個人項目中嘗到 pre-commit 的甜頭后,可能會想要在團(tuán)隊中推廣它。以下是一些實用的推廣技巧:
在項目 README 中添加 pre-commit 安裝指南,確保新成員能夠快速上手
將 pre-commit 配置納入版本控制,確保團(tuán)隊成員使用相同的配置
在 CI/CD 流程中強(qiáng)制執(zhí)行 pre-commit 檢查,可以使用
pre-commit run --all-files命令定期更新鉤子版本,以獲取最新的功能和修復(fù)
開發(fā)自定義 pre-commit 鉤子
當(dāng)現(xiàn)成的鉤子不能滿足你的特定需求時,你可以開發(fā)自己的 pre-commit 鉤子。以下是創(chuàng)建自定義鉤子的基本步驟:
創(chuàng)建一個簡單的腳本,該腳本將執(zhí)行你想要的檢查邏輯
確保腳本具有執(zhí)行權(quán)限(在 Windows 上這一步通常不是必需的)
-
在
.pre-commit-config.yaml中添加自定義鉤子:- repo: local hooks: - id: my-custom-hook name: My Custom Hook entry: path/to/your/script.py language: python types: [python]
與 CI/CD 流程結(jié)合
為了確保代碼質(zhì)量,最好在 CI/CD 流程中也運行 pre-commit 檢查。這樣可以避免有人繞過本地檢查直接提交代碼。
在 CI/CD 配置文件中,你可以添加類似以下的步驟:
jobs:
lint:
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Install pre-commit
run: pip install pre-commit
- name: Run pre-commit checks
run: pre-commit run --all-files
結(jié)論:讓 pre-commit 成為你的代碼質(zhì)量「第一道防線」
pre-commit 不是一個復(fù)雜的工具,但它能為你的項目帶來顯著的質(zhì)量提升。通過在代碼提交前就解決掉大多數(shù)常見問題,你和你的團(tuán)隊可以把更多精力放在真正重要的功能開發(fā)上。
無論是個人項目還是大型團(tuán)隊協(xié)作,pre-commit 都值得嘗試——它可能不會解決所有代碼質(zhì)量問題,但絕對能幫你避免大多數(shù)低級錯誤。
現(xiàn)在就給你的項目加上這道「安全門」吧!打開命令提示符或 PowerShell,按照本文的指南安裝 pre-commit,讓你的代碼提交更有保障。