Skip to content

项目提交约束快速上手

懒得说那么多废话,说了快速上手,就要快速上手,

不要跳步骤,

不要跳步骤,

不要跳步骤,

重要的事情说三遍。

1. 需要的工具包

工具包当前版本说明
commitizen4.3.0规范提交信息的工具
cz-message-helper1.2.2自定义提交信息的模板
commitlint17.6.6校验提交信息的工具
commitlint-config-gitmoji2.3.1gitmoji 提交信息校验规则
husky8.0.3git 钩子工具
standard-version9.5.0自动更新版本并生成 CHANGELOG
conventional-changelog-gitmoji-config1.5.2gitmoji changelog 配置文件

2. 在单个项目中安装

2.1 项目初始化

在项目根目录执行以下命令(早用pnpm,早轻松)

bash
pnpm add -D commitizen commitlint commitlint-config-gitmoji standard-version conventional-changelog-gitmoji-config cz-message-helper husky

安装完毕:

json
// package.json
{
  "devDependencies": {
    "commitizen": "^4.3.0",
    "commitlint": "^17.6.5",
    "commitlint-config-gitmoji": "^2.3.1",
    "standard-version": "^9.5.0",
    "conventional-changelog-gitmoji-config": "^1.5.2",
    "cz-message-helper": "^1.2.2",
    "husky": "^8.0.0"
  }
}

2.2 配置

提示

请仔细阅读每一个步骤,不要跳步执行命令

  1. 执行命令npx husky-init && npx husky add .husky/commit-msg 'npx --no -- commitlint --edit ${1}'[1],会在项目根目录自动生成.husky文件夹,并自动package.jsonscript添加prepare字段。

警告

以上命令,据传 Windows 系统使用 cmd 会报错,具体信息请自行搜索解决。

  1. 删除.husky文件夹中pre-commit文件内的npm test命令。
  2. 在项目根目录创建以下文件.czrc[2],.cz-message.js[3],.commitlintrc.js[4],.changelogrc.js[5]
  3. 完善各种配置文件:
js
{"path": "node_modules/cz-message-helper"}
js
module.exports = {
  questions: [
    {
      type: 'list',
      name: 'type',
      message: '请选择要提交的更改类型:',
      choices: [
        { value: ':bug: fix: ', name: '🐛 fix: -------- 修复BUG' },
        { value: ':sparkles: feat: ', name: '✨ feat: ------- 新功能' },
        { value: ':memo: docs: ', name: '📝 docs: ------- 仅文档更改' },
        { value: ':lipstick: style: ', name: '💄 style: ------ 不影响代码运行的更改(调整空白、格式、缺少分号等)' },
        { value: ':card_file_box: chore: ', name: '🗃️  chore: ------ 非 src 和 test 的修改' },
        { value: ':recycle: refactor: ', name: '♻️  refactor: --- 重构架构或代码' },
        { value: ':zap: perf:', name: '⚡️ perf:  ------ 改进性能的代码更改' },
        { value: ':test_tube: test: ', name: '🧪 test:  ------ 添加测试单元' },
        { value: ':rewind: revert: ', name: '⏪ revert: ----- 回退至某一个版本' },
        { value: ':truck: merge: ', name: '🚚 merge: ------ 合并一个分支, 解决冲突分支' },
        { value: ':construction_worker: ci: ', name: '👷 ci: --------- 自动化流程配置或脚本修改' },
        { value: ':wrench: build: ', name: '🔧 build: ------ 修改构建流程或外部依赖' },
      ],
    },

    {
      type: 'list',
      name: 'scope',
      message: '请选择更改的范围:',
      choices() {
        return [
          { name: '', value: false },
          { name: '自定义', value: 'custom' },
        ]
      },
      filter(value, answers) {
        return value || ''
      },
    },

    {
      type: 'input',
      name: 'customScope',
      message: '请输入自定义的变更的范围(可选):',
      when(answers) {
        return answers.scope === 'custom'
      },
      filter(value, answers) {
        answers.scope = value || ''
        return value || ''
      },
    },

    {
      type: 'input',
      name: 'subject',
      message: '请简明扼要的摘要描述(建议字数在50字内):',
      validate(value) {
        return value.length > 50 ? `[subject] Exceed limit: 50` : true
      },
    },

    {
      type: 'input',
      name: 'body',
      message: '请提供更详细的变更说明(可选), 使用“\\n”换行:',
    },

    {
      type: 'input',
      name: 'breaking',
      message: '请列出任何重大变化(可选):',
      when(answers) {
        return /^(:[a-z0-9A-Z_-]+(:)(\s*))?(feat|fix)(\2\s*)?$/.test(answers.type.toLowerCase())
      },
    },

    {
      type: 'input',
      name: 'footer',
      message: '请列出此更改关闭的任何问题(可选), 例如: #31,#34:',
    },
  ],

  templater: (answers, wrap) => {
    let template = ''

    template += answers.type ? `${answers.type}` : ``
    template += answers.scope ? `(${answers.scope})` : ``
    template += answers.subject ? `: ${answers.subject}` : ``
    template += answers.body ? `\n\n${wrap(answers.body)}` : ``
    template += answers.breaking ? `\n\nBREAKING CHANGE: ${wrap(answers.breaking)}` : ``
    template += answers.footer ? `\n\nISSUES CLOSED: ${wrap(answers.footer)}` : ``

    return template
  },

  language: 'cn',
}
js
module.exports = {
  extends: ['gitmoji'],
}
js
module.exports = {
  titleLanguage: 'zh-CN',
}
  1. package.jsonscript中添加指令"commit": "git-cz" (commit可以根据个人习惯修改)

