本文从一个真实的前端项目出发,梳理 Git Tag 的核心用法、语义化版本规范,以及如何配合 GitHub Actions 实现"打 tag 即发布"的自动化流程。
一、Git Tag 是什么?
你可以把 Tag 理解为 Git 仓库的版本书签。
每次 git commit 产生的 hash(如 1419814)对人类不友好,而 Tag 让你给某个 commit 取一个有意义的名字:
commit 1419814 ←── tag: v1.1.0
commit e368e3a ←── tag: v1.0.0
与分支(branch)不同,Tag 一旦创建就不会随新提交移动,永远指向那个固定的 commit。这使它非常适合标记发布版本。
二、两种 Tag 类型
轻量标签(Lightweight)
只是 commit 的别名,不包含额外信息:
git tag v1.0.0
附注标签(Annotated) ✅ 推荐
包含作者、日期、说明信息,是一个完整的 Git 对象:
git tag -a v1.0.0 -m "首个正式发布版本"
查看区别:
# 轻量标签 — 只显示 commit 信息
git show v1.0.0
# 附注标签 — 额外显示 tag 作者、日期、说明
git show v1.1.0
# Tagger: Rayner <xxx@xxx.com>
# Date: Sun Mar 2 11:34:00 2026 +0800
# feat(diagnosis): add autocomplete presets...
实践建议:正式版本一律用附注标签,轻量标签留给临时标记或个人备忘。
三、Tag 常用操作速查
创建
# 给当前 HEAD 打标签
git tag -a v1.1.0 -m "feat: 新增初诊预设自动匹配功能"
# 给历史 commit 补打标签
git tag -a v0.9.0 abc1234 -m "beta 版本"
查看
# 列出所有标签
git tag -l
# 按版本号降序排列(推荐)
git tag -l --sort=-v:refname
# 模糊筛选
git tag -l "v1.*"
# 查看标签详情
git show v1.1.0
推送到远程
重点:git push 默认不推送标签!必须显式推送:
# 推送单个标签
git push origin v1.1.0
# 推送所有本地标签
git push origin --tags
这是新手最常踩的坑 — 本地打了标签以为万事大吉,结果远程仓库和 CI/CD 完全无感知。
删除
# 删除本地标签
git tag -d v0.6.0
# 删除远程标签
git push origin --delete v0.6.0
基于 Tag 检出代码
# 查看某个版本的代码(进入 detached HEAD 状态)
git checkout v1.0.0
# 基于某个 tag 创建新分支进行修复
git checkout -b hotfix/v1.0.1 v1.0.0
四、语义化版本(Semantic Versioning)
Tag 命名推荐遵循 Semver 2.0.0 规范,格式为 vMAJOR.MINOR.PATCH:
v1.1.0
│ │ │
│ │ └── PATCH 修订号:向下兼容的 bug 修复
│ └──── MINOR 次版本号:向下兼容的新功能
└────── MAJOR 主版本号:包含破坏性变更
版本递增规则
| 变更类型 | 举例 | 版本变化 |
|---|---|---|
| 修复 bug | 修复登录页白屏 | v1.0.0 → v1.0.1 |
| 新增功能(向下兼容) | 新增初诊预设短语 | v1.0.0 → v1.1.0 |
| 破坏性变更 | API 接口重构、移除旧功能 | v1.1.0 → v2.0.0 |
实际判断技巧
核心问题:升级版本后,原来能跑的代码会不会炸?
举个具体例子,假设你维护一个诊断模块,别的同事在调用你的函数:
// 同事的代码
import { updateDiagnosis } from '@/services/diagnosis';
updateDiagnosis(patientId, diagnosisId, { chief_complaint: '头晕' });
三种情况:
| 你做的变更 | 同事的代码需要改吗? | 版本 | 原因 |
|---|---|---|---|
修复了 updateDiagnosis 内部的一个空指针 bug | 不需要,升级即修复 | patch | 行为修正,接口没变 |
新增了 PresetTextArea 组件 | 不需要,原来的代码照常用 | minor | 新功能是增量的,不影响已有代码 |
把 updateDiagnosis(patientId, id, data) 改成了 updateDiagnosis({ patientId, id, ...data }) | 需要! 调用方的参数格式得全改 | major | 接口签名变了,原来的调用会报错 |
简单口诀:
- 升级后原来的代码炸了 → major
- 升级后原来的代码没炸,但多了新东西可以用 → minor
- 升级后原来的代码没炸,只是 bug 少了 → patch
Ant Design 的版本实践
Ant Design 遵循同样的 Semver 规范,它的发布节奏是:
- patch:每周末日常 bugfix
- minor:每月发布带有新特性的向下兼容版本
- major:包含破坏性更新,不在固定周期内(如 antd v5 → v6)
五、Tag + GitHub Actions = 自动发布
这是 Tag 最实用的场景:推送 tag 自动触发构建和发布。
工作流配置
# .github/workflows/release.yml
name: Release
on:
push:
tags:
- 'v*.*.*' # 匹配所有 semver 格式的 tag
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- run: npm ci
- run: npm run build
# 打包构建产物
- name: Package dist
run: zip -r dist-${{ github.ref_name }}.zip dist/
# 创建 GitHub Release 并上传附件
- name: Create Release
uses: softprops/action-gh-release@v2
with:
generate_release_notes: true
files: dist-${{ github.ref_name }}.zip
完整发布流程
# 1. 开发完成,提交代码
git add .
git commit -m "feat(diagnosis): add autocomplete presets"
# 2. 推送代码
git push
# 3. 打附注标签
git tag -a v1.1.0 -m "feat: 新增初诊预设自动匹配功能"
# 4. 推送标签(触发 CI/CD)
git push origin v1.1.0
# 5. GitHub Actions 自动执行:
# checkout → install → build → zip → create release
推送 tag 后,在 GitHub 仓库的 Actions 页面可以看到 workflow 被触发,完成后会在 Releases 页面生成一个新版本,附带构建产物的 zip 包。
触发条件解析
on:
push:
tags:
- 'v*.*.*'
v1.0.0— 匹配 ✅v1.1.0— 匹配 ✅v2.0.0-beta.1— 不匹配 ❌(多了-beta.1)release-1.0— 不匹配 ❌(缺少v前缀)
如果需要匹配预发布版本,可以改为 'v*' 或添加 'v*.*.*-*'。
六、常见问题
Q1:打错了 tag 怎么办?
# 删除本地错误 tag
git tag -d v0.6.0
# 如果已推送到远程,也要删除远程
git push origin --delete v0.6.0
# 重新打正确的 tag
git tag -a v1.1.0 -m "正确的版本"
git push origin v1.1.0
Q2:忘记推送 tag,CI/CD 没触发?
git push 只推送分支,不推送标签。必须额外执行:
git push origin v1.1.0
# 或推送所有标签
git push origin --tags
Q3:Tag 和 Branch 有什么区别?
| 特性 | Tag | Branch |
|---|---|---|
| 是否移动 | 固定不动 | 随 commit 前移 |
| 用途 | 标记版本快照 | 开发分支 |
| 推送方式 | 需显式推送 | git push 自动推送 |
Q4:什么时候该打 tag?
- 功能开发完成、测试通过、准备发布时
- 不要在开发过程中频繁打 tag
- 一个 tag 对应一个可发布的稳定版本
七、总结
开发完成 → git commit → git tag -a vX.Y.Z → git push origin vX.Y.Z
│
遵循 Semver 规范
patch: 修 bug
minor: 加功能
major: 破坏性更新
│
推送触发 CI/CD → 自动构建发布
Git Tag 本身很简单,但结合语义化版本和 CI/CD,就构成了一套完整的版本管理与自动发布体系。掌握这套流程,你的项目发布就从"手动打包上传"进化到了"一行命令自动搞定"。
参考资料: