規範你的 commit message 並且根據 commit 自動生成 CHANGELOG.md

sunshine小小倩發表於2018-10-27

專案地址: github.com/sunshine940…

一個好的專案通常都是多人合作的結果,然而每個人有每個人的開發習慣,並不統一。

所以 commit message 就顯得格外的重要。有些不規範的 commit 可能過個一個月之後你自己都不知道當時的提交目的了ヘ(;´Д`ヘ),

所以,為了能使得日後復(zhao)盤(guo)的時候更加的方便,團隊之間遵守同一套 commit message 規範還是很有必要的。

本篇文章介紹的是 Angular 規範,這是目前使用最廣的寫法,比較合理和系統化,並且有配套的工具。

commit message 的作用

  • 提供更多的歷史資訊,方便快速瀏覽。
  • 可以過濾某些commit(比如文件改動),便於快速查詢資訊。
  • 可以直接從commit生成Change log。

commit message 的格式

剛剛有說到,我們使用的是 Angular 規範,下面來大致介紹下:

使用 git commit 可以提交多行 commit message.

commit message 包括三個部分:HeaderBodyFooter

<type>(<scope>): <subject>
// 空一行
<body>
// 空一行
<footer>
複製程式碼

其中,Header 是必填,BodyFooter 是選填。

Header

Header 包括三個欄位:type(必填)、scope(選填)和 subject(必填)

type

type 用於說明 commit 的類別,只允許使用下面 7 個標識。

  • feat:新功能(feature)
  • fix:修補bug
  • docs:文件(documentation)
  • style: 格式(不影響程式碼執行的變動)
  • refactor:重構(即不是新增功能,也不是修改bug的程式碼變動)
  • test:增加測試
  • chore:構建過程或輔助工具的變動

typefeatfix,則該 commit 將肯定出現在 Change log 之中。

scope

scope 用於說明 commit 影響的範圍,比如資料層、控制層、檢視層等等,視專案不同而不同。

subject

subjectcommit 目的的簡短描述,不超過50個字元

以動詞開頭,使用第一人稱現在時,比如 change,而不是 changed 或 changes
第一個字母小寫
結尾不加句號(.)
複製程式碼

body

Body 部分是對本次 commit 的詳細描述,可以分成多行。下面是一個範例。

More detailed explanatory text, if necessary.  Wrap it to 
about 72 characters or so. 

Further paragraphs come after blank lines.

- Bullet points are okay, too
- Use a hanging indent
複製程式碼

Footer

Footer 部分只用於兩種情況

  • 不相容變動

如果當前程式碼與上一個版本不相容,則 Footer 部分以 BREAKING CHANGE 開頭,後面是對變動的描述、以及變動理由和遷移方法。

  • 關閉 Issue 如果當前 commit 針對某個 issue,那麼可以在 Footer 部分關閉這個 issue
Closes #123, #245, #992
複製程式碼

Commitizen -- 自動生成合格的 commit message

根據上述的描述,你是不是在感慨寫個 commit message 好麻煩,這裡介紹下 Commitizen -- 能夠根據提示自動生成符合規範的 commit message

安裝

$ npm install -g commitizen
複製程式碼

在專案中使用

然後,在專案目錄裡,執行下面的命令,使其支援 AngularCommit message 格式。

$ commitizen init cz-conventional-changelog --save --save-exact
複製程式碼

commit

在提交的時候就可以使用 git cz 就可以根據提示,生成自動化的 commit message

Commitizen

validate-commit-msg 檢查你的 commit-message 規範

Commitizen 可以幫助我們規範自己的 commit-message,但是在團隊合作中,如何規範其他成員的 commit 規範呢?

可以使用 validate-commit-msg 來檢查你的專案的 commit-message 是否符合格式

validate-commit-msg 安裝

npm install --save-dev validate-commit-msg
複製程式碼

husky 安裝

按照 validate-commit-msg 中 README 中寫的,可以用 validate-commit-msg 作為一個 githook 來驗證提交訊息,並且推薦了 husky

This provides you a binary that you can use as a githook to validate the commit message. I recommend husky. You'll want to make this part of the commit-msg githook, e.g. when using husky, add "commitmsg": "validate-commit-msg" to your npm scripts in package.json.

執行

npm install husky --save-dev
複製程式碼

並且在 package.json 中的 scripts 欄位中加入

"commitmsg": "validate-commit-msg"
複製程式碼

然後每次 git commit 之後,就會自動檢查 commit message 是否合格。如果不合格,就會報錯

husky > commit-msg (node v9.2.1)
INVALID COMMIT MSG: does not match "<type>(<scope>): <subject>" !
change
husky > commit-msg hook failed (add --no-verify to bypass)
複製程式碼

生成 Change log

如果你的所有 commit 都符合 Angular 格式,那麼釋出新版本時, Change log 就可以用指令碼自動生成。

生成的文件包括以下三個部分。

  • New features
  • Bug fixes
  • Breaking changes.

每個部分都會羅列相關的 commit ,並且有指向這些 commit 的連結。當然,生成的文件允許手動修改,所以釋出前,你還可以新增其他內容。

conventional-changelog 自動根據 commit 生成 change log

conventional-changelog 安裝

npm install -g conventional-changelog-cli
複製程式碼

conventional-changelog 工作流

  • Make changes
  • Commit those changes
  • Make sure Travis turns green
  • Bump version in package.json
  • conventionalChangelog
  • Commit package.json and CHANGELOG.md files
  • Tag
  • Push

conventionalChangelog 這一步有兩種選擇

# 不會覆蓋以前的 Change log,只會在 CHANGELOG.md 的頭部加上自從上次釋出以來的變動
$ conventional-changelog -p angular -i CHANGELOG.md -s -p 

# 生成所有釋出的 Change log
$ conventional-changelog -p angular -i CHANGELOG.md -w -r 0
複製程式碼

注意:

  • 這裡安裝的是 conventional-changelog-cli,安裝 conventional-changelog 會報 conventional-changelog: command not found 的錯誤
  • 查閱了很多文章使用的是 conventional-changelog -p angular -i CHANGELOG.md -w,這樣只能在命令列中 log 出 CHANGELOG 的內容,不會生成檔案,如果要生成檔案需要使用 conventional-changelog -p angular -i CHANGELOG.md -s。更多的 config 可以使用 conventional-changelog --help 檢視
  • 還需要注意的是,在生成 changlog 之前,需要先使用 $ npm version [version] 更改版本號,然後再生成 changelog,這一步很多的博文都沒有寫,就會導致增量生成的 CHANGELOG 一直都有之前的 commit 記錄。

自動判斷版本號

上面步驟有兩個需要優化的地方

  • 需要在 conventionalChangelog 之前先要更改版本號
  • 生成 CHANGELOG.md 之後又造成了新的改動,所以還需要再執行一遍提交

所以我們需要自動化的執行這些,commitizen 還依據 conventional message,建立起一個生態

使用這些工具可以簡化釋出流程。

cp package.json _package.json &&
preset=`conventional-commits-detector` && 
echo $preset &&
bump=`conventional-recommended-bump -p angular` &&
echo ${1:-$bump} &&
npm --no-git-tag-version version ${1:-$bump} &>/dev/null &&
conventional-changelog -i CHANGELOG.md -s -p ${2:-$preset} &&
git add CHANGELOG.md package.json package-lock.json &&
version=`cat package.json` &&
git commit -m'docs(CHANGELOG): $version' &&
mv -f _package.json package.json &&
npm version ${1:-$bump} -m 'chore(release): %s' &&
git push --follow-tags 
複製程式碼

在你的專案中規範 commit message 並且根據 commit 自動生成 CHANGELOG.md

  1. 安裝依賴
npm install -g commitizen conventional-changelog conventional-changelog-cli conventional-commits-detector conventional-recommended-bump husky validate-commit-msg

複製程式碼

安裝完成之後版本如下(我遇到過 conventional-recommended-bump4.x 的版本會報錯Error: Unable to load the "angular" preset package. Please make sure it's installed.。降低下版本就好。

/usr/local/lib
├── commitizen@3.0.4
├── conventional-changelog@2.0.3
├── conventional-changelog-cli@2.0.5
├── conventional-commits-detector@0.1.1
├── conventional-recommended-bump@0.3.0
└── npm@6.1.0
複製程式碼
  1. package.json 中增加 script 欄位
    "changelog": "cp package.json _package.json &&preset=`conventional-commits-detector` && echo $preset && bump=`conventional-recommended-bump -p angular` && echo ${1:-$bump} && npm --no-git-tag-version version ${1:-$bump} &>/dev/null && conventional-changelog -i CHANGELOG.md -s -p ${2:-$preset} && git add CHANGELOG.md package.json package-lock.json && version=`cat package.json` && git commit -m'docs(CHANGELOG): $version' && mv -f _package.json package.json && npm version ${1:-$bump} -m 'chore(release): %s' && git push --follow-tags "
複製程式碼
  1. 使用 使用 git cz 就可以根據提示,生成自動化的 commit message 使用 npm run changelog 生成 changelog, tag, 升級 version, 並自動執行 git push

問題

改方案還有一個問題尚未解決,就是使用 conventional-recommended-bump 更換推薦版本,我實驗的專案都是隻改動了中間的版本號,如果你的專案對版本號要去比較嚴格,建議使用手動更換版本號的方式。

相關文章