关于 conventional-commit-message
conventional-commit-message 是用于编写、审查和修改 Conventional Commits 提交信息的 Skill。它帮助判断类型、范围、破坏性变更及发布影响,适用于兼容的变更日志工具。
主要功能
- 01Conventional Commits 格式规范
- 02提交类型选择指南
- 03范围选择建议
- 04破坏性变更标记
- 05发布影响评估
- 06Commitlint 验证指引
适用场景
- 01根据代码差异拟定提交信息
- 02审查或修改现有提交信息
- 03为依赖或工具变更选择类型
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ conventional-changelog/ conventional-changelog --skill conventional-commit-message安装后在 Claude Code 中输入/conventional-commit-message确认已加载。
详细介绍
Conventional Commit 提交信息
在使用 conventional-changelog-conventionalcommits 预设或兼容的 Conventional Commits 发布工具的仓库中编写、修改、审查或建议提交信息时,请使用此技能。
提交格式
使用 Conventional Commits 1.0.0 消息结构:
<type>[optional scope][optional !]: <description>
[optional body]
[optional footer(s)]
规则:
- 必须提供
type,后面可跟可选的括号括起的scope、可选的!,以及:。 - 必须提供
description,紧跟在:后面。保持简洁,适合用于变更日志;除非专有名词或标识符需要使用特定大小写,否则使用小写。末尾不要加句号。 scope是可选的,应指明代码库中的某个部分。- 较长的正文是可选的,应在描述后空一行开始,格式不限。
- 页脚是可选的,应在正文或描述后空一行开始,每个页脚使用
Token: value或Token #value格式。 - 页脚标记使用连字符代替空格,例如
Reviewed-by;但BREAKING CHANGE除外。BREAKING-CHANGE与BREAKING CHANGE同义。 - 页脚值可以包含空格和换行。遇到下一个有效的页脚标记及分隔符时,页脚值结束。
- Conventional Commit 各组成部分不区分大小写,但作为页脚标记使用时,
BREAKING CHANGE必须全大写。 - 对于连贯的更改,优先使用一个提交。如果一个差异中包含互不相关、会显示在发布说明中的更改,建议拆分提交。
- 编写的描述应适合作为生成的变更日志中的条目。避免使用
add some feature、update stuff或fix issue这类含糊的实现说明。优先说明面向用户的结果,例如support custom scopes、preserve prerelease tags或require Node.js 22。 - 在描述中,将代码标识符用反引号括起——包括函数、选项、标志、类型或文件名:
add `autocase` to match camelCase and kebab-case forms、support `--no-*` negation。GitHub 会在提交信息中呈现反引号,生成的变更日志也会保留它们;当普通文本中的flag或rest等词可能产生歧义时,反引号还能标明它们是代码。 - 将任何非有意用于提及 GitHub 用户的
@前缀标记用反引号括起——包括带作用域的包名(@types/node)、装饰器(@Injectable)和 JSDoc/注解标签(@deprecated)。GitHub 会将提交信息和变更日志中的裸@name解析为用户提及,可能链接到无关的 GitHub 账户并通知该用户。 - 通常优先使用主动语态的动词短语,而非被动句。优先使用
support custom scopes,而不是custom scopes were added;除非被动语态对项目来说明显更自然。
破坏性更改通过标题中紧邻 : 前的 ! 或破坏性更改页脚表示。影响已知时,请使用页脚:
feat(parser)!: remove legacy token fallback
BREAKING CHANGE: custom token fallbacks are no longer applied during parsing.
如果使用了 !,但未提供破坏性更改页脚,则由描述说明破坏性更改。
类型选择
默认可见类型:
feat:面向用户的功能;显示在Features下;提升次版本号。提交新增功能时使用。feature:feat的可接受别名;除非要遵循项目现有风格,否则优先使用feat。fix:错误修复或正确性修复;显示在Bug Fixes下;提升修订版本号。提交用于修复错误时使用。perf:性能改进;显示在Performance Improvements下;提升修订版本号。revert:还原提交;显示在Reverts下;提升修订版本号。
默认隐藏类型:
docs:仅修改文档。style:仅修改格式、空白、标点或样式,不改变行为。chore:一般维护,不应记录在变更日志中,也不应提升版本号;仅在没有更具体的隐藏类型适用时使用。refactor:有意保持行为/API 不变的代码修改。test:仅修改测试。build:构建系统、打包、依赖元数据、生成的构建配置。ci:仅修改 CI 工作流或自动化。
将隐藏类型视为不记录变更日志且不提升版本号。如果代码更改明显不会影响已发布的行为或 API,即使修改了源文件,也应使用隐藏类型,而不是 fix 或 feat。
按照 Conventional Commits 规范,除 feat 和 fix 以外的类型也可以使用,但除非包含破坏性更改标记,否则规范不会为它们隐含指定 SemVer 影响。本仓库的预设通过配置的提交类型,赋予了额外的可见性和版本提升行为。
不要将 chore 当作所有隐藏更改的兜底类型。应优先选择最准确描述更改的隐藏类型:包管理器、构建工具、依赖元数据、生成的构建配置和工作区配置使用 build;仅限 CI 的自动化使用 ci;测试使用 test;文档使用 docs;保持行为不变的代码重构使用 refactor;仅修改格式时使用 style。
除非有意改变发布影响,否则不要在隐藏提交中添加 !、BREAKING CHANGE 或 Release-As。这些信号会覆盖隐藏/不提升版本号的意图。
选择隐藏类型之前,先确认差异是否会改变任何已发布包的公共契约,即使更改的文件是元数据、配置、测试、生成文件或 CI 文件。公共契约包括受支持的运行时和平台版本、包导出项、CLI 行为、配置预设、对等依赖要求、生成的输出、已记录的 API 和默认行为。如果公共契约变得更严格、移除了先前支持的用法,或改变了用户可见行为,应使用可见类型。如果先前支持的用法不再有效,应使用 ! 和 BREAKING CHANGE 页脚。
发布影响或破坏性影响的常见警示信号:
- 提高最低运行时、平台、浏览器或引擎支持版本。
- 移除、重命名或缩小包导出项、入口点、CLI 标志、选项、配置预设或已记录 API 的范围。
- 收紧对等依赖版本范围,或提高所需外部工具的要求。
- 更改使用者获得的生成输出、默认值、验证规则、解析行为或 lint/配置规则。
影响判定规则
根据发布影响选择类型,而不是根据文件路径:
- 新增公开行为:
feat。 - 修正公开行为:
fix。 - 不改变行为的运行时速度或内存优化:
perf。 - 更新
dependencies中的运行时依赖:fix。这会改变已发布软件包的依赖关系图,可能改善正确性、安全性或运行时行为,即使未触及源代码,也应触发发布。只有当依赖更新改变或移除了受支持的公开行为时,才使用!。 - 收紧公开契约,或移除之前受支持的用法:使用带有
BREAKING CHANGE页脚的feat!或fix!。例如,将engines.node提高到 Node.js 22 时,主题应类似于require Node.js 22。 - 保持行为不变的内部重写:
refactor。 - 依赖锁文件/软件包管理器维护、构建工具、生成的构建配置,或不改变已发布行为的工作区软件包管理器配置:使用
build,除非本地风格明显更倾向于另一种隐藏类型。 - 仅修改 CI 工作流:
ci。 - 不影响产品代码的测试新增或调整:
test。 - 仅涉及文档/README/示例文本:
docs。 - 不适合更具体的隐藏类型的一般性维护工作:
chore。
如果不确定源代码变更是否会影响用户,请检查测试和公开 API 的用法。如果变更属于防御性清理、迁移衔接、私有辅助函数重命名、lint 修复或仅涉及类型的重组,优先选择隐藏类型。
选择范围
选择范围之前,先检查仓库:
git diff --staged --name-only
git diff --name-only
rg --files -g '*commitlint*' -g '.commitlintrc*' -g 'commitlint.config.*'
rg --files -g 'package.json'
优先使用暂存的变更。如果没有暂存内容,则使用工作树差异。
如果项目使用 commitlint,选择提交消息之前先阅读其配置。配置可能会定义允许的类型、允许的范围、大小写要求、最大长度及其他本地格式规则。常见位置包括 .commitlintrc、.commitlintrc.json、.commitlintrc.yaml、.commitlintrc.yml、.commitlintrc.js、.commitlintrc.cjs、.commitlintrc.mjs、.commitlintrc.ts、commitlint.config.js、commitlint.config.cjs、commitlint.config.mjs 和 commitlint.config.ts。
单仓库项目:
- 通常省略范围。
- 仅当项目已有明确范围(例如
cli、docs、deps、release或子系统名称)时才使用范围。
Monorepo:
- 优先使用受影响的软件包名称作为范围。
- 根据工作区软件包名称、现有的 commitlint
scope-enum或近期提交确定软件包范围。 - 如果 commitlint 或本地工具支持多个范围,且一项连贯的、对发布可见的变更影响多个已发布软件包,则使用所有受影响的软件包范围,而不是将变更归并到一个软件包。
- 优先使用仓库认可的多范围分隔符。如果本地配置允许多个范围,但未明确分隔符,则先用 commitlint 验证逗号分隔的范围列表,再使用它。
- 如果软件包名称带有 npm 作用域,遵循仓库现有约定:使用完整软件包名称或不带作用域的软件包名称部分。
- 如果只修改了一个软件包,则使用该软件包范围。
- 如果多个软件包因同一原因发生变更,且有意义,可使用
deps、dev-deps或release等共享范围。 - 对影响整个 Monorepo 发布、涉及许多软件包的变更,优先省略范围,除非仓库要求填写。发布工具通常根据发生变更的软件包,而不是
global范围来判断受影响的软件包。 - 如果多个软件包因不同原因发生变更,先尝试如实描述共同意图。如果唯一诚实的消息会过于模糊或掩盖发布影响,则建议拆分为多个提交。
仅涉及依赖的工作:
- 如果
deps是可接受的范围,则对dependencies中的运行时依赖更新使用fix(deps)。 - 如果
dev-deps是可接受的范围,则对仅用于开发的工具依赖更新使用dev-deps。
消息构建流程
- 检查已更改文件和差异摘要。
- 确定对已发布行为的影响。
- 选择可见或隐藏类型。
- 选择最精确且有效的范围。
- 若为可见变更,从用户角度将主题写成一条变更日志;若为隐藏变更,则从维护意图出发撰写。
- 仅在需要说明破坏性变更、关闭问题、发布类型或重要背景时添加正文或页脚。
- 如果工作明确关联某个问题、PR、错误报告或用户提供的跟踪 URL,请在提交正文或页脚中添加相关引用。对于应关闭问题的修复,使用
Fixes #123.之类的关闭页脚。对于不关闭问题的背景引用,使用Refs #123.之类的非关闭引用。 - 如果已配置 commitlint 且 CLI 可用,请在向用户提供候选消息前进行验证。
尽可能优先使用本地安装的 commitlint 二进制文件进行验证。优先使用 ./node_modules/.bin/commitlint,而非包管理器运行器,因为它可以避免包管理器环境、沙盒和注册表行为,同时仍使用仓库已安装的版本和配置。
echo 'type(scope): subject' | ./node_modules/.bin/commitlint
仅当本地二进制文件不存在,且在当前环境中可以接受运行时,才将包管理器运行器用作后备方案:
echo 'type(scope): subject' | pnpm commitlint
echo 'type(scope): subject' | npm exec commitlint
echo 'type(scope): subject' | npx commitlint
将示例替换为实际候选消息。对于多行消息,请使用 printf 或其他能原样保留完整消息的命令:
printf '%s\n\n%s\n' 'feat(parser)!: remove legacy token fallback' 'BREAKING CHANGE: custom token fallbacks are no longer applied.' | ./node_modules/.bin/commitlint
如果 commitlint 验证失败,请调整类型、范围、大小写或主题长度,然后重新验证。如果已配置 commitlint,但当前环境无法运行 CLI,请告知用户。
自然地使用问题引用:
fix(parser): handle empty commit body refs #123
仅当提交应关闭问题时,才使用关闭关键词:
fix(cli): preserve prerelease tag when appending changelog
Fixes #123.
对于影响单体仓库中多个软件包的关联变更,在仓库支持时使用多个范围:
fix(package-a,package-b): preserve compare links
Fixes #123.
示例
可见的发布条目:
feat(writer): support scoped package links
feat!: require Node.js 22
feat: add `rest` function to read all remaining arguments
fix(parser): keep issue references from multiline footers
fix(cli): handle `--no-*` flags in strict mode
perf(git-client): avoid duplicate tag lookups
revert: feat(writer): support scoped package links
隐藏的无版本更新条目:
refactor(conventional-changelog): simplify context defaults
test(writer): cover empty reference groups
docs(conventionalcommits): clarify hidden commit types
build(dev-deps): update oxlint
ci: use node 22 in tests
chore(release): prepare package metadata
单体仓库软件包范围:
fix(conventional-changelog-writer): preserve reference order
refactor(conventional-commits-parser): split token normalization
test(git-client): cover lightweight tags
输出风格
用户要求提供提交消息时,只输出推荐的消息,除非用户要求解释或备选方案。对于影响不确定的情况,提供两个简洁选项,并说明各自对发布的影响:
fix(parser): handle empty commit body
或者,如果不打算提升版本:
refactor(parser): handle empty commit body defensively