如何不依赖CI构建号生成关联Git的可排序人类友好发布版本号
Git关联可排序易读版本号生成方案
以下方案全部适配单Git仓库托管前后端、手动触发发布、不依赖CI系统内置构建号的场景,生成的版本号满足人类易读、可直接通过字符串比对判断先后顺序的要求,可完全替代原有build-{数字}格式的镜像标签。
方案1:Git原生长描述派生的语义化版本
这是工程界适配性最广的实现方式,完全依托Git原生命令实现,不需要额外维护状态文件。
- 实现逻辑:
- 先给仓库的正式发布节点打固定格式的语义化锚点标签,遵循通用的
v主.次.补丁规则,比如v2.1.0、v2.2.0 - 针对任意待发布的提交,执行
git describe --tags --long命令自动生成版本串:如果当前提交正好在锚点标签上,就直接输出和标签一致的版本号;如果提交在锚点标签之后,就自动拼接{锚点版本}-{距锚点的提交总数}-g{短提交哈希}的格式,可进一步整理为标准语义化结构,比如把距锚点15次提交的版本整理为2.1.1-dev.15
- 先给仓库的正式发布节点打固定格式的语义化锚点标签,遵循通用的
- 排序能力:完全兼容语义化版本的排序规则,逐段比对主版本、次版本、补丁版本、开发迭代计数即可精准判断先后,不存在排序歧义
- 场景适配:哪怕手动选择任意历史提交拉取代码,本地执行一次Git命令就能算出对应版本号,不需要CI系统提前预先生成构建序号,完全支持挑取任意提交手动构建发布的流程。
方案2:基于提交时间的日期结构化版本
适合不想维护大量语义化锚点标签的团队,实现零额外状态维护成本。
- 实现逻辑:
- 读取待发布提交的UTC提交时间,转换为
年.月.日.当日提交序号的结构 - 当日提交序号的计算规则为:统计从提交当日UTC 00:00 到当前提交时间点,仓库内所有提交的总次数,作为版本号最后一段数字
- 示例:2024年6月15日当天的第7次提交,生成的版本号为
2024.06.15.7
- 读取待发布提交的UTC提交时间,转换为
- 排序能力:逐段从左到右比对数字大小即可实现精准排序,先比年份,再比月份、日期,最后比当日提交序号,完全可以直接判断版本先后
- 注意事项:需要通过Git钩子约束仓库内的提交时间,禁止人为修改提交时间戳,避免版本乱序
方案3:基于提交拓扑的全局计数版本
适合分支模型复杂、需要明确版本在分支树中位置的团队。
- 实现逻辑:
- 为仓库的主分支(如
main)维护一份只增不减的全局提交计数映射,每合入一次提交就将计数+1,该映射可通过Git钩子脚本在本地自动维护,不需要CI系统介入 - 生成版本时按照
{主分支累计提交计数}.{待发布提交相对主分支的偏移提交数}的格式组装,比如主分支累计提交数走到1240时,从主分支拉取的特性分支上多了3次提交,对应生成的版本号为1240.3
- 为仓库的主分支(如
- 排序能力:排序逻辑非常直白,先比对主分支累计计数,数值更大的对应版本一定更晚;同一主分支计数下,分支偏移量越大代表距离主分支基线越远,不存在排序歧义。
现有流水线适配提示
- 原有并行执行的Gradle后端构建、Angular前端构建步骤,可将生成的Git关联版本号通过环境变量传递给构建工具,直接把版本号打入后端Jar包、前端静态资源的内置版本信息中,不需要改动原有并行执行的流程
- 手动触发容器化步骤时,只需要把目标提交的版本号作为入参传入,即可自动生成对应的Docker镜像标签,替换原有的Bitbucket构建号逻辑
- 因为版本号完全和Git提交绑定,不同历史提交生成的版本号不会出现重复,可顺畅支持任意挑选历史提交手动构建发布的工作流。
内容的提问来源于stack exchange,提问作者ams
相关产品推荐
相关产品推荐

