Chapter 06

标签与版本发布

用语义化版本标记里程碑——从 Git Tag 到 SemVer 规范与自动化 CHANGELOG

什么是标签

标签(Tag)是指向特定 commit 的永久引用。与分支不同,标签一旦创建,通常不会移动——分支会随着新提交而前进,标签则始终指向它被创建时的那个 commit。

标签的典型用途:标记软件版本发布(v1.0.0v2.3.1-beta.1),方便将来快速找到某个版本对应的代码。

两种标签类型

轻量标签(Lightweight Tag)

本质上只是一个指向某个 commit 的指针(就像分支一样),不包含任何额外信息。

# 在当前 HEAD 处创建轻量标签
git tag v1.0.0

# 在指定 commit 处创建
git tag v0.9.0 abc1234

附注标签(Annotated Tag)—— 推荐

附注标签是 Git 数据库中的一个完整对象,包含:标签者姓名和邮箱、创建日期、标签消息,以及可选的 GPG 签名。

# 创建附注标签(-a = annotated,-m = message)
git tag -a v1.0.0 -m "Release version 1.0.0"

# 创建并打开编辑器输入详细标签信息
git tag -a v1.0.0

# 创建 GPG 签名的标签(-s)
git tag -s v1.0.0 -m "Signed release v1.0.0"

为什么推荐附注标签?附注标签包含完整的元数据(谁打的、什么时候打的、为什么打),可以用 GPG 签名验证真实性,在 GitHub/GitLab 上可以自动触发 Release 页面的生成。

标签操作

# 列出所有标签
git tag

# 按模式过滤列出(支持通配符)
git tag -l "v1.*"

# 查看标签详情(显示标签信息 + 对应的 commit)
git show v1.0.0

# 检出到某个标签(进入 detached HEAD 状态)
git checkout v1.0.0
# 建议检出标签后立即创建分支
git switch -c hotfix-v1.0.x

给历史提交打标签

忘记打标签?没关系,可以对过去的任意提交补打标签。

# 先找到要打标签的提交哈希
git log --oneline

# 对历史提交打附注标签
git tag -a v0.9.0 abc1234 -m "Retroactively tag 0.9.0 release"

推送标签到远程

标签不会随 git push 自动推送,需要显式操作。

# 推送单个标签
git push origin v1.0.0

# 推送所有本地标签到远程
git push origin --tags

# 只推送附注标签(不推送轻量标签)
git push origin --follow-tags

GitHub Release:当你推送一个附注标签到 GitHub 后,可以在 GitHub 仓库的 "Releases" 页面找到它,并在那里添加发布说明、附上编译好的二进制文件,创建正式的 Release。

删除标签

# 删除本地标签
git tag -d v1.0.0

# 删除远程标签(方式一)
git push origin :refs/tags/v1.0.0

# 删除远程标签(方式二,更直观)
git push origin --delete v1.0.0

语义化版本(SemVer)

Semantic Versioning(语义化版本)是一套被广泛采用的版本号规范,格式为 MAJOR.MINOR.PATCH(如 2.1.3)。

字段含义递增时机
MAJOR(主版本)重大变更不兼容的 API 变更时(Breaking Change)
MINOR(次版本)功能新增新增了向后兼容的新功能时
PATCH(补丁)Bug 修复向后兼容的 bug 修复

预发布版本与构建元数据

2.1.3-alpha.1    # alpha 版本,内部测试
2.1.3-beta.2     # beta 版本,公测
2.1.3-rc.1       # Release Candidate,发布候选
2.1.3+build.456  # 构建元数据(不影响版本优先级)

版本号规则示例

版本号从 1.0.0 开始意味着你的公开 API 已稳定,承诺向后兼容性。在 API 稳定之前,使用 0.x.x 版本以表明仍处于初期开发阶段。

CHANGELOG 与自动化发布

CHANGELOG 是一个记录每个版本"做了什么变化"的文档,帮助用户快速了解升级影响。

手动维护 CHANGELOG

# CHANGELOG.md

## [2.1.0] - 2024-03-15

### Added
- Dark mode support
- Export to PDF feature

### Fixed
- Fix crash when user has no avatar

### Changed
- Redesigned settings page

## [2.0.0] - 2024-01-10

### BREAKING CHANGES
- Renamed `getUserById` to `getUser`
- Removed deprecated `legacyLogin` endpoint

Conventional Commits → 自动生成 CHANGELOG

遵循 Conventional Commits 规范的项目,可以使用工具自动生成 CHANGELOG 并自动递增版本号:

# 使用 standard-version(传统方案)
npx standard-version

# 使用 release-please(Google 推荐,GitHub Actions 集成)
# 在 GitHub Actions 中配置,自动分析 commit,创建 Release PR

# 使用 semantic-release(全自动方案)
npx semantic-release

这些工具会分析 commit 信息(feat: → MINOR,fix: → PATCH,feat!:BREAKING CHANGE → MAJOR),自动决定下一个版本号,生成 CHANGELOG,打标签,发布 Release。这就是为什么 Conventional Commits 规范如此重要。