什么是变更日志

变更日志(Changelog)是一个按时间顺序记录项目所有重要变更的文件。它帮助用户、开发者和利益相关者了解每个版本中发生了什么变化,包括新功能、Bug 修复、破坏性变更等。

为什么需要变更日志

  • 用户友好:让用户快速了解新功能、修复的问题和需要注意的变更
  • 版本追溯:帮助定位问题首次出现或修复的版本
  • 团队协作:统一团队对变更的理解和沟通
  • 发布管理:辅助版本发布流程和发布说明的撰写

与 Git Log 的区别

特性 变更日志 Git Log
目标受众 用户、开发者、利益相关者 开发者
内容粒度 功能级别的高级描述 每次提交的详细记录
可读性 高度结构化、易于阅读 技术性强、包含实现细节
维护方式 手动维护或自动化生成 自动记录所有提交
版本关联 按版本组织 按时间顺序

Git Log 记录所有的代码提交,包括内部重构、测试调整等;而变更日志只记录对用户有意义的变更。

Keep a Changelog 规范

Keep a Changelog 是目前最广泛采用的变更日志规范,由 Olivier Lacan 创建。

变更类型分类

Keep a Changelog 定义了以下变更类型:

  • Added:新增的功能
  • Changed:现有功能的变更
  • Deprecated:即将移除的功能
  • Removed:已移除的功能
  • Fixed:Bug 修复
  • Security:安全相关的变更

格式规范

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added
- 新功能的描述

### Changed
- 功能变更的描述

### Deprecated
- 即将废弃的功能

### Removed
- 已移除的功能

### Fixed
- 修复的 Bug

### Security
- 安全修复

## [1.0.0] - 2017-06-20

### Added
- 其他变更

Unreleased 部分