2.3 验证

  1. 执行git add .添加所有文件到暂存区。
  2. 执行git commit -m "hello"提交代码。
  3. 会看到husky拦截提交,并显示违规信息。
bash
myblog_vitepress on main [⇡!+?] is 📦 1.0.0-beta.3 via ⬢ v18.16.0
 git commit -m "hello"
   input: hello
   Your commit should start with gitmoji code. Please check the emoji code on https://gitmoji.dev/. [start-with-gitmoji]
   subject may not be empty [subject-empty]
   type may not be empty [type-empty]

   found 3 problems, 0 warnings
   Get help: https://github.com/conventional-changelog/commitlint/#what-is-commitlint

husky - commit-msg hook exited with code 1 (error)
规范示例
bash
myblog_vitepress on main [⇡!+?] is 📦 1.0.0-beta.3 via ⬢ v18.16.0
 pm commit

> vitepress@1.0.0-beta.3 commit /Users/bddxg/Documents/coding/web/myblog_vitepress
> git-cz

cz-cli@4.3.0, cz-message-helper@1.2.2

? 请选择要提交的更改类型:
  🧪 test:  ------ 添加测试单元
 revert: ----- 回退至某一个版本
  🚚 merge: ------ 合并一个分支, 解决冲突分支
  🐛 fix: -------- 修复BUG
 feat: ------- 新功能
 📝 docs: ------- 仅文档更改
  💄 style: ------ 不影响代码运行的更改(调整空白、格式、缺少分号等)
(Move up and down to reveal more choices)

? 请选择要提交的更改类型: 📝 docs: ------- 仅文档更改
? 请选择更改的范围: 自定义
? 请输入自定义的变更的范围(可选): 前端方向
? 请简明扼要的摘要描述(建议字数在50字内): 更新文章
? 请提供更详细的变更说明(可选), 使用“\n”换行: Commitizen.md
? 请列出此更改关闭的任何问题(可选), 例如: #31,#34:

###--------------------------------------------------------###
:memo: docs: (前端方向): 更新文章

Commitizen.md
###--------------------------------------------------------###

? 您确定要继续执行上面的提交吗? 提交
[main 3d2ff1d] :memo: docs: (前端方向): 更新文章
 2 files changed, 426 insertions(+)
 create mode 100644 "docs/article/expansion/前端方向/Commitizen.md"

2.4 自动生成 changelog

相关的包,最开始我们已经安装过了,直接进行配置即可:

想生成之前所有 commit 信息产生的 changelog 则需要使用这条命令:

bash
npx standard-version --preset gitmoji-config -i docs/CHANGELOG.md --header '# 更新日志'

当然这样的命令有点长且啰嗦,可以通过在 package.json 中添加 scripts 来简化命令,具体就不再赘述 令人遗憾的是,我目前的提交都不符合提交约束的规范,只好借别人的图演示一下,从本篇博客开始,我的提交将会遵守提交约束的规范

参考资料:

  • cz-message-helper, 作者: linpengteng 这个模板解决了 cz-customizable不能自定义scope的问题。但可惜只有 1star(还是我给的),希望大家多多支持。(包作者非本人)
  • Gitmoji Commit Workflow 完全指南,作者:Arvin Xu, 通过文章,解决了 emoji 提交信息的校验问题。
  • commitlint,官网,查看文档解决了联动husky的问题。

  1. 初始化husky并添加commit-msg钩子 👈🏻

  2. .czrccommitizen的配置文件,用于指定commitizen的适配器,这里使用的是cz-message-helper,它是一个commitizen的适配器,它的作用是提供一个交互式的命令行,帮助我们生成符合规范的提交信息。 👈🏻

  3. .cz-message.jscz-message-helper的配置文件,用于配置commitizen的交互式命令行的问题,以及提交信息的模板。 👈🏻

  4. .commitlintrc.jscommitlint的配置文件,用于配置commitlint的校验规则,这里使用的是gitmoji的校验规则。 👈🏻

  5. .changelogrc.jsconventional-changelog-gitmoji-config 的配置文件 👈🏻