背景
项目组基于Cronet自研的产品每次对外发布对应一个版本号,在此之前版本号都是手动由Release Engineer进行填写,并在代码中用到了版本号的地方进行相应修改。
现状
版本号分为4位,前两位对应一次发布,第三位为patch(从1开始),第四位没有作用,默认为1。例如1.5.2.1,即表示我们2016.12月份发布的1.5版本,其中进行了一次patch,因此第三位为2。
版本号由Release Engineer在组内确认完后,由于目前部分模块均在代码中写死了版本号,需要去手动调整后再commit一次,才能发布。
总之,这块存在两个问题。
- 我们对四位版本号的使用不合理,实际上只用到了其中三位。
- 每次发布时,为了版本号需要人工去调整代码,这显然是很难忍受的。
目标
为了提高效率,我们将现状和需求分析了下,分为两个具体要做的事:
- 提供统一的版本号配置管理,只需修改版本号配置,便可应用到整个代码库。
- 尽量将版本号做成自动化无需人工干预的。
解决方案
1.明确四位版本号的每一位用途
可参考chromium对于四位版本号的解释
chromium/version-numbers
概括来说:
四位版本号由 MAJOR.MINOR.BUILD.PATCH组成
MAJOR and Minor: 每次版本发布时update,这个跟我们现在是一样的。
BUILD:在trunk上(应该可以理解为代码库里主干和所有分支)有构建的时候,永久性自增1
PATCH:在构建分支上进行编译,则自增1
参考chromium做法,再结合我们自身需求。我们可以有如下规则:
版本号前两位MAJOR.MINOR对应一次发布,无需变化。
使用第三位作为BUILD,任何一次在agile上触发的编译均会将BUILD永久性+1,初始值为1024(看了一下我们已有的编译已经超过了1000次)。
使用第四位作为PATCH,每个MAJOR.MINOR都有自己的PATCH,初始值为1,任何一次该版本的agile编译,将PATCH+1。
2.版本号统一配置管理,与具体代码解耦
我们参考了chromium原生的版本号宏的生成方案,通过读取一个配置文件中的版本号,在编译时生成一个包含#define CRONET_VERSION 1.6.x.x类似这种宏的头文件,所有需要用到版本号的代码只需获取该宏即可。
具体可参考代码库中:baidu/version.gni
这样做完后,RE无需去手动修改代码,而只要调整配置文件,即可全局生效。
3.自动化版本号
在第一步问题解决后,还是不太能说服大家这个有多好用,我们发现版本号的BUILD & PATCH都跟编译次数相关,如果能将其做成自动化的,就更好了。
这块自动化的做法是:
我们自维护的编译server维护了一块数据存储BUILD号 以及 MAJOR.MINOR对应的PATCH,每次编译开始前,根据存储的数据将代码中的版本号配置文件修改,在编译时就生效了。版本文件在编译成功后会作为编译产物之一返回,方便大家确认版本。
这是编译server与版本号相关代码。
最终效果
会自动生成该头文件,任何需要使用到版本号的代码,仅需要include该头文件即可使用统一版本号。
收益总结
标准化了四位版本号的使用,之前只用到了前三位的,这是不正规的。
如果按照严格标准,可以将我们对代码库的修改文件次数由N*M(N代表一个版本内所有commit数目,M代表使用了版本号的文件数,目前M=3)降低到 1次。
统一后,版本号采用宏来定义,通过编译依赖和头文件获取,看起来比较优雅。