2. 版本号规范:语义化版本号(SemVer)在EPS中的应用

版本号这东西,说白了就是软件的身份证。我见过太多团队因为版本号乱打,导致集成时鸡飞狗跳的场景。今天咱们就聊聊语义化版本号(SemVer)在EPS软件里到底该怎么用。

2.1 为什么EPS必须用SemVer?

EPS软件有个特点:它不是一个孤立的程序。它要跟PLC通信、要跟MES对接、还要兼容不同品牌的伺服驱动器。你想想看,如果版本号没有规则,A模块说升级了,B模块说也升级了,结果两个不兼容——这锅谁来背?

我个人习惯,从第一个正式版本开始就严格执行SemVer。别等到项目做大了再回头补,那成本太高了。

核心原则:版本号格式为 X.Y.Z(主版本号.次版本号.补丁号),每个数字都是非负整数,且不能有前导零。

2.2 主版本号:不兼容的变更

什么时候该动主版本号?记住一句话:让老用户无法直接升级的改动

  • API接口不兼容:比如EPS的轴控接口从MoveAbs(pos)改成了MoveToPosition(targetPos),老代码全部报错
  • 数据结构变更:配置文件的JSON结构改了,旧版本解析不了新文件
  • 通信协议重写:Modbus寄存器地址映射全部重新规划
  • 依赖项大版本升级:比如底层实时内核从v2升级到v3,API全变了

我曾经踩过的坑:有一次我们只是改了内部算法,觉得不影响外部接口,就只升了次版本号。结果客户反馈说他们的上位机收不到数据了——原来算法优化后,数据刷新频率变了,对方的超时机制没适配。从那以后,凡是可能影响外部行为的改动,我都建议至少升次版本号。

2.3 次版本号:向下兼容的新功能

次版本号增加,意味着「我加了新东西,但你老代码照样跑」。

  • 新增功能:比如EPS增加了电子凸轮功能,但原有的点位运动完全不受影响
  • 新增API:添加了GetAxisStatus()方法,老方法都还在
  • 新增配置项:配置文件中增加了可选字段,旧配置文件读取时自动补默认值
  • 性能优化:算法效率提升,但对外表现完全一致

这里有个细节要注意:次版本号升级时,不能删除或修改任何已有的公共接口。哪怕你觉得那个接口命名很蠢,也只能标记为@Deprecated,不能直接删。

我的建议:在EPS开发中,次版本号可以适当频繁一些。我一般每完成一个完整的功能特性,就升一次次版本号。这样客户和测试人员都能清楚知道「这个版本多了什么」。

2.4 补丁号:Bug修复与微小调整

补丁号是最简单的——只修bug,不加功能

  • Bug修复:比如某个轴在特定速度下会抖动,修好了
  • 安全补丁:修复了某个缓冲区溢出的漏洞
  • 文档修正:API文档中参数说明写错了,更正一下
  • 内部优化:代码重构但不改变外部行为

嗯,这里要注意:补丁版本不能引入任何新功能。哪怕是一个小小的日志输出格式调整,如果会影响外部解析,都不应该放在补丁里。

2.5 EPS实战中的版本号变更示例

咱们拿一个实际的EPS项目来举例。假设当前版本是 2.3.1

变更内容 新版本号 理由
修复了轴回零时偶尔超时的bug 2.3.2 纯bug修复,补丁号+1
新增了电子齿轮功能 2.4.0 向下兼容的新功能,次版本号+1,补丁号归零
重构了运动规划接口,旧接口全部废弃 3.0.0 不兼容变更,主版本号+1,次版本号和补丁号归零
修复了日志文件路径错误 2.3.3 微小bug,补丁号+1
增加了Modbus TCP支持,旧串口协议不变 2.5.0 新功能且兼容,次版本号+1

2.6 预发布版本与构建元数据

在实际开发中,我们经常需要发布测试版本。SemVer也考虑到了这一点:

  • 预发布版本:在版本号后加连字符,如 2.4.0-alpha.12.4.0-beta.22.4.0-rc.1
  • 构建元数据:在版本号后加加号,如 2.4.0+build.20240315

预发布版本有个重要特性:它的优先级低于正式版本。也就是说,2.4.0-alpha2.4.0 要「老」。这在依赖管理时特别重要——你不会想在生产环境里装个alpha版本吧?

EPS中的实践建议:

  • 内部测试用 -alpha-dev
  • 客户验收用 -beta-rc(Release Candidate)
  • 正式发布去掉所有后缀

2.7 版本号比较规则

你可能会问:版本号怎么比大小?其实很简单:

  1. 先比主版本号,大的优先
  2. 主版本号相同,比次版本号
  3. 主次都相同,比补丁号
  4. 正式版本 > 任何预发布版本
  5. 预发布版本按标识符逐段比较

举个例子:2.4.0 > 2.4.0-rc.1 > 2.4.0-beta.2 > 2.4.0-alpha.1 > 2.3.9

一个小技巧:在EPS的版本管理脚本里,我习惯用Python的 packaging.version 库来做版本比较。它原生支持SemVer,比自己写正则靠谱多了。

2.8 避坑指南

最后,分享几个我在EPS项目中踩过的坑:

  • 不要用日期当版本号20240315 这种版本号没法表达兼容性信息。我见过一个团队用日期,结果两个「20240315」版本之间API全变了,谁也说不清该用哪个。
  • 不要跳版本号:从 1.0.0 直接跳到 2.0.0 没问题,但别从 1.0.0 跳到 3.0.0。中间跳过的版本会让依赖管理混乱。
  • 补丁号不要超过三位数:虽然规范允许,但 1.0.256 这种版本号看起来就很奇怪。我一般补丁号到99就考虑升次版本了。
  • 版本号一旦发布,不可修改:如果发现 2.3.1 有bug,应该发布 2.3.2,而不是重新发布 2.3.1。这是对用户最基本的尊重。

好了,版本号规范就讲到这里。下一章咱们聊聊版本分支策略——怎么在Git里管理这些版本号,让追溯变得轻松愉快。