Commitizen + Husky + Commitlint实现commit message校验

2,505 阅读5分钟

Commitizen, Husky, Commitlint

 先简要地介绍这三个工具的作用,让大家对整个校验过程如何实现有一个大体的了解。

  • Commitizen:是一个命令行提示工具,它主要用于帮助我们更快地写出规范的commit message
  • Commitlint:用于校验填写的commit message是否符合设定的规范
  • Husky:是一个git hook工具,用于在提交过程中的某个特定时刻触发commitlint

第一步:Commitizen

 安装Commitizen有全局安装和单个项目安装两种方式,在此我们推荐全局安装,以下是安装过程。

 首先,全局安装Commitizen:

npm install -g commitizen			

 然后,全局安装Commitizen的适配器,一般是cz-conventional-changelog

npm install -g cz-conventional-changelog

 适配器的作用是按照某个指定的规范帮助我们生成commit message。cz-conventional-changelog预设的是Angular团队规范。你也可以选择其他的适配器来切换不同的规范,甚至自定义一个适配器。

 如果你是mac用户,请运行下面这条命令,它会在你的home目录下,创建一个.czrc文件。路径指向刚才全局安装的适配器。

echo '{ "path": "cz-conventional-changelog" }' > ~/.czrc	

 如果你是windows用户,请把下面这条命令中的C:\Users\12105更换成你自己电脑上的\Users\username目录再运行。这条命令的本质其实就是在Users\username目录下创建一个内容为{ "path": "cz-conventional-changelog" }.czrc文件。

echo { "path": "cz-conventional-changelog" } > C:\Users\12105\.czrc

 至此,第一步全局安装Commitizen完成。在任何一个git仓库中运行git cz,就可以通过Commitizen来填写commit message完成提交。

第二步:Husky

 首先,在项目中安装husky:

npm install husky --save-dev

 然后,启用git hooks:

npx husky install

​ 为了以后能在npm install之后自动地启用git hooks,我们可以在package.json中添加以下配置:(prepare脚本会在npm install之后自动执行,它是npm的一个生命周期脚本

{
  ...
  "scripts": {
    "prepare": "husky install"
  }
}

 或者,运行下面这条命令。注意:该命令要求npm版本在7及以上。

npm set-script prepare "husky install"

第三步:Commitlint

 首先,在项目中安装@commitlint/cli@commitlint/config-conventional

npm install --save-dev @commitlint/config-conventional @commitlint/cli

@commitlint/config-conventional,它配置了Commitlint使用的校验规则,要求commit message符合Angular团队规范。当然,也可以通过安装其他的配置包来切换不同的规范。

 然后,在项目目录下添加commitlint.config.js配置文件。

echo module.exports = {extends: ['@commitlint/config-conventional']} > commitlint.config.js

 最后,添加commit-msg hook配置,用于在commit-msg中校验commit message。commit-msg是一个git hook,它会在提交时被触发。

.\node_modules\.bin\husky add .husky/commit-msg "npx --no -- commitlint --edit $1"

 或:

npx husky add .husky/commit-msg 'npx --no commitlint --edit "$1"'

 现在,你就可以通过git cz来代替git commit,借助Commitizen的提交完成提交。比如像这样: image-20220502195131005.png  在结束commit message的填写之后,会自动触发对commit message的校验。如果校验通过,就会顺利完成一次提交。如果校验不通过,提交会被中止,需要重新提交,像这样: image-20220502195557221.png

 到这里,一个完整的校验流程已经搭建完成了。下面是一些可选的配置,如果有类似的需要,可以参考下~

定制自己的校验规范

 上述校验流程中,不管是Commitizen的适配器,还是Commitlint预设的校验规则,我们都使用了默认的Angular团队规范配置。那如果我们需要一些个性化的校验规范,应该怎么做呢?

 我们以给原有Angluar规范增加一个type的选项为例,展示如何定制原有规范中的一些配置。这里分为两个步骤:

第一步:定制Commitizen适配器

 首先,安装cz-customizable,它是一个第三方适配器,提供了灵活的配置项

npm install --save-dev cz-customizable

 然后,在package.json中配置config.commitizen.path,把cz-customizable作为Commitizen的插件使用。

{ 
  ... 
  "config": { 
    "commitizen": {
      "path": "node_modules/cz-customizable" 
    } 
  } 
}

 接着在项目目录下添加.cz-config.js文件,作为配置文件。这里我们希望添加一个新的type选项wip,含义是"Work in progress"。所以添加以下配置:

module.exports = {
  types: [
    { value: "feat", name: "feat:     A new feature" },
    { value: "fix", name: "fix:      A bug fix" },
    { value: "docs", name: "docs:     Documentation only changes" },
    { value: "style", name: "style:    Changes that do not affect the meaning of the code\n            (white-space, formatting, missing semi-colons, etc)" },
    { value: "refactor", name: "refactor: A code change that neither fixes a bug nor adds a feature" },
    { value: "perf", name: "perf:     A code change that improves performance" },
    { value: "test",  name: "test:     Adding missing tests" },
    { value: "chore", name: "chore:    Changes to the build process or auxiliary tools\n            and libraries such as documentation generation" },
    { value: "revert", name: "revert:   Revert to a commit" },
    { value: "wip", name: "wip:      Work in progress" },
  ]
};
第二步:定制Commitlint校验规则

 完成第一步,我们现在可以使用Commitizen写出typewip的commit message了。但是,提交时会发现Commitlint校验不通过: image.png  这是因为Commitlint对type的枚举值有所限制。我们还要更新Commitlint中关于type枚举值的校验规则。定制规范中的其他配置项时也要注意同步更新Commitlint的校验配置

 更新.commitlint.config.js中的配置,主要是更新type-enum的规则:

module.exports = {
    extends: ['@commitlint/config-conventional'],
    rules: {
        'type-enum': [2, 'always', ['build', 'chore', 'ci', 'docs', 'feat', 'fix', 'perf', 'refactor', 'revert', 'style', 'test', 'wip']]
    }
};

 这样,就完成了对原有规范中某个配置的定制。