# SemVer 2.0.0 规范细节

> 来源：https://semver.org/ ，缓存于 2026-05-21。本文件是 SKILL.md 的补充，覆盖预发布优先级、版本比较、构建元数据、0.y.z 与常见误区。决策主流程见 [../SKILL.md](../SKILL.md)。

## 1. 版本号构成（规范 §2、§9、§10）

完整形态：`MAJOR.MINOR.PATCH[-预发布][+构建元数据]`

- `MAJOR` / `MINOR` / `PATCH`：非负整数，**禁止前导零**（`01` 非法）
- 预发布（pre-release）：紧跟 `-`，由点分标识符组成，如 `-alpha`、`-alpha.1`、`-0.3.7`、`-x.7.z.92`
  - 每个标识符仅含 `[0-9A-Za-z-]`，不可为空
  - 纯数字标识符**禁止前导零**
- 构建元数据（build metadata）：紧跟 `+`，同样点分标识符，如 `+001`、`+20130313144700`、`+exp.sha.5114f85`

## 2. 递增规则（规范 §6、§7、§8）

- §6 **PATCH**（`z`，x.y.Z）：仅当引入**向后兼容的 bug 修复**时递增
- §7 **MINOR**（`y`，x.Y.z）：新增**向后兼容**的功能时**必须**递增；公开 API 中任何功能被标记为 deprecated **必须**递增；也**可**在新增大量内部新功能时递增。递增时 patch **必须**归零
- §8 **MAJOR**（`x`，X.y.z）：引入**向后不兼容**的 API 变更时**必须**递增。递增时 minor、patch **必须**归零。可包含 minor、patch 级别的变更

## 3. 主版本 0（规范 §4、§5）

- §4：`0.y.z` 用于初始开发，**任何东西都可能随时变化**，公开 API **不应**视为稳定
- §5：`1.0.0` 定义公开 API。此后版本号如何递增由这套 API 的变化决定

## 4. 发布不可变（规范 §3）

一旦某个版本的包发布，其内容**禁止修改**。任何修改都**必须**作为新版本发布。这是版本号可被依赖的前提。

## 5. 预发布优先级（规范 §9、§11）

预发布版本表示**可能不稳定、未必满足正式版兼容要求**。其优先级**低于**关联的正式版：

```
1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta
            < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0
```

## 6. 版本优先级比较规则（规范 §11）

判断两个版本谁"新"：

1. **§11.2** 先比 MAJOR、MINOR、PATCH，按数值依次比较：`1.0.0 < 2.0.0 < 2.1.0 < 2.1.1`
2. **§11.3** major/minor/patch 相同时，**有预发布的一方优先级更低**：`1.0.0-alpha < 1.0.0`
3. **§11.4** 两者都有预发布时，从左到右逐个标识符比较：
   - 纯数字标识符按**数值**比较
   - 含字母/连字符的标识符按 **ASCII 字典序**比较
   - **数字标识符** 优先级**低于** 非数字标识符（`alpha.1` 中 `1` < `alpha`）
   - 前面都相等时，**字段更多**的一方优先级更高（`alpha < alpha.1`）

**构建元数据不参与比较**（§10）：`1.0.0+build.1`、`1.0.0+build.2`、`1.0.0` 优先级相同。

## 7. 常见误区

| 误区 | 纠正 |
|------|------|
| "改了代码就得升 patch" | 纯内部、无 API 影响的改动也可不发版；发版才需定级别 |
| "加功能一定升 minor" | 若新功能破坏了旧用法（如改了默认行为），是 MAJOR |
| "bug 修复一定是 patch" | 若有人依赖旧（错误）行为，修复对其是 breaking，倾向 MAJOR |
| "0.x 可以随便发" | 规范允许，但社区惯例仍区分 minor=breaking、patch=feature/fix |
| "1.0.0-rc.1 比 1.0.0 新" | 反了，预发布优先级低于正式版 |
| "构建元数据能区分版本新旧" | 不能，比较时被忽略 |
| "版本号能跳"（1.0.0 → 1.0.5） | 不能，必须逐级递增 |

## 8. 与 npm/node-semver 的关系

`scripts/bump.py` 的预发布递增语义对齐 [node-semver](https://github.com/npm/node-semver) 的 `semver.inc()`：
- `premajor/preminor/prepatch`：先递增对应位再加 `-preid.0`
- `prerelease`：无预发布时等价 `prepatch` 加预发布；已有预发布时递增末位数字，或换 preid 重置为 0
- 升 `major/minor/patch` 时若当前正好是对应位的预发布版（如 `2.0.0-rc.1` 升 major），仅转为正式版而不再 +1
