一文搞定 Conventional Commits

你們好,我是洛竹🎋,一隻住在杭城的木系前端🧚🏻‍♀️,若是你喜歡個人文章📚,能夠經過點贊幫我彙集靈力⭐️。前端

本文的最佳實踐已加入洛竹的漸進式腳手架體系,執行 npx @luozhu/create-commitlint 便可爲項目賦能。node

前言

規範化 git commit 對於提升 git log 可讀性、可控的版本控制和 changelog 生成都有着重要的做用。然而阻礙咱們腳步的不僅是團隊的推廣,單單對於一系列工具的配置都讓人頭大。這其中主要就是 commitlint 和 commitizen 的配合使用以及自定義提交規範。本文總結了目前的最佳實踐給你們,若是有幫助,賞個star足矣。git

Conventional Commits 約定式提交規範

Conventional Commits 是一種用於給提交信息增長人機可讀含義的規範。約定式提交規範是一種基於消息的輕量級約定。它提供了一組用於建立清晰的提交歷史的簡單規則;這使得編寫基於規範的自動化工具變得更容易。這個約定與 SemVer 相吻合,在提交信息中描述新特性、bug 修復和破壞性變動。github

提交說明的結構以下所示:shell

<類型>([可選的做用域]): <描述>

[可選的正文]

[可選的腳註]
複製代碼

類型(type)

  • feat:: 類型爲 feat 的提交表示在代碼庫中新增了一個功能(這和語義化版本中的 MINOR 相對應)。
  • fix::類型爲 fix 的 提交表示在代碼庫中修復了一個 bug (這和語義化版本中的 PATCH 相對應)。
  • docs:: 只是更改文檔。
  • style:: 不影響代碼含義的變化(空白、格式化、缺乏分號等)。
  • refactor:: 代碼重構,既不修復錯誤也不添加功能。
  • perf:: 改進性能的代碼更改。
  • test:: 添加確實測試或更正現有的測試。
  • build:: 影響構建系統或外部依賴關係的更改(示例範圍:gulp、broccoli、NPM)。
  • ci:: 更改持續集成文件和腳本(示例範圍:Travis、Circle、BrowserStack、SauceLabs)。
  • chore:: 其餘不修改srctest文件。
  • revert:: commit 回退。

範圍(scope)

能夠爲提交類型添加一個圍在圓括號內的做用域,覺得其提供額外的上下文信息。例如 feat(parser): adds ability to parse arrays.npm

BREAKING CHANGE

在可選的正文或腳註的起始位置帶有 BREAKING CHANGE: 的提交,表示引入了破壞性 API 變動(這和語義化版本中的 MAJOR 相對應)。 破壞性變動能夠是任意 類型 提交的一部分。json

示例

包含了描述以及正文內有破壞性變動的提交說明

feat: allow provided config object to extend other configs

BREAKING CHANGE: `extends` key in config file is now used for extending other config files
複製代碼

包含了可選的 ! 字符以提醒注意破壞性變動的提交說明

chore!: drop Node 6 from testing matrix

BREAKING CHANGE: dropping Node 6 which hits end of life in April
複製代碼

不包含正文的提交說明

docs: correct spelling of CHANGELOG
複製代碼

包含做用域的提交說明

feat(lang): add polish language
複製代碼

爲 fix 編寫的提交說明,包含(可選的) issue 編號

fix: correct minor typos in code

see the issue for details on the typos fixed

closes issue #12
複製代碼

約定式提交規範

  1. 每一個提交都必須使用類型字段前綴,它由一個名詞組成,諸如featfix,其後接一個可選的做用域字段,以及一個必要的冒號(英文半角)和空格。
  2. 當一個提交爲應用或類庫實現了新特性時,必須使用feat類型。
  3. 當一個提交爲應用修復 bug 時,必須使用fix類型。
  4. 做用域字段能夠跟隨在類型字段後面。做用有必須是一個描述某部分代碼的名詞,並用圓括號包圍,例如:fix(parser):
  5. 描述字段必須緊接在類型/做用域前綴的空格以後。描述指的是對代碼變動的簡短總結,例如:fix:array parsing issue when multiplejspaces were contained in string
  6. 在簡短描述以後,能夠編寫更長的提交正文,爲代碼變動提供額外的上下文信息。正文必須起始於描述字段結束的一個空行後。
  7. 在正文結束的一個空行以後,能夠編寫一行或或多行腳註。腳註必須包含關於提交的元信息,例如:關聯的合併請求、Reviewer、破壞性變動、每條元信息一行。
  8. 破壞性變動必須標示在正文區域最開始處,或腳註區域中某一行的開始。一個破壞性變動必須包含大寫的文本BREAKING CHANGE,後面緊跟冒號和空格。
  9. BREAKING CHANGE:以後必須提供描述,以描述對 API 的變動。例如:BREAKING CHANGE: enviroment variables now take precedence over cofig files
  10. 在提交說明中,能夠使用featfix以外的類型。
  11. 工具的實現必須不區分大小寫地解析構成約定式提交的信息單元,只有BREAKING CHANGE 必須是大寫的。
  12. 能夠在類型/做用域前綴以後,:以前,附加!字符,以進一步提醒注意破壞性變動。當有!前綴時,正文或腳註內必須包含BREAKING CHANGE: description