Unreleased 部分用于记录尚未发布的变更。当准备发布新版本时:

  1. 创建新的版本标题(如 [1.2.0] - 2024-01-15
  2. 将 Unreleased 中的变更移动到新版本下
  3. 清空 Unreleased 部分,开始记录下一个版本的变更

版本链接

对于 GitHub 等平台,可以添加版本比较链接:

1
2
3
4
5
6
7
8
9
10
11
12
13
## [1.0.0] - 2017-06-20

### Added
- New visual identity by [@tylerfortune8](https://github.com/tylerfortune8).

## [0.3.0] - 2017-05-03

### Changed
- Update documentation layout.

[Unreleased]: https://github.com/example/project/compare/v1.0.0...HEAD
[1.0.0]: https://github.com/example/project/compare/v0.3.0...v1.0.0
[0.3.0]: https://github.com/example/project/releases/tag/v0.3.0

完整的 CHANGELOG.md 示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added
- Dark mode support in settings
- Export data to CSV format

### Changed
- Improve dashboard loading performance
- Update API rate limit handling

### Fixed
- Fix authentication token expiration issue
- Resolve memory leak in background tasks

## [2.1.0] - 2024-01-15

### Added
- New notification system
- Support for custom themes
- Two-factor authentication

### Changed
- Redesign user interface
- Migrate to new authentication backend

### Deprecated
- Old API endpoints will be removed in v3.0.0

### Fixed
- Fix crash when processing large files
- Correct timezone handling in date filters

## [2.0.0] - 2023-12-01

### Added
- Complete rewrite of the core engine
- Plugin system for extensions
- Real-time collaboration features

### Changed
- **BREAKING**: Configuration file format changed from YAML to TOML
- **BREAKING**: API v1 endpoints are now deprecated, use v2

### Removed
- Legacy authentication method
- Support for Python 2.7

### Fixed
- Multiple security vulnerabilities (CVE-2023-1234, CVE-2023-5678)

### Security
- Implement rate limiting to prevent DoS attacks

## [1.5.0] - 2023-10-20

### Added
- Export reports to PDF
- Batch operation support

### Fixed
- Fix issue with special characters in filenames

[Unreleased]: https://github.com/example/project/compare/v2.1.0...HEAD
[2.1.0]: https://github.com/example/project/compare/v2.0.0...v2.1.0
[2.0.0]: https://github.com/example/project/compare/v1.5.0...v2.0.0
[1.5.0]: https://github.com/example/project/releases/tag/v1.5.0

Conventional Commits 规范

Conventional Commits 是一种用于创建明确 commit history 的轻量级约定。

Commit Message 格式

1
2
3
4
5
<type>[optional scope]: <description>

[optional body]

[optional footer(s)]

Type(类型)

Type 必须是以下之一:

  • feat:新功能(feature)
  • fix:Bug 修复
  • docs:文档变更(documentation)
  • style:代码格式调整(不影响代码运行的变动)
  • refactor:重构(既不是新增功能,也不是修复 bug)
  • perf:性能优化
  • test:增加测试
  • chore:构建过程或辅助工具的变动
  • ci:CI 配置文件和脚本的变更
  • build:影响构建系统或外部依赖的变更

Scope(范围)

Scope 用于指定 commit 影响的范围,通常是模块名或组件名。

示例:feat(parser): add support for nested objects

Description(描述)

Description 是对变更的简短描述,使用现在时态祈使语气:“add” 而非 “added” 或 “adds”。

Body(正文)

Body 用于详细描述变更,可以包含多个段落。

1
2
3
4
5
6
7
8
feat(api): add user authentication

Implement OAuth2 authentication flow with support for:
- Google OAuth
- GitHub OAuth
- Custom OAuth providers

Closes #123

Footer 用于关联 Issue 或标记破坏性变更。

Breaking Change

1
2
3
4
feat(api): remove deprecated endpoints

BREAKING CHANGE: The `/api/v1/users` endpoint has been removed.
Use `/api/v2/users` instead.

关联 Issue

1
2
3
4
fix(auth): resolve token expiration issue

Closes #456
Refs #789

Commit Message 示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 新功能
feat(auth): add two-factor authentication support

# Bug 修复
fix(database): resolve connection pool exhaustion

# 文档变更
docs(readme): update installation instructions

# 代码格式
style(ui): adjust button spacing

# 重构
refactor(utils): simplify date parsing logic

# 性能优化
perf(api): optimize query response time

# 测试
feat(user): add unit tests for user service

# 构建/工具
chore(deps): upgrade lodash to version 4.17.21

# 破坏性变更
feat(core): remove legacy sync API

BREAKING CHANGE: The sync() method has been removed.
Use the new async syncData() method instead.

自动化工具

conventional-changelog

conventional-changelog 是根据 Conventional Commits 自动生成变更日志的工具。

安装

1
npm install -g conventional-changelog-cli

使用

1
2
3
4
5
# 生成变更日志(首次)
conventional-changelog -p angular -i CHANGELOG.md -s

# 更新变更日志
conventional-changelog -p angular -i CHANGELOG.md -r 0

配置选项

  • -p:预设类型(angular、atom、codemirror、ember、eslint、jshint 等)
  • -i:变更日志文件路径
  • -s:与现有变更日志合并
  • -r:发布版本数量(0 表示全部)

standard-version / release-please

这两个工具不仅生成变更日志,还会自动管理版本号和 Git 标签。

standard-version

1
2
3
4
5
6
7
npm install -g standard-version

# 发布新版本
standard-version

# 或作为 npm script
npm run release

release-please

1
2
3
4
npm install -g release-please

# 创建 pull request 包含版本更新
release-please release-pr

commitlint

commitlint 用于检查 commit message 是否符合 Conventional Commits 规范。

安装

1
npm install --save-dev @commitlint/{cli,config-conventional}

配置

创建 commitlint.config.js

1
2
3
4
5
6
7
8
9
10
11
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [
2,
'always',
['feat', 'fix', 'docs', 'style', 'refactor', 'perf', 'test', 'chore']
],
'scope-case': [2, 'always', 'kebab-case']
}
};

