目前,互联网产品呈现出高频优化迭代的趋势,需求方但愿尽早地看到结果,并给予及时反馈,因此技术团队须要用“小步快跑”的姿式来作产品,尽早地交付新版本。基于以上背景,美团客户端研发平台适时地推行了单周发版的迭代策略。单周版本迭代的优势能够归纳为三个方面:更快地验证产品创意是否符合预期,更灵活地上线节奏,更早地修复线上Bug。安全
首先说一下美团平台的发版策略,主要变动点是由以前的每四周发一版改成每周都有发版。具体对好比下:架构
在以前按月发版的迭代节奏下,基本上全部的需求都属于串行开发,每一个版本的开发流程比较固定。从“评审-开发-提测-灰度-上线”各个环节都处于一个固定的时间点来顺序执行,开发人力资源的协调方式也相对简单。全面推动单周发版以后,并不能把全部需求压缩到5天以内开发完成,而是会存在大量的并行开发的场景,以前的固定时间节点所有被打破,由固定周期变成了动态化调配,这给业务方的需求管理和研发人员人力管理都带来了指数式复杂度的提高。一旦进入并行开发,需求之间会产生冲突和依赖关系,版本代码也会随之产生冲突和依赖,这也大大提升了开发过程当中的分支管理成本,如何规范化管理分支,下降分支冲突,把控代码质量,是本文接下来要讨论的重点。工具
下面描述了几种典型的单周发版带来的问题:开发工具
对于各业务方来讲,需求开发每每并非都能在5天内完成,通常需求在5~10天左右,在以前串行发版模式下这个问题其实也存在,但并不突出,在单周发版的前提下,都要面临跨版本开发,意味着多个版本多个需求会同步并行开发,这给业务方的分支管理带来了极大的挑战。测试
交通业务线涉及火车票、国内机票、国际机票多条业务线,代码仓库除了业务线的独立仓库,还有交通首页,交通公共仓库,RN仓库等多个仓库,Android端6个Git仓库,iOS端5个仓库,RN5个仓库,共计16个Git仓库。优化
多仓库频繁发版分支代码存在安全风险,容易漏合代码,冲掉线上代码。ui
例如交通公共基础仓库,承载了不少交通业务线的UI功能组件,这些公共组件的业务变化频繁,公共基础仓库变化的同时,可能会对使用组件的业务产生影响,须要同步的升级发版。美团平台的策略是公共服务组件每四个小版本统一升级一次,但对业务方自身组件这种策略限制较大,仍是须要公共组件也要具有随时发版的能力。spa
针对上面提出的问题,交通客户端团队经过技术培训、流程优化、关键点检测、自动化处理等方式保证分支代码的安全。技术培训主要是增强技术人员分支管理的基本知识,Git的正确使用方法,这里不作过多描述。本文主要讨论关键点检测,以及如何进行自动化的分支管理。插件
在实施单周发版以前,业务方代码仓库只有两个分支,Develop分支,即开发分支;Stage分支,即发版分支;开发流程基本在串行开发模式,每一个版本10天开发,8天测试,而后进入下一版本的开发。命令行
这种方式只能适用于节奏固定的长周期开发方式,对于多版本并行开发来讲,有点力不从心,显然已经不能承载当前更灵活的发版节奏。
针对这些问题,咱们推出了以下分支管理结构。总的来讲,就是废除以前做为开发分支的Develop分支,创建对应的Release发版分支,每一个版本打包从Release分支直接打包;同时Stage分支再也不承担打包职责,而是做为一个主干分支实时同步全部已发布上线的功能,Stage分支更像一个“母体”,孵化出Release分支和其它Feature分支;当Release分支测试经过、而且发版上线以后,再合入到Stage分支,此时全部正在开发中的其它分支都须要同步Stage分支的最新代码,保证下一个即将发布的版本的功能代码的完整性。
上面的流程描述可能有些复杂,下面是简化的流程图,每一个版本都有本身的生命周期:
为了适应单周发版,新的开发流程也引入了不少新的挑战。例以下图所示的一个Branch分支中涉及的六个关键点:建立分支、合入主干、主干变化通知、Merge主干变化、检测主干同步、未同步拦截,除了这些还要考虑多仓库同步操做的问题,还有热修复版本的管理方式的问题。可否把这些关键节点合理的规范和把控起来,是咱们当前应对多分支并行开发的主要难点:
如何更高效的解决这些问题呢?结合咱们当前使用的工具:Git + Atlassian Stash 代码仓库管理工具;Jenkins Build打包工具;大象(美团内部通信工具)内网通讯工具。目前这三个开发工具已经很是成熟、稳定,而且接口丰富易于扩展,咱们须要配合当前单周发版的分支管理模式,利用这些工具来进行扩展开发,正所谓“要站在巨人的肩膀上”。
建立Release分支,本质上是从Stage新建一个分支,当前提早一个周期建立新的发版分支,例如在10.1.1版本Release后,建立10.1.3版本的分支,此时10.1.2版本处于开发测试阶段。业务方全部的分支命名和平台的分支命名保持一致,采用Release/x.x.x的格式,但同时须要升级成为即将发布的Release版本号,例如10.1.3。
如今交通业务线多达十几个仓库,每一个仓库每周都要操做一次须要耗费大量人力。以前每一个分支的建立都是经过Stash或者手工建立,能不能自动化批处理的建立呢?答案是确定的。对此,咱们采用了Jenkins的方式,须要创建一个Jenkins Job, 基本原理就是经过命令行的方式进行Branch的建立,而后经过Job管理,批处理创建全部仓库的Release分支,这样就收敛了Branch的建立,即采用统一的命名规范,而且同时升级版本号。这就解决了建立分支的难点,实现了自动化建立分支,而且实现了规范化命名。
一个好的开发习惯,就是天天写码以前都同步主分支,可是仍是须要一个机制来确保同步。这里作了三个措施来确保各个分支和Stage是保持同步的:一个通知,一个警告,一次拦截。这三个步骤解决主干变化通知、检测主干同步、未同步拦截的问题。
一个通知:具体路径以下,创建了一个内部推送公众帐号和一个Jenkins监听Job,当全部交通业务仓库Stage分支有代码改动,通知全部对应的开发人员,该仓库有代码变化,请及时合入。
一次警告:本地开发过程当中,每次提交代码到远端仓库时,会触发一个Stage分支代码同步检测的脚本,若是发现未同步,会经过内部通信系统通知提交者存在未同步主分支问题。但这里目前并不作强制拦截,保证分支代码开发的总体流畅性。
最终拦截:在开发分支打包的过程当中强制拦截,最终功能代码上线仍是须要打包操做。在打包操做时统一收口,因为以前打包也是在Jenkins上来完成的,这里咱们也是经过在打包Jenkins上接入了分支合并检测的插件,这样每次打包时会再次检测和主分支的同步状况。若是发现未同步则打包失败,确保每次发版都包含当前线上已有代码的功能,防止新版本丢失功能。
和上面提到的第一个如何建立分支的问题相似,经过Jenkins Job来进行批量操做,能够一键建立全部分支的Pull Request;在每一个版本发版以前,统一进行一次打包,合入美团的主分支,防止多个仓库有漏合的状况。
公共基础和业务分支保持一样的策略,经过批处理脚本同时创建分支,合并分支,监听分支变化,须要注意的是,每次版本升级,公共基础库也须要同步的打包,而且强制业务库升级。否则,若是基础仓库存在接口变更,有的业务升级了,有的业务没升级,最终会致使没法合入主分支,进而没法打出App包。
热修复确实是一种很是规的处理方式。从原则上来说,热修复须要在对应的Release分支上进行修改,而后把修改合入Stage分支,同时须要同步到其它正在开发的分支。实际的处理须要根据具体状况来分析,是否须要对线上多个版本热修复。若是多版本都要修复就不能再合入Stage分支,不然会致使Stage分支冲突,若是把Stage分支合入须要热修复的其它分支,会把线上当前最新代码带入历史旧版本,会致使版本兼容性问题。最终执行起来可能仍是对热修复版本进行单独处理,不必定要进行Stage主分支的同步,热修复的版本管理成本会比较高,更多的须要人工介入。
目前总体的分支发版流程已经基本完成,如今已经稳定运行了10个小版本,同时没有出现由于分支管理问题而引起的线上问题。
不过,当前总体流程的自动化程度还有待提升,每周须要人工去触发,不少代码合并过程当中的冲突问题还须要人工去解决。将来咱们但愿可以自动化地根据平台的版本号自动建立分支,而且对于一些简单的冲突问题拥有自动化的处理能力。随着单周发版的不断成熟,将来对于持续交付能力也将不断提高,发版节奏能够不限于单周,一周两版或是更快的发版节奏也成为一种新的可能。