文?/?李宇?李方
最早提出ABS的目的是为了把QA(Quality?Assurance,品质保证)和PE(Project?Engineering,项目工程)从编译任务中解放出来,从而避免重复劳动,提高工作效率。在我们实施ABS之前,从开发到测试,再从测试到发布,都是通过Tag来传递代码的(参见图1)。
其中,QA取A?tag下的代码编译部署,用于测试;PE取R?Tag下的代码编译并发布。
问题及解决方案
在正式实施ABS的过程中,最关键的是我们必须找出其对开发有利的地方,让研发团队主动地配合我们实施过程改进。因此,在推广ABS的时候,我们针对研发团队当前出现的三个问题,提出了对应的解决方案。
{dy}是编译环境不一致的问题。引入ABS之前的局面是:开发、测试和PE各自都有一个编译环境。因此常常会出现这样的问题:开发编译通过了,到测试那却无法通过。同时,由于编译环境不一致也会导致一些发布问题。而每次查找这些问题的原因,都会占用开发不少的时间。
第二是公共包的管理问题。一个团队的代码在提测和发布前需要对调用的一些公共组件进行编译,这些公共组件称之为公共包。随着系统和团队的发展,其中的调用关系会越来越复杂。例如,算法团队一的A组件,在编译时要调用算法团队二的B组件,以及SDS(SQL?Data?Service,结构化查询语言数据服务)团队的C组件。而引擎、前端、平台等另外7个团队在编译时要调用算法团队一的A组件。由于各业务线的不一致,引擎团队一需要调用A组件的3.1版本,而引擎团队二需要调用A组件的4.0版本。在这种环境下,经常会出现被调用的一方升级了自己的组件,而没有通知到所有调用方,这便产生了的公共包版本不一致的问题。
第三是代码和生产环境安全性的问题。公司在这方面应该算是早有准备,因为企业每年都会接收来自四大会计师事务所的一些审计问题。公司保证安全性的措施之一是生产与发布的分离。换言之,就是开发业务系统的人不能接触线上生产系统,负责线上系统的人不能动开发的代码,否则线上业务系统的安全性就会大大降低。
针对以上三个问题,对应的解决方案可以归纳为以下两点:
1.?统一编译环境,由配管为每个团队维护{wy}xx的编译环境。这就xx了开发、测试和PE各自一个编译环境的局面,避免了因编译环境不一致而导致的发布问题。另外,由配管牵头建立公共包的管理规范,谁调用谁负责。确保每个团队的编译服务器上配置的都是{zx1}的适合这个团队的公共包。
2.?ABS实施后收回QA和PE在SVN上的权限。这会提高产品代码安全性,QA和PE只要去Yum服务器上取包即可(参见图2)。
在正式的实施过程中,我们采用了Hudson这个工具来集成SVN和Yum。Hudson本身是用于持续集成的,它具有灵活的扩展性和各种可配置插件。我们可以利用它来完成80%的工作,另外20%需要与团队自身流程相配合,因此仍需要二次开发。
ABS一期
在ABS一期,我们实现了开发阶段持续集成。测试发布阶段是自动打包传递的一个过程,把DEV、SCM、OPS、QA和PE的工作区域和职责区分开来。
DEV是SVN的Owner,只要通过平台将代码提交编译即可;SCM是Hudson的Owner,需要为各团队维护{wy}的Hudson编译环境;OPS是Yum服务器的Owner,需要为QA和PE划分好区域,并授予权限;QA和PE是没有SVN或Hudson权限的,只要到约定地点获取发布包执行测试或分发即可。
我们在具体实施的时候把编译分为三大类。
1.?Check-In?Building:在代码提交至配置库时自动进行编译,从而拦截编译类型的Bug。
2.?Schedule?Building:定时运行的编译,根据实际情况定制。如我们经常提及的Daily?Building,项目进行每日构建(构建的时间可以根据实际情况决定),各研发人员需要在此前将每天的代码提交到SVN,由自动编译平台进行编译。
3.?Manual?Building:人工触发,通常为开发人员提交测试时的编译,或者测试通过后提交PE的编译。可以根据不同的产品发布要求和过程,将Manual?Building分为下列3种情况。
Module?Building:编译的范围是其中一个Module,从功能的角度上颗粒度到模块,产出物可以是dll、lib、.a等文件,也可以是exe文件。Module?Building完成后不需要有安装包。其对应的发布是Module?Release,发布时不需要有全量编译,在Test的基础上打Release即可。
System?Building:编译需要对整个系统进行全量编译,产出物是exe或tar文件。与System?Release相对应,发布时在Test?Building基础上进行操作,为全量发布。
Test?Building:开发自测通过需要提交给内容QA的编译称作Test?Building。现场紧急?Bug修改或者已发布版本临时修改需要回溯到此编译所对应的分支上进行。Test?Building不重新获取代码,只在Module?Building或System?Building的代码和产出物上进行处理,只有当上面的编译通过时才可以继续执行Test?Building。
ABS二期
ABS第二期,我们开始与其他团队的自动化工具进行打通,旨在整合一个大的自动化工具平台。我们把已经细化出来的ABS总体目标拆分成如图3所示的8个部分。
- 持续集成;
- 自动编译打包、完成代码流转;
- 编译前自动进行代码合并;
- 自动部署;
- 与开发阶段的单元测试集成;
- 与自动化测试集成;
- 与淘宝Java团队的配置管理平台集成。
我们在ABS实施过程中根据各团队自身的情况,定制了不同的流程和解决方案。大体上把团队分为三类:前端团队、后端团队和底层团队。前端团队主要以Java为主,如网站前端和业务系统;后端团队主要以C、C++、PHP为主,如投放引擎和算法;底层团队以C为主,主要工作为存储、通信等底层平台的研发。下面,我分别讲一下三种团队的研发模式,以及各自所采取的策略。
前端团队
前端团队的特点是要和业务紧密配合,包括一些紧急的商务合作。他们{zd0}挑战就是要保证Trunk的稳定性,并且使之处于随时可发布状态。
为此,前端团队封锁了Trunk的权限,Trunk只用于上线时合并代码,即只有上线才用,不允许开发。另外需要建立两个分支:开发分支用于开发,合并分支用于发布前的回归测试。基本流程如下(参见图4):①分支开发→②分支测试→③稳定后合并分支→④分支回归测试→⑤合并到主干→⑥主干R?tag上线。
此外,由于Trunk封闭,所以当发布上线时出现紧急Bug,就直接在Tag上进行修改:①Tag上紧急Bug?x→?②Tag测试→③Tag上线→④反向合并到主干。
前端团队这种管理模式的好处是满足了业务需求,可以随时上线。不足之处是分支相对较多,代码合并工作量大,而且由于日常需求也至少经过4轮测试(开发分支测试、合并分支回归测试、预发布后冒烟测试、发布后线上验证测试),测试成本较高。
前端团队发布频繁,几乎每天都有编译发布,因此DailyBuild其实是没有太大意义的。相反,由于分支太多,代码合并会占据很多工作量,所以前端团队实施ABS的重点是:自动合并和自动编译不改。
后端团队
后端团队相对于前端团队来说,发布没有那么频繁,既有5人/日的日常需求,也有50人/日的项目需求。分支相对较少,但分支上的改动较大。
为了{zd0}限度地节省测试资源,减少合并的时间和复杂度。后端团队采取了主干开发和共用分支的原则,并设立了专人(SCM代表)来管理分支的原则:
1.?SCM代表负责开分支。Plan?Meeting(月度产品会详见本刊上期实践栏目)确定下月分支计划及测试提交点。分支应尽量少,不冲突的项目和需求共用分支。
2.?Trunk合并前需邮件向SCM代表申请,并抄送团队。主要原则是为了保证分支上的测试稳定,因为Trunk从上一次合并到打R上线之间是不允许再合并的,所以要尽量保证在主干上从测试到发布的时间不要超过两天。这样才不会出现多个项目分支等待合并的情况。
后端主要流程如下(参见图5):
大项目:①分支开发→②分支测试→③稳定后合并→?④主干回归→⑤主干R?tag上线。
日常需求:①分支开发→②合并主干→?③主干测试→④主干R?tag上线。
紧急Bug?x:①分支Fixbug→②?分支测试→③分支上线→④合并主干。
后端团队的管理方式是效率{zg}、最节省成本的一种做法。但需要团队内部的开发工程师兼职配管的工作,人为地来判断分支的开启和合并。这种情况下ABS既要考虑持续集成,也要重点关注自动编译流转这一块的内容。
底层团队
底层团队的代码是发布频率{zd1}的,很少真正地往生产环境上发布。所以自动编译流转这块的优先级相对没有那么高。但由于大都是大团队的项目研发,几十个开发人员共同修改一套代码。为了检查代码的完整性和一致性,同时将项目的公用组件以产出物的方式进行及时共享,持续集成是一个相对重要的部分。
底层团队对质量的要求相对较高,为了保证代码和产品的质量,写代码的同时,也会配上相应的单元测试和自动化测试脚本。
此外,由于底层团队很少使用分支,因此所有成员共用同一个Trunk,将持续集成和自动化测试结合起来,保证每次提交的Trunk的质量,是底层团队的实施重点。
底层团队一次提交代码的流程如下:
1.?如果是新功能提交,编译后首先要跑通所有的功能测试,然后才能提交成功。
2.?提交成功后即进入每日的Daily?Build。每晚ABS会将整个系统编译一遍,先跑所有的单元测试脚本,接着是优先级P1的冒烟测试,然后是优先级P1的功能测试。跑通之后的Build版本才会向上升级并发出邮件通知。
3.?升级完后会继续把优先级P2到P4的功能测试跑完并发出邮件通知。
总结
任何一个组织的流程经过一段时间,都会逐渐地淡化、变形,对流程的重新明确,是对现状的一种反思和改进。梳理流程的主要目的是将大家当前的做事方式明晰化,使旧的方法能够执行到位,而不是增加新的流程。
总的来说,在流程推进上,要以知识、方法、观念、{zj0}实践的传递为主,而不是以撰写流程和培训为主。作为过程改进人员,我们希望自己扮演的角色是整个团队中的一员,而不是外来的和尚。
作者简介:
李宇,淘宝技术保障部,过程改进部主管。北京开发性技术社区Openparty的组织者之一。曾在软通动力做过SQA,有过2年创业经历。之后一直在雅虎、阿里妈妈、淘宝从事过程改进工作。
李方,淘宝技术保障部过程改进专家。2003年从传统软件业进入互联网,转战深圳、北京、杭州,服务的客户从几个人的小团队到几百人的大部门,实践经验丰富。
(本文来自《程序员》杂志10年02期)