与 Husky 集成

1
2
3
npm install --save-dev husky
npx husky install
npx husky add .husky/commit-msg 'npx commitlint --edit $1'

Conventional Commits 与语义版本化的映射

语义版本化(Semantic Versioning)使用 MAJOR.MINOR.PATCH 格式:

  • MAJOR:不兼容的 API 修改
  • MINOR:向下兼容的功能性新增
  • PATCH:向下兼容的问题修正

Conventional Commits 与语义版本化的映射关系:

Commit Type 版本影响 说明
feat MINOR 新增功能,向下兼容
fix PATCH Bug 修复,向下兼容
BREAKING CHANGE MAJOR 破坏性变更
其他类型 无影响 不影响版本号

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
# 这些提交会导致 MINOR 版本递增
feat(api): add user profile endpoint
feat(ui): implement dark mode

# 这些提交会导致 PATCH 版本递增
fix(auth): resolve login timeout issue
fix(database): handle null values correctly

# 这个提交会导致 MAJOR 版本递增
feat(core): migrate to new data format

BREAKING CHANGE: Data format changed from JSON to YAML.
All existing data must be migrated using the migration tool.

版本计算示例

假设当前版本是 1.2.3

  • 如果只有 fixchore 提交 → 1.2.4
  • 如果有 feat 提交 → 1.3.0
  • 如果有 BREAKING CHANGE2.0.0

最佳实践建议

1. 保持一致性

  • 在整个项目中使用相同的 commit message 风格
  • 建立团队规范,确保所有成员遵循约定
  • 使用工具强制执行规范(如 commitlint)

2. 编写有意义的描述

  • 描述应该清晰说明"做了什么"而不是"为什么做"
  • 使用现在时态祈使语气:“add” 而非 “added”
  • 保持简洁,通常不超过 50 个字符

3. 合理使用 Scope

  • Scope 应该反映受影响的模块或组件
  • 对于大型项目,Scope 可以帮助快速定位变更
  • 避免过于笼统或过于具体的 Scope

4. 及时更新变更日志

  • 定期从 Unreleased 部分发布变更
  • 在每个版本发布后更新版本链接
  • 保持变更日志的可读性和结构

5. 利用自动化工具

  • 使用 conventional-changelog 自动生成变更日志
  • 使用 commitlint 确保 commit message 质量
  • 使用 standard-versionrelease-please 自动管理版本

6. 处理破坏性变更

  • 在 commit message 中明确标记 BREAKING CHANGE
  • 在变更日志中详细说明迁移指南
  • 提供足够的过渡期和兼容性方案

7. 维护 Unreleased 部分

  • 在开发过程中持续记录变更
  • 定期整理和归类变更
  • 发布时将变更移动到对应版本

8. 文档化工作流程

  • 为团队成员提供清晰的指南
  • 包含 commit message 示例
  • 说明工具的使用方法

9. 定期审查和优化

  • 定期检查变更日志的质量
  • 根据项目需求调整规范
  • 收集团队反馈并改进流程

10. 与 CI/CD 集成

  • 在 CI 流程中验证 commit message
  • 自动生成发布说明
  • 集成到自动化发布流程中

总结

变更日志规范是软件工程中的重要实践,它:

  • 提高透明度:让用户和开发者清楚了解项目演进
  • 简化协作:统一团队的沟通和协作方式
  • 自动化流程:通过工具链减少手动工作
  • 提升质量:规范的 commit message 和变更记录

通过遵循 Keep a Changelog 和 Conventional Commits 规范,结合自动化工具,可以建立高效的版本管理和变更追踪体系。

推荐的工具链组合:

  1. commitlint:验证 commit message
  2. husky:Git hooks 管理
  3. conventional-changelog:生成变更日志
  4. standard-version:自动化版本管理

这套工作流已被广泛应用于开源项目和企业级应用中,能够显著提升项目的维护质量和开发效率。