changelog.md 对 composer 完全透明,它只依赖 git tag 和 composer.json 的 version 字段;必须严格遵循 keep a changelog 规范,确保版本标题、动词开头条目、发布日期与实际代码变更三者严丝合缝。

CHANGELOG.md 对 Composer 完全透明,它只看 composer.json 的 version 字段或 Git tag —— 写得再详细,Composer 也不会读它一眼。
为什么改了 CHANGELOG 却没人在意?
常见错误现象:composer update 后新功能不生效,翻 CHANGELOG.md 发现写了“Added Config::getRequired()”,但实际 vendor 里没这个方法;或者线上报错说找不到类,而 CHANGELOG 里压根没提 BC break。
根本原因不是日志写得不好,而是你把 CHANGELOG 当成了版本权威来源。实际上:
- Composer 安装时只认 Git tag(如
v3.2.0)和composer.json中的"version": "3.2.0"是否一致 - 如果 tag 是
v3.2.0,但composer.json里写的是"version": "3.2.1",Packagist 同步会失败或忽略该版本,## [3.2.0]段落就彻底失效 -
CHANGELOG.md是给人看的,不是给工具链解析的 —— 它不参与依赖解析、不触发任何自动行为
怎么写才真正有用?
必须严格对齐 Keep a Changelog 规范,否则团队和用户根本没法快速判断「值不值得升」或「我的 bug 修没修」。
使用场景:你刚发完 v3.2.0,合并了修复空数组崩溃的 PR #45 和新增方法的 PR #47。
- 标题必须是
## [3.2.0] - 2026-08-25(日期填实际发布日,不是 commit 日) - 每条以动词开头:
Fixed、Added、Deprecated、Removed—— 别用Changed或Updated - 描述要具体:
Fixed YAML parsing crash on empty arrays (#45),而不是“修复 YAML 解析问题” - 禁止嵌套、禁止跨版本混写;旧版本内容绝不动,哪怕发现当年写错了
谁该管 CHANGELOG?谁不该碰?
应用程序(Application)维护者必须写,开源库(Library)作者也必须写;但下游使用者完全不用改它 —— 改了也没人同步。
容易踩的坑:
- 在 library 的
composer.json里硬编码"version"字段:这会让 Packagist 拒绝同步,tag 和 version 不一致时直接失效 - 把
CHANGELOG.md当成 API 文档用:它不承诺接口契约,只记录可观察的行为变化 - 在 CI/CD 中校验
content-hash或composer.lock是否匹配 CHANGELOG:毫无意义,Composer 压根不读它
最常被忽略的一点:CHANGELOG 的价值不在于“有没有”,而在于“是否和 tag、version、实际代码变更三者严丝合缝”。少一个对齐,它就从协作工具退化成装饰性文本。











