语义化版本校验实战:批量做 semver 检查,揪出不规范的版本号
发版前对着一堆版本号做语义化版本校验,逐行判定主.次.修订三段数字是否合规,识别带前导零和空预发布标签的脏数据,把审计结果交给 CI 和依赖清单复核。
语义化版本校验实战:批量做 semver 检查,揪出不规范的版本号
依赖清单里混进一个不合规的版本号,往往要到 CI 红了或者线上拉错包才被发现。语义化版本(Semantic Versioning,简称 semver)的规则其实很死板:核心必须是 主版本.次版本.修订号 三段非负整数,中间用点号连接,后面可以挂可选的预发布标签和构建元数据。可真正落到一份几百行的清单上,人眼一行行核对既慢又容易漏。这篇讲怎么把这件事批量做掉。
主.次.修订:三段数字的硬规则
semver 的核心格式是 MAJOR.MINOR.PATCH,三段都得是数字,缺一不可。常被忽略的几条:
- 三段都不能带前导零,
01.2.3里的01直接判失败,只能写1.2.3。 - 修订号不能省。
1.2看着像版本号,但少了第三段,不是合法 semver。 - 多一段也不行。
1.2.3.4是四段,超出三段核心结构,同样不通过。 - 预发布标签跟在修订号后面,用连字符引出,比如
1.0.0-alpha.beta;每个点号分隔的标识符不能为空,1.0.0-这种空标签会被判失败。 - 构建元数据用加号引出,比如
1.0.0+build.5,它不参与版本优先级比较。
记住一点:格式合法只代表写法对,不代表这个版本真的发布过。校验通过的版本号,仍可能是个根本不存在的 tag。
一份真实的输入输出例子
把下面这几行粘进 语义化版本号列表校验器:
1.2.3
v1.2
1.2.3.4
1.0.0-alpha.beta
01.2.3
逐行判定结果:
| 输入 | 结果 | 原因 | | --- | --- | --- | | 1.2.3 | 通过 | 标准三段 | | v1.2 | 失败 | 带 v 前缀且缺修订号 | | 1.2.3.4 | 失败 | 四段,超出三段核心 | | 1.0.0-alpha.beta | 通过 | 合法预发布标签 | | 01.2.3 | 失败 | 主版本带前导零 |
1.2.3 和 1.0.0-alpha.beta 通过,v1.2,1.2.3.4,01.2.3 各自因为不同的规则被拦下。每一条失败的旁边都给出具体原因,不用你回头猜是哪条规则没过。
发版前和 CI 里怎么用
这件事最该卡在两个位置。一个是发版前的人工复核:把 package.json,go.mod,镜像 tag 列表或者发布说明里的版本字符串挑出来,过一遍校验,确认没有手滑写成 1.2 或者 1.0.0- 这种半截标签。另一个是 CI 流程:把待校验的清单导出成 CSV 或 JSON,作为流水线的一道前置门禁,有失败行就让构建停下来,而不是等部署阶段才暴雷。
我自己整理一份跨服务的依赖矩阵时,从十几个仓库的导出里复制版本号,中间夹着客服工单截来的文本和 Markdown 笔记,肉眼根本看不出哪行多了个隐藏空格或者少了一段。粘进来跑一遍,带前导零的和缺修订号的几行立刻被标红,省掉的不只是核对时间,更是漏改一处的返工。
预发布标签和清单去重
预发布标签是踩坑高发区。1.0.0-rc.1,1.0.0-alpha.1,1.0.0-0.3.7 都是合法写法,但标识符之间任何一个为空都算违规。批量校验时把这类边角情况一并交给规则判,比靠记忆可靠得多。
清单审计还有个常见需求是去重和规范化。同一个版本可能在不同来源里反复出现,网页复制来的文本又常带隐藏空白。建议先规范化再去重,顺手把无效项一起带出来复核,而不是直接丢掉。需要更专门的拆分动作时,可以用 语义化版本号去重器 把清单整理成下游脚本能直接吃的格式。
把结果交接出去
校验完不该停在屏幕上。导出成带行号的 CSV 或 Markdown,失败行和原因一起留痕,这就是一份可交接的审计记录,回头排查时能直接定位到原文哪一行。需要喂给脚本或者数据库时,切成 JSON,SQL IN,TypeScript union 都行,不用手工补引号和逗号。全程解析,校验,去重,导出都在浏览器本地完成,版本字符串不会发到任何服务器,处理内部包名和私有 tag 时这点尤其重要。
语义化版本校验本质上是一件机械活,规则清楚,适合批量交给工具。把它放进发版前检查和 CI 这两个关口,脏版本号就很难再溜到下游。
Made by Toolora · Updated 2026-06-13