3. 版本标识与语义化版本策略

在 ctrlX AUTOMATION 中,一个可运行的系统并不是单一软件,而是由固件(Firmware)、应用(App)、配置(Configuration)和数据模型(Data Model)四类对象共同构成的组合体。它们各自独立演进,却又必须协同工作。如果版本标识混乱,就会出现“固件升级后应用无法启动”“配置回滚后数据模型不匹配”这类难以定位的问题。因此,本节的核心任务是:为这四类对象建立清晰的命名规则,并设计一套可追溯的语义化版本号与内部构建号映射方案。

四类对象的版本命名规则

ctrlX AUTOMATION 的版本标识需要区分“对外可见版本”和“内部构建版本”。对外版本用于人阅读、依赖声明和兼容性判断;内部构建号用于精确定位某一次编译或打包产物,保证可追溯。

固件版本通常采用 MAJOR.MINOR.PATCH 三段式,例如 2.6.4。MAJOR 变化表示不兼容的接口或运行时变更;MINOR 表示向后兼容的功能新增;PATCH 表示向后兼容的问题修复。固件还应附带一个构建号,如 2.6.4+build.20240517.3,其中 20240517 是日期,3 是当日第几次构建。

应用版本同样使用语义化版本,但需要额外声明其依赖的固件范围。例如某应用版本 1.4.0 声明 firmware: >=2.4.0 <3.0.0,表示它兼容 2.x 系列固件,但不保证在 3.x 上运行。应用构建号建议采用 应用名-版本-提交短哈希,如 myapp-1.4.0-a3f9c21,便于从运行实例反查源码提交。

配置版本与固件、应用不同,它描述的是“参数集合”而非代码。配置版本建议采用 CONFIG-MAJOR.MINOR,并绑定目标固件主版本。例如 cfg-2.3 表示面向固件 2.x 的第 3 次配置修订。配置变更必须记录变更摘要,如“新增 axis2 使能参数”“修改 EtherCAT 周期为 1ms”。

数据模型版本描述的是数据结构、字段类型和语义。它一旦变更,往往影响上层应用读写。数据模型版本建议采用 DM-MAJOR.MINOR.PATCH,其中 MAJOR 变化表示字段删除或类型不兼容,MINOR 表示新增可选字段,PATCH 表示文档或约束修正。

语义化版本与内部构建号的映射方案

仅有语义化版本还不够,因为同一个 2.6.4 可能对应多次内部构建。映射方案的目标是:给定任意一个运行中的对象,都能唯一确定它的源码提交、构建时间和依赖清单。

推荐采用“三段对外版本 + 四段内部构建”的映射结构:

对外版本:  2.6.4
内部构建:  2.6.4.20240517.3.a3f9c21
字段含义:  主.次.修订.日期.当日序号.提交短哈希

对于应用,可在内部构建号前增加应用标识:

myapp-1.4.0.20240520.1.b7e2d10

这样,当现场设备上报版本时,运维人员可以立即判断:这是 1.4.0 应用的第 1 次构建,提交哈希为 b7e2d10,构建日期为 2024-05-20。若需要回滚,也能精确找到对应产物,而不是只回滚到“1.4.0”这个模糊版本。

建议在 CI/CD 流水线中自动生成内部构建号,禁止手工填写。构建号一旦生成,不得修改,只能追加新构建。

版本兼容性矩阵与追溯链

四类对象的版本不是孤立的,它们之间存在依赖和约束。下图展示了固件、应用、配置、数据模型之间的版本追溯关系:应用声明固件范围,配置绑定固件主版本,数据模型被应用引用,而内部构建号则把每一类对象锚定到具体的构建产物。

ctrlX AUTOMATION 四类对象版本追溯关系 固件 Firmware 对外: 2.6.4 内部: 2.6.4.20240517.3.a3f9c21 MAJOR.MINOR.PATCH 应用 App 对外: 1.4.0 内部: myapp-1.4.0.20240520.1.b7e2d10 声明 firmware 依赖范围 配置 Configuration 对外: cfg-2.3 绑定固件主版本 2.x CONFIG-MAJOR.MINOR 数据模型 Data Model 对外: DM-3.2.1 MAJOR 不兼容 / MINOR 新增 DM-MAJOR.MINOR.PATCH 依赖: firmware >=2.4.0 <3.0.0 绑定主版本 引用 DM-3.x 追溯链: 运行实例 → 内部构建号 → 提交哈希 → 依赖清单 → 兼容性矩阵 任一环节可反查,保证版本可追溯、可回滚、可审计

在实际项目中,建议维护一张版本兼容性矩阵表,至少包含以下字段:对象类型、对外版本、内部构建号、依赖对象及范围、发布日期、变更摘要。每次发布新版本时,由流水线自动追加一行,而不是人工维护。这样,当现场设备出现异常时,只需读取其版本信息,就能在矩阵中定位到对应的构建产物和依赖关系。

版本号变更的判断依据

版本号不是随意递增的,每一次变更都需要有明确依据。对于固件和应用,判断规则如下:

  • 删除或重命名对外接口、修改通信协议字段含义、改变运行时行为导致旧应用无法启动 → 递增 MAJOR。
  • 新增接口、新增可选参数、新增功能但不影响旧应用运行 → 递增 MINOR。
  • 修复缺陷、优化性能、更新文档,不改变接口和语义 → 递增 PATCH。

对于配置,只要参数结构或默认值发生不兼容变化,就递增 CONFIG-MAJOR;仅新增可选参数或调整注释,递增 CONFIG-MINOR。对于数据模型,字段删除、类型变更、单位变更属于 MAJOR;新增可选字段属于 MINOR;约束修正属于 PATCH。

不要用“日期版本”替代语义化版本。日期版本无法表达兼容性,也无法让依赖声明自动判断范围。日期只能作为内部构建号的一部分。

落地建议

在 ctrlX AUTOMATION 项目中落地这套方案,可以从三个动作开始。第一,在代码仓库根目录放置版本声明文件,例如 version.json,由 CI 读取并生成内部构建号。第二,在应用打包时写入依赖清单,声明固件范围和数据模型版本。第三,在设备启动日志中输出四类对象的对外版本和内部构建号,便于现场快速采集。

{
  "firmware": "2.6.4",
  "firmwareBuild": "2.6.4.20240517.3.a3f9c21",
  "app": "myapp-1.4.0",
  "appBuild": "myapp-1.4.0.20240520.1.b7e2d10",
  "config": "cfg-2.3",
  "dataModel": "DM-3.2.1",
  "dependencies": {
    "firmware": ">=2.4.0 <3.0.0",
    "dataModel": "DM-3.x"
  }
}

这份清单既是构建产物的一部分,也是现场排障的入口。只要版本标识规则统一、内部构建号可追溯、兼容性矩阵可查询,固件、应用、配置和数据模型的协同演进就不会失控。