約定式提交 (Conventional Commits)
Conventional Commits 是一種 commit message 的規範, 透過統一的格式來描述 commit 的內容, 並且可以透過 commit message 來自動生成 changelog, 並且可以透過 commit message 來自動判斷版本號
參考 https://www.conventionalcommits.org 來給予 commit 的訊息更多語義的格式規範
常見類型
-
feat: 表示新增了一個新功能或者在項目中加入或修改了顯著的新內容
-
fix: 用於修復 bug
-
docs: 僅僅更改了文件, 用於沒有改動程式碼的文件更新
-
style: 不影響程式碼含義的更改 (空格, 格式化, 缺少分號, coding style...etc.)
-
refactor: 重構現有的程式碼, 既不修正 bug 也不添加功能, 通常指修改程式碼以提高可讀性, 簡化結構或改善性能, ex:
- remove unused code
-
perf: 用於提高程式效能的更改
-
test: 新增或修改測試
-
build: 影響 build or deps 的更改 (ex: npm, gulp)
-
ci: 與 ci/cd 相關的配置文件或 scripts (ex: GitHub actions workflow)
-
chore: 其他不修改 src 或 test 文件的更改, ex:
- storybook, eslint, prettier, husky, lint-staged...etc.
- console.log, debugger
- 版號更新: chore(release): v1.0.0
- console.log (或自定義 type)
-
revert: 用於撤銷之前的 commit
-
也可以自訂特定於團隊自己約定的類型, ex: debug (如果團隊有這樣的約定), 可以用來開發中臨時需要增加 log 做測試的情況
影響範圍
影響範圍可以是可以是元件、檔名或或特定的功能, 以 monorepo 來說也可以針對各別 project 來做區分, 區分方式是用括號包起來, 例如:
- feat(client): add login button
- fix(server): fix require lodash not defined
- feat(client/login): add login page
- fix(client/SomeFeature): fix SomeFeature return error
BREAKING CHANGE
用於重大變更, 或可能會破壞現有程式碼的變更, 通常會在描述中加入 BREAKING CHANGE:
來描述變更的內容, 通常有兩種方式:
-
在 commit msg 底部:
feat: allow provided config object to extend other configs
BREAKING CHANGE: `extends` key in config file is now used for extending other config files -
在類型加上
!
來表示重大變更feat!: allow provided config object to extend other configs
關聯 issue
可以在 commit msg 中加入關聯的 issue/ticket, ex:
- feat: add login page #123
Commitizen
Commitizen 是一個幫助我們撰寫符合約定式提交規範的 commit message 的工具, 透過命令列的方式來引導我們撰寫 commit message, 並且可以透過 git cz 來取代 git commit 來使用
安裝 Commitizen
pnpm add commitizen -D
將 Commitizen 的指令 cz 加入 package.json 的 scripts 中
{
"scripts": {
"commit": "git cz"
}
}
或者使用 cz-conventional-changelog
adapter 來執行 Commitizen:
pnpm add cz-conventional-changelog -D
並且在 package.json 中加入以下設定:
{
"config": {
"commitizen": {
"path": "cz-conventional-changelog"
}
}
}
執行 scripts
後就可以在 cmd 中透過 Commitizen 的方式來撰寫 commit message, 全部回答完後會產生一個符合約定式提交規範的 commit message, 並且會自動 commit
Commitlint
Commitlint 是一個用來檢查 commit message 是否符合約定式提交規範的工具, 透過使用正規表達式來檢查 commit message 是否符合規範, 並且可以透過 git hooks 來在 commit 時檢查 commit message
Husky
Husky 是一個用來設定 git hooks 的工具, 可以透過 husky 來設定 pre-commit hook 在 commit 時檢查 commit message 是否符合約定式提交規範, 或者在提交前執行 lint, test 等操作
Commitizen + Commitlint + Husky 結合一起使用
安裝
pnpm add husky commitizen @commitlint/cli @commitlint/config-conventional -D
搭配 @commitlint/cz-commitlint 使用
pnpm add @commitlint/cz-commitlint -D
並且在 package.json 中加入以下設定:
{
"config": {
"commitizen": {
"path": "@commitlint/cz-commitlint"
}
}
}
-
初始化 husky 產生
.husky
:pnpm exec husky init
-
新增
commitlint.config.js
來配置 commitlint 設定:module.exports = { extends: ['@commitlint/config-conventional'] };
-
設置 husky
prepare-commit-msg
hook:#!/usr/bin/env sh
if [ -t 0 ]; then
# 如果在終端中運行
exec < /dev/tty && [ -z "$(cat "$1")" ] && pnpm exec cz --hook || true
else
# 如果在 GUI 中運行
[ -z "$(cat "$1")" ] && pnpm exec cz --hook || true
fi用於在 Git 提交過程中自動觸發 Commitizen cmd, 以便生成符合特定格式的 commit msg
-
設置 husky
pre-commit
hook 並搭配eslint-staged
:pre-commit hook:
#!/usr/bin/env sh
# lint-staged
echo "Running lint-staged..."
pnpm exec lint-staged
# if lint-staged fails, don't commit
if [ $? != 0 ]; then
echo "Linting failed, commit aborted"
exit 1
filint-staged:
pnpm add lint-staged -D
package.json:
{
"lint-staged": {
"apps/cas-server/*.{js,jsx,ts,tsx}": ["turbo run lint --filter cas-server --"],
"apps/vite-demo/*.{js,jsx,ts,tsx}": ["turbo run lint --filter vite-demo --", "turbo run lint:css --filter vite-demo --"],
"apps/**/*.{js,jsx,ts,tsx}": ["pnpm run format"],
"apps/**/*.{css,scss}": ["pnpm run format", "turbo run lint:css --"],
"apps/**/*.{html,md}": ["pnpm run format"]
}
}因為每個需要檢查的需求及規則會有所不同, 需要針對對應的 repo 去設定 script
在 Git 提交過程中自動觸發 lint-staged, 以便在提交前先進行 eslint 及 prettier 的檢查, 其中 lint-staged 只檢查 staged 的檔案, 以減少檢查時間
-
設置 husky
commit-msg
hook:#!/bin/sh
pnpm exec commitlint --edit $1用於在 Git 提交過程中自動觸發
commitlint
, 以便在提交前檢查 commit message 是否符合約定式提交規範
當要使用時執行 pnpm cz
即可在 cmd 上透過 Commitizen 的方式來撰寫 commit message
註1: commitling.config.js
檔案須為 UTF-8
編碼, 否則會報錯
註2: lint 相關的設定可參考 docs/lint
註3 : 可以再搭配 git-cliff
來自動生成 changelog
- 在 root 安裝
git-cliff
, init cliff (需要 template 可以參考此, 這邊只用 default)pnpm add git-cliff -D
git cliff --init - 在 package.json 中加入以下設定:
也可以指定特定 workspace apps
{
"scripts": {
"changelog": "git-cliff -o CHANGELOG.md"
}
}{
"scripts": {
"changelog": "git-cliff --include-path 'packages/config-eslint/**/*' -o CHANGELOG.md"
}
}
refs: