3. 版本语义与制品命名规范
在发布编排中,版本号不是“随便起个名字”,而是贯穿构建、测试、制品仓库、部署与回滚的主键。版本语义一旦混乱,后续的制品追溯、灰度判断、回滚定位都会失效。本节围绕四件事展开:SemVer 与 CalVer 的适用边界、构建元数据如何承载可追溯信息、制品命名如何做到唯一且可解析,以及这些规则如何映射到 GitLab CI 变量。
一、SemVer:用三段数字表达兼容性承诺
SemVer(语义化版本)格式为 MAJOR.MINOR.PATCH,其核心不是数字本身,而是兼容性契约:
- MAJOR:不兼容的 API 变更,升级方必须改代码或改配置。
- MINOR:向后兼容的功能新增,旧调用方式仍可用。
- PATCH:向后兼容的缺陷修复,不新增功能。
预发布版本追加连字符标识,如 1.4.0-rc.1;构建元数据追加加号,如 1.4.0+20240521.3。注意 SemVer 规定:构建元数据不参与版本优先级比较,1.4.0+a 与 1.4.0+b 视为同一版本。因此元数据只能用于追溯,不能用来区分“谁更新”。
一个常见误区是把 CI 流水线号直接塞进 PATCH,例如 1.4.137。这会让 PATCH 失去“修复”语义,消费者无法判断 137 与 138 之间是否兼容。正确做法是:PATCH 由人工或变更类型决定,流水线号放入构建元数据。
二、CalVer:用时间表达发布节奏
当产品以固定节奏发布、且不对外承诺 API 兼容性时,CalVer(日历版本)更直观。常见格式有 YYYY.MM.DD、YY.MM、YYYY.MINOR.PATCH。例如 2024.05.1 表示 2024 年 5 月第 1 次发布。
CalVer 的优点是时间可读、排序天然递增;缺点是无法从版本号判断兼容性。因此采用 CalVer 的项目必须额外维护兼容性说明或变更日志。选择建议:库、SDK、对外 API 用 SemVer;内部服务、镜像、数据集、定期快照用 CalVer。
三、构建元数据:让每个制品可追溯
构建元数据是版本号中“+ ”之后的部分,也是 CI 中最有价值的信息载体。推荐至少包含:提交短 SHA、流水线 ID、构建时间。例如:
1.4.0+git.a1b2c3d.pipeline.8821.20240521T0930Z
这样任何一个制品都能反查到具体提交与流水线。需要注意:元数据中不要放会破坏文件系统或 URL 的字符,建议只使用小写字母、数字、点、连字符。若制品要发布到 npm、PyPI 等公共仓库,需确认其对元数据字符的限制。
四、制品命名:唯一、可解析、可排序
制品文件名应满足三个条件:全局唯一、可被脚本解析、按字典序可近似排序。推荐命名模板:
{项目}-{版本}-{平台}-{架构}.{扩展名}
示例:
payment-api-1.4.0-linux-amd64.tar.gz
payment-api-1.4.0-linux-arm64.tar.gz
web-console-2024.05.1-static.zip
若同一版本需要多次构建(如重跑流水线),应在文件名中追加流水线 ID 或构建号,避免覆盖:payment-api-1.4.0+git.a1b2c3d-linux-amd64.tar.gz。注意 + 在 URL 中会被解析为空格,若制品通过 HTTP 下载,建议用 _ 或 . 替代,或在发布时做 URL 编码。
五、GitLab CI 变量映射
GitLab 预定义变量是版本生成的原料。关键变量包括:CI_COMMIT_TAG、CI_COMMIT_SHORT_SHA、CI_PIPELINE_IID、CI_COMMIT_REF_SLUG、CI_JOB_ID。映射策略如下:
- 打标签发布:
CI_COMMIT_TAG直接作为版本号,如v1.4.0,去掉前缀v后使用。 - 分支构建:版本号 = 基础版本 + 预发布标识 + 提交短 SHA,如
1.4.0-dev.a1b2c3d。 - 构建元数据:由
CI_PIPELINE_IID与CI_COMMIT_SHORT_SHA拼接。 - 制品名:由
CI_PROJECT_NAME、版本、CI_COMMIT_REF_SLUG组合。
下面这张图展示了从 GitLab CI 变量到最终版本号与制品名的映射链路,以及 SemVer 与 CalVer 两条分支的差异。
六、落地检查清单
在流水线中落地版本规范时,建议逐项确认:
- 版本号是否由单一来源生成?推荐在
before_script中统一计算并写入VERSION变量,后续 job 只引用。 - 标签发布与分支构建是否走不同分支逻辑?标签必须严格校验格式,分支必须带预发布标识。
- 制品名是否包含平台与架构?多架构构建时缺少这两项会导致覆盖。
- 构建元数据是否包含提交 SHA 与流水线 ID?缺少任一项都会降低追溯能力。
- 是否验证了版本号在制品仓库中的唯一性?重复上传应失败而非静默覆盖。
validate-version job,用正则校验 CI_COMMIT_TAG 是否符合 ^v\d+\.\d+\.\d+(-[0-9A-Za-z.-]+)?$,不符合则直接失败,避免非法版本进入制品仓库。版本语义与制品命名看似是“格式问题”,实则是发布治理的基础设施。把 SemVer/CalVer 的选择、构建元数据的字段、制品名的模板、CI 变量的映射四件事固定下来,后续的灰度、回滚、审计才有稳定的锚点。