项目交付与维护:发布流程、版本号规范、CHANGELOG编写、长期维护策略

说实话,很多团队把项目交付当成终点。代码写完,编译通过,打包发出去,完事。但在我十几年的嵌入式开发生涯里,真正让我头疼的从来不是写代码,而是交付之后的事情。

你想想看,一个产品要活多久?少则两三年,多则七八年。这期间要修bug、加功能、适配新硬件。如果没有一套规范的交付流程,后期维护就是一场噩梦。我见过太多项目,因为版本号乱标、CHANGELOG不写,最后连自己都搞不清哪个版本跑在哪个设备上。

今天我们就来聊聊,怎么把交付这件事做得漂亮、专业。

一、发布流程:从代码到交付的标准化路径

发布流程不是走形式。它是质量保障的最后一道防线。我个人习惯把发布流程分成五个阶段:

  1. 代码冻结:所有新功能开发停止,只修bug
  2. 回归测试:跑一遍完整的测试用例,包括单元测试、集成测试、压力测试
  3. 构建打包:用CI/CD工具自动构建,生成固件、文档、烧录工具
  4. 发布评审:项目经理、测试负责人、架构师三方签字
  5. 正式发布:打tag、上传制品库、通知相关方

我在项目中遇到过最惨的一次,就是跳过了回归测试直接发布。结果固件烧到产线上,发现某个外设驱动在低温环境下会死锁。那批板子已经焊好了两千片,全部返工。从那以后,我再也不敢省这一步。

注意:嵌入式产品的发布流程,一定要包含硬件版本校验。同一个固件可能跑在不同硬件版本上,发布前必须确认兼容性。

版本号规范:语义化版本与嵌入式场景的适配

版本号怎么定?业界最流行的是语义化版本(SemVer):主版本.次版本.修订号。但嵌入式场景有些特殊,我一般会加一个硬件版本字段。

字段 含义 何时递增
主版本 不兼容的API变更 协议变更、硬件平台更换
次版本 向下兼容的功能新增 增加新功能、新命令
修订号 向下兼容的问题修正 bug修复、性能优化
硬件版本 目标硬件平台标识 PCB改版、芯片更换

举个例子:v2.3.1-hw04,表示主版本2,次版本3,修订号1,适配硬件版本04。这样一看就知道这个固件该烧到哪块板子上。

我曾经接手过一个项目,版本号是 v1.2.3_final_final2。嗯,你懂的。后来我强制团队用语义化版本,配合git tag管理,再也没出过版本混乱的问题。

小技巧:在代码里定义一个版本宏,编译时自动从git tag获取版本号。这样固件里自带的版本信息永远不会出错。
// version.h
#define VERSION_MAJOR 2
#define VERSION_MINOR 3
#define VERSION_PATCH 1
#define HW_VERSION "hw04"

#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)

#define VERSION_STRING \
    "v" TOSTRING(VERSION_MAJOR) "." \
    TOSTRING(VERSION_MINOR) "." \
    TOSTRING(VERSION_PATCH) "-" \
    HW_VERSION

CHANGELOG编写:让每一次变更都有迹可循

CHANGELOG不是流水账。它是给谁看的?给测试人员、给运维、给下一个接手的开发者。所以内容要清晰、分类要明确。

我推荐用 Keep a Changelog 的格式,按版本倒序排列,每个版本包含以下分类:

  • Added:新增功能
  • Changed:功能变更
  • Deprecated:即将废弃的功能
  • Removed:已移除的功能
  • Fixed:bug修复
  • Security:安全修复

写CHANGELOG有个原则:对事不对人。不要写「张三修复了串口bug」,要写「修复了串口在115200波特率下数据丢失的问题」。这样即使张三离职了,后人也能看懂。

好的CHANGELOG示例:

## [2.3.1] - 2024-06-15
### Fixed
- 修复了看门狗超时时间配置错误导致系统意外重启的问题
- 修复了SPI通信在高速模式下时钟相位偏移的问题

### Changed
- 优化了Flash写入性能,批量写入速度提升约30%
- 更新了MQTT客户端库版本至v4.2.0

我见过最离谱的CHANGELOG,就一句话:「修复了一些bug」。嗯,这跟没写有什么区别?

长期维护策略:让产品活得更久

嵌入式产品的生命周期往往很长。我手头有个项目,2016年发布,到现在还在维护。怎么做到?靠的是策略。

第一,建立LTS版本分支。 每半年或一年,从主分支拉一个长期支持版本。LTS版本只修bug,不添功能。这样客户可以安心用,不用担心升级带来的兼容性问题。

第二,做好向后兼容。 接口设计时就要考虑扩展。比如协议字段预留保留位,API参数用结构体而不是散列参数。这样后续加功能不会破坏已有代码。

第三,自动化回归测试。 每次提交代码,自动跑一遍所有测试用例。我团队里有个规矩:测试覆盖率低于80%的模块,不允许合入主分支。

第四,文档同步更新。 代码改了,文档必须跟着改。我习惯把API文档和代码放在同一个仓库里,用Doxygen自动生成。这样文档永远不会过时。

血的教训:我曾经维护过一个项目,前任离职时没留下任何文档。我花了整整两个月才搞清楚整个系统的架构。从那以后,我要求每个模块的负责人必须写README,否则代码不予合入。

知识体系总览

下面这张图,把本章的核心逻辑串起来了。从发布流程到版本号,再到CHANGELOG和维护策略,每一步都是环环相扣的。

项目交付与维护知识体系 发布流程 代码冻结 → 回归测试 → 构建打包 → 发布评审 → 正式发布 版本号规范 主版本.次版本.修订号-硬件版本(如 v2.3.1-hw04) CHANGELOG编写 Added / Changed / Deprecated / Removed / Fixed / Security 长期维护策略 LTS分支 | 向后兼容 | 自动化测试 | 文档同步

说白了,交付不是终点,而是维护的起点。你前面做得越规范,后面就越省心。我见过太多项目,前期赶进度,版本号乱标、CHANGELOG不写,结果后期维护成本是开发成本的三倍以上。

所以我的建议是:从项目第一天就把这些规范立起来。哪怕多花两天时间,也值得。

公众号:蓝海资料掘金营,微信deep3321