Someday, all software will be built this way.
原文链接:http://alblue.bandlem.com/2011/02/someday.html
(笔者注:文章主要介绍Git,Gerrit,Jenkins为代表的版本控制,代码审核,持续集成工具在现代软件开发中的使用,笔者认为这些都是当下最时髦,最先进的开发工具和工程思想,特做简单翻译与大家共享。)
先从代码审核说起,代码审核系统总的来说分为两类,各有优缺点:
- 提交前的审核,即把所做的改动附到审核系统。好处是避免了因为不准确或者不存在的版本号码而搞乱版本控制系统;缺点是提交的审核意见可能和提交的代码改动不吻合。
- 提交后的审核,即不管三七二十一先把代码提交到版本控制系统。好处是所有的改动和审核意见都保存到了版本系统中;缺点是错误的改动可能会搞乱版本控制系统。
解决方案是使用branch(笔者暂且称之为分支,以区分称为主干的HEAD)。当改动被保存到分支时,就不会影响到其他在主干上工作的开发人员。审核人员可以独立地在这个分支上进行代码审核,提出建议,修改,完成审核后最终把改动保存到主干。当然,如果需要做两个同时发生的改动,则需要两个分支。
显然,分支就会带来合并。以使用Git为例,开发人员可以在本地的分支上做代码改动,push这个分支到*仓库,请审核人员(一般即同组的其他开发人员)进行代码审核,最后把审核过的改动合并到master(HEAD,trunk,即主干)中。因为Git是分布式版本控制系统,最后的合并将包含所有的历史改动(包含审核人员的意见和签名),这样当有人说“张三批准了01b3cd这个改动”时,开发人员可以准确地看到这个改动具体是什么。
下面来说说Gerrit。
Gerrit是和Git有良好互动的代码审核系统。Gerrit一般处在开发人员的本地Git仓库和Git*仓库之间。简单来说,开发人员将改动push给Gerrit,Gerrit提供一个专业的审核平台,审核人员可以对每个改动过的文件,甚至对每一行改动进行评论。Gerrit同时保存审核投票,包括+1和-1两种,默认情况下,每个改动需要得到+2的投票才算审核合格。
下面说说Jenkins(即以前的Hudson)。
作为一项近年来十分流行的持续集成工具,Jenkins能够从版本控制系统中取出最新的代码,编译,运行测试,并将结果email给相关人员。Jenkins支持随心所欲的触发。开发人员可以设定每天晚上服务器空闲的时候触发Jenkins,或者设定当版本控制系统检测到改动时触发。通常情况下,每次只触发一个分支上(或者主干上)的编译运行。Gerrit有一个触发器可以在每产生一条新的审核意见时触发Jenkins,它甚至能告诉Jenkins取出改动的那个或者那些文件,编译,然后自动运行所有的测试。当Jenkins完成编译运行无误时,Gerrit会自动针对这些改动发表+1(Verified)意见,相反地,如果Jenkins上编译运行有错,则发表-1意见。通过配置,所有这些可以在审核人员还没有开始审核时就全部完成。另外,Git还有一个插件(Git Plugin)可以用来把成功的改动push到远程仓库中,这样所有人都知道这个改动已经在Jenkins上成功通过了编译和测试。
这样,一旦一个改动被push到Gerrit,Jenkins自动进行集成(编译,测试,标记+1),审核人员进行审核,填写评论(可以不填),增加+1标记(可以设置为不需要增加),这个改动就视为一个正确改动了。因为Gerrit参与整个流程(Jenkins成功后会在Gerrit标记+1,失败后会标记-1),因此Gerrit能够代表开发人员将审核合格的改动push到主干(远程服务器,比如Github或者bitbucket)中去。
一旦开发人员开始使用Git,就会充分体会到分布式版本控制系统的好处。一旦开始使用Gerrit,就不存在未经审核的改动。一旦开始使用Jenkins,开发人员就不需要手动运行编译,测试工作。这就是当下最红的软件开发工具和思想。