先说结论维护者和贡献者吵得最不值当的架有一半来自两句话没说清这次合并到底改了什么对用户来说升级会不会踩雷Conventional Commits约定式提交解决「单次 commit 怎么一眼看懂」CHANGELOG变更日志解决「版本与版本之间到底差在哪」。二者都不绑定某一托管平台GitHub、GitCode、Gitee 一样用——差别只在_release 按钮在哪写作习惯是通用的。一、为什么单靠「好好写中文 commit」往往不够小团队可以靠口头同步一旦进入开源协作PR 里 conversation 很长评审结束后读者只看主线历史。发版时要写 Release Notes若平时 commit 杂乱只能临时翻 diff容易漏改、漏写破坏性变更。约定式提交的价值是把信息嵌进机器可读 人可读的格式里方便后续接 lint、生成文档、甚至自动化发版可选。二、Conventional Commits最小够用格式核心结构就一行类型(可选作用域): 描述 [可选正文] [可选脚注]1常用类型背这 6 个就够开工类型典型含义feat新功能往往对应次版本号 bumpfix修复缺陷往往对应补丁版本docs仅文档chore构建/工具/杂项不改变对外行为refactor重构但不改行为test测试相关2作用域可选但很有用例子fix(auth): handle expired refresh token读者一眼知道动的是auth模块而不是全局乱扫。3破坏性变更怎么写必须在脚注或正文中显式声明例如feat(api)!: remove legacy /v1/ping endpoint BREAKING CHANGE: clients must switch to /v2/ping!在类型后是一种常见简写工具链若支持会识别无论如何文字里写清 BREAKING CHANGE最稳妥。三、和 SemVer 怎么「弱绑定」心态要对语义化版本SemVerMAJOR.MINOR.PATCH是发布策略约定式提交是沟通格式。二者常见约定非强制全世界统一是fix→ 多数情况 bumpPATCHfeat→ 多数情况 bumpMINOR破坏性变更→ bumpMAJOR实际项目以你们RELEASE.md或自动化工具配置为准新手记住有破坏性变更就一定要在 CHANGELOG 里吼一声。四、CHANGELOG推荐「Keep a Changelog」心智不必一上来就上复杂工具。维护者最小可行路径是仓库根目录放CHANGELOG.md。每个版本一节按Added / Changed / Fixed / Removed / Security分类可以只用到其中几类。发版前把本周期内符合约定的 PR/commit归类抄进去。读者最关心三类信息新增能力要不要升级尝鲜修复了啥坑要不要立刻升级不兼容点升级前要改代码吗反例尽量避免只写「修复若干问题」——等于没说。把内部重构写满三屏——对外用户不关心。五、可核对命令从 git 历史里「抠」本次发布范围发版前维护者常用提交区间做核对把 tag 名换成你们仓库真实标签# 上一版本标签至今的提交列表示例gitlog v1.2.0..HEAD--oneline# 只看符合约定式前缀的行粗筛按需调整正则gitlog v1.2.0..HEAD--oneline|grep-E^(feat|fix|docs|chore|refactor|test)若你们完全没用 tag也可以先用日期或合并提交的起点但长期建议打 annotated tag管版本。gittag-av1.3.0-mrelease v1.3.0gitpush origin v1.3.0六、可选进阶什么时候再上自动化当贡献者变多、发版变频繁再考虑commitlint在 CI 里拦截不规范提交信息需团队共识否则摩擦大。standard-version / release-it / changesets等自动生成版本号与 CHANGELOG 草稿。原则是先把约定写进 CONTRIBUTING.md再上加锁工具。否则新人第一条 PR 就被 lint 打回体验很差。七、给贡献者的一句话看到仓库里有CONTRIBUTING.md写了 commit 规范就照着写没有的话优先模仿现有历史里最多的那种前缀样式别独自发明新方言。总结Conventional Commits 不是形式主义而是把「以后要写 Release Notes」的成本前置到每次提交CHANGELOG 是对用户的承诺摘要。两件事都做轻量一点你的 Fork→PR 合并进去之后维护者发版会轻松很多——反过来你也更容易拿到「合并」。你们仓库现在是手写 CHANGELOG、自动生成还是「几乎没有」