前面写过四篇文章,各自讲述了Git Hooks 与 Husky、commitlint + Husky 规范 git commit 日志、根据 commit message 自动生成 changelog、如何自定义 conventional-changelog,这篇文章是将这些知识整合起来,应用到为自动生成 changelog
commitlint + Husky 规范 git commit 日志
规范 commit 日志的好处
- 团队形成一致的代码提交风格,更好的提高工作效率
- 规范的 commit message 有助于团队其它人员 review, 还可以有效的输出 CHANGELOG, 对项目十分重要
- 成为一名有追求的工程师
安装 & 配置 commitlint
安装 commitlint cli
和 config-conventional
npm install --save-dev @commitlint/{config-conventional,cli}
# For Windows:
npm install --save-dev @commitlint/config-conventional @commitlint/cli
创建 commitlint.config.js 配置 commitlint
echo "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.js
安装 & 配置 husky
安装 husky
npm install husky --save-dev
启用 Git hooks
npx husky install
添加 commit-msg
hook
运行以下命令创建 commit-msg
hook
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit "$1"'
# 有时上面的命令在某些命令解释器中不起作用
# 你可以尝试下面的命令在commit-msg文件中写入 npx --no -- commitlint --edit $1
npx husky add .husky/commit-msg \"npx --no -- commitlint --edit '$1'\"
# or
npx husky add .husky/commit-msg "npx --no -- commitlint --edit $1"
提交 commit,发现 commitlint
已经生效,不符合 commitlint 规范的 git commit
的将被停止
Tip
如果你遇到如下报错,删除node_modules并执行
npm install
重新安装即可.husky/_/husky.sh: No such file or directory
commitlint 规范
提交格式
git commit -m <type>(scope?): <subject>
Examples
git commit -m 'chore: run tests on travis ci'
git commit -m 'fix(server): send cors headers'
git commit -m 'feat(blog): add comment section'
注意,英文冒号 + 空格
常用的 type 类别
type:用于表明我们这次提交的改动类型,是新增了功能?还是修改了测试代码?又或者是更新了文档?总结以下 11 种类型:
- build:主要目的是修改项目构建系统(例如 glup,webpack,rollup 的配置等)的提交
- ci:主要目的是修改项目继续集成流程(例如 Travis,Jenkins,GitLab CI,Circle等)的提交
- docs:文档更新
- feat:新增功能
- fix:bug 修复
- perf:性能优化
- refactor:重构代码(既没有新增功能,也没有修复 bug)
- revert:回滚某个更早之前的提交
- style:不影响程序逻辑的代码修改(修改空白字符,补全缺失的分号等)
- test:新增测试用例或是更新现有测试
- chore:不属于以上类型的其他类型(日常事务)
更多的 type 说明 你可以参阅这里 commitlint type-enum
scope:作用域,可选。用于标识此次提交主要涉及到代码中哪些模块。支持多作用域(可使用分隔符:“/”、“” 和 “,”
subject:一句话描述此次提交的主要内容,做到言简意赅。
自定义 commitlint 规范
https://commitlint.js.org/#/reference-rules
我们可以通过修改 commitlint.config.js 来自定义我们的提交规范,如:
rule
配置说明:rule
由name
和配置数组组成,如:'name: [0, 'always', 72]'
,数组中第一位为level
,可选0,1,2,0为disable,1为warning,2为error;第二位为是否启用,可选always|never
,第三位该rule的值。具体配置例子如下:
// commitlint.config.js
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [2, 'always', [
'test', 'upd', 'feat', 'fix', 'refactor', 'docs', 'chore', 'style', 'revert',
]],
'type-case': [0],
'type-empty': [0],
'scope-empty': [0],
'scope-case': [0],
'subject-full-stop': [0, 'never'],
'subject-case': [0, 'never'],
'header-max-length': [0, 'always', 72],
},
};
根据 commit message 自动生成 changelog
安装依赖
npm install conventional-changelog conventional-changelog-cli conventional-changelog-custom-config compare-func --save-dev
或者
yarn add conventional-changelog conventional-changelog-cli conventional-changelog-custom-config compare-func --save-dev
自定义 changelog
在根目录创建的 changelog-option.js
文件
const compareFunc = require('compare-func')
module.exports = {
writerOpts: {
transform: (commit, context) => {
let discard = true
const issues = []
commit.notes.forEach(note => {
note.title = 'BREAKING CHANGES'
discard = false
})
if (commit.type === 'feat') {
commit.type = '✨ Features | 新功能'
} else if (commit.type === 'fix') {
commit.type = '🐛 Bug Fixes | Bug 修复'
} else if (commit.type === 'perf') {
commit.type = '⚡ Performance Improvements | 性能优化'
} else if (commit.type === 'revert' || commit.revert) {
commit.type = '⏪ Reverts | 回退'
} else if (discard) {
return
} else if (commit.type === 'docs') {
commit.type = '📝 Documentation | 文档'
} else if (commit.type === 'style') {
commit.type = '💄 Styles | 风格'
} else if (commit.type === 'refactor') {
commit.type = '♻ Code Refactoring | 代码重构'
} else if (commit.type === 'test') {
commit.type = '✅ Tests | 测试'
} else if (commit.type === 'build') {
commit.type = '👷 Build System | 构建'
} else if (commit.type === 'ci') {
commit.type = '🔧 Continuous Integration | CI 配置'
} else if (commit.type === 'chore') {
commit.type = '🎫 Chores | 其他更新'
}
if (commit.scope === '*') {
commit.scope = ''
}
if (typeof commit.hash === 'string') {
commit.hash = commit.hash.substring(0, 7)
}
if (typeof commit.subject === 'string') {
let url = context.repository
? `${context.host}/${context.owner}/${context.repository}`
: context.repoUrl
if (url) {
url = `${url}/issues/`
// Issue URLs.
commit.subject = commit.subject.replace(/#([0-9]+)/g, (_, issue) => {
issues.push(issue)
return `[#${issue}](${url}${issue})`
})
}
if (context.host) {
// User URLs.
commit.subject = commit.subject.replace(/\B@([a-z0-9](?:-?[a-z0-9/]){0,38})/g, (_, username) => {
if (username.includes('/')) {
return `@${username}`
}
return `[@${username}](${context.host}/${username})`
})
}
}
// remove references that already appear in the subject
commit.references = commit.references.filter(reference => {
if (issues.indexOf(reference.issue) === -1) {
return true
}
return false
})
return commit
},
groupBy: 'type',
commitGroupsSort: 'title',
commitsSort: ['scope', 'subject'],
noteGroupsSort: 'title',
notesSort: compareFunc
}
}
添加脚本
修改 package.json 中 scripts 字段
{
"scripts": {
"version": "conventional-changelog -p custom-config -i CHANGELOG.md -s -n ./changelog-option.js && git add CHANGELOG.md",
"postversion": "git push --tags",
"changelog": "conventional-changelog -p custom-config -i CHANGELOG.md -s -n ./changelog-option.js && git add CHANGELOG.md"
}
}
在这指定配置文件位置,我们放在了根目录,也可以指定其他地方
配置项说明:
- -p custom-config 指定风格*
- -i CHANGELOG.md 指定输出的文件名称
- -s 输出到infile,这样就不需要指定与outfile相同的文件
- -r 从最新的版本生成多少个版本如果为0,则整个更改日志将被重新生成,输出文件将被覆盖。默认值:1
- -n ./changelog-option.js 指定自定义配置
自动生成 CHANGELOG.md 文件
执行 npm version
的时候会自动生成
手动生成 CHANGELOG.md 文件
直接运行下面的命令即可
npm run changelog
如果type
为feat
、fix
、perf
、revert
,则该 commit 将肯定出现在 Change log 之中。其他情况(docs
、chore
、style
、refactor
、test
)由你决定(通 commitlint.config.js
配置)。
如何使用
第一步,提交 commit
按照上面的 git commit
提交格式提交代码
第二步,用命令升级版本号
注意,版本的log使用
npm version <newversion>
才会生成新的log,手动修改 package.json version 不会有新的版本log
我们使用如下命令来升级项目版本号
命令 | 作用 | 执行结果version |
---|---|---|
npm version patch | 升级修订号 | 首次执行2.0.0-0 -> 2.0.0 再次执行2.0.0 -> 2.0.1 |
npm version minor | 升级次版本号 | 2.0.1 -> 2.1.0 |
npm version major | 升级主版本号 | 2.1.0 -> 3.0.0 |
注意
npm version <newversion>
后会自动生成 git tag
,在git push 时还要 git push --tags。
因为changelog读取的就是git tag
参阅
- commitlint + Husky 规范 git commit 日志
- 规范你的 commit message 并且根据 commit 自动生成 CHANGELOG
- 如何自定义 conventional-changelog
- Git Hooks 与 Husky
- https://commitlint.js.org/
- https://typicode.github.io/husky/#/?id=install
- https://github.com/conventional-changelog/commitlint
- https://github.com/conventional-changelog/commitlint/blob/master/@commitlint/config-conventional/index.js
- https://www.conventionalcommits.org/en/v1.0.0-beta.2/#why-use-conventional-commits