爲何使用約定式提交

  • 自動化生產 CHANGELOG。
  • 基於提交的類型,自動決定語義化的版本變動。
  • 向同事、公衆與其餘利益關係者傳達變化的性質。
  • 觸發構建和部署流程。
  • 讓人們探索一個更加結構化的提交歷史,以便下降對你的項目做出貢獻的難度。

cz-customizable

可自定義的Commitizen插件(或獨立實用運行)可幫助實現一致的提交消息。gulp

安裝 commitizen、cz-customizable:ubuntu

$ yarn add -D commitizen cz-customizable
複製代碼

向 package.json 添加新的 script:bash

{
  "scripts" : {
    ...
    "commit": "git cz"
  }
  "config": {
    "commitizen": {
      "path": "cz-customizable"
    }
  }
}
複製代碼

在根目錄新建 .cz-config.js 並複製 cz-config-EXAMPLE.js 到文件。

效果:

commitlint

commitlint檢查您的提交消息是否符合conventional commit format

一、安裝 @commitlint/cli、yorkie:

$ yarn add -D @commitlint/cli yorkie
複製代碼

二、添加 git commit hooks 到 package.json:

{
  ...
  "gitHooks": {
    "commit-msg": "commitlint -e -V"
  }
}
複製代碼

三、安裝 commitlint-config-cz:

commitlint-config-cz 合併 cz-customizable 的配置 {types,scopes,scopeOverrides} 和 commitlint 的配置 {type-enum,scope-enum}。這樣,你就能夠在一個地方維護 types 和 scopes。

$ yarn add commitlint-config-cz -D
複製代碼

四、在 commitlint.config.js 中用 cz 擴展您的 commitlint 配置:

module.exports = {
  extends: ['cz'],
  rules: {
    // must add these rules
    'type-empty': [2, 'never'],
    'subject-empty': [2, 'never']
  }
};
複製代碼

vscode commitizen

在 VS Code 中搜索裝 vscode commitizen,而後就能夠擺脫命令行了,並且這個插件是和前面全部的配置兼容的,效果以下:

GitHub Actions

新建一個 github workflow .github/workflows/commitlint.yml,做用是在提交 pull_request 時,檢查信息:

name: Lint Commit Messages
on: [pull_request]

jobs:
  commitlint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 0
      - uses: actions/setup-node@v1
        with:
          node-version: '10.x'
      - run: npm install
      - name: Add dependencies for commitlint action
        # $GITHUB_WORKSPACE is the path to your repository
        run: echo "::set-env name=NODE_PATH::$GITHUB_WORKSPACE/node_modules"
      # Now the commitlint action will run considering its own dependencies and yours as well 🚀
      - uses: wagoid/commitlint-github-action@v2
複製代碼

standard-version

standard-version 是一款遵循語義化版本( semver)commit message 標準規範 的版本和 changelog 自動化工具。一般狀況線下,咱們會在 master 分支進行以下的版本發佈操做:

  1. git pull origin master
  2. 根據 package.json 中的 version 更新版本號,更新 CHANGELOG
  3. git add .
  4. git commit
  5. git tag 打版本操做
  6. git push --tags:push 版本 tag 和 master 分支到倉庫

其中 2,3,4,5 是 standard-version 工具會自動完成的工做,配合本地的 shell 腳本,則能夠自動完成一系列版本發佈的工做了。

安裝 & 使用

$ yarn add -D standard-version
複製代碼
// package.json
{
  "scripts": {
    "release": "standard-version"
  }
}
複製代碼
  • First Release:yarn release --first-release
  • Cutting Release:yarn release
  • Release as a Pre-Release:yarn release --prerelease or yarn release --prerelease alpha
  • Release as a Target Type Imperatively (npm version-like):yarn release --release-as minor or yarn release --release-as 1.1.0,能夠合併 --prerelease以此方便發佈實驗性特性
  • Prevent Git Hooks:yarn release --no-verify

本文首發於「洛竹的官方網站」,同步於公衆號「洛竹早茶館」和「掘金專欄」。

相關文章
相關標籤/搜索