登录

  • 登录
  • 忘记密码?点击找回

注册

  • 获取手机验证码 60
  • 注册

找回密码

  • 获取手机验证码60
  • 找回
毕业论文网 > 外文翻译 > 计算机类 > 软件工程 > 正文

基于Buildbot、Docker、Gitlab的持续集成(CI)的实现外文翻译资料

 2022-10-26 10:10  

英语原文共 14 页,剩余内容已隐藏,支付完成后下载完整资料


持续集成

马丁·福勒

------作于martinfowler.com 2006年5月1日

我还可以生动记起第一次看到大型软件工程的情景。我当时在一家大型英国电子公司的QA部门实习。我的经理带我熟悉公司环境,我们进到一间巨大的,充满了压抑感和格子间的的仓库。我被告知这个项目已经开发了好几年,现在正在集成阶段,并已经集成了好几个月。我的向导还告诉我没人知道集成要多久才能结束。从此我学到了软件开发的一个惯例:集成是一个很耗时并难以预测的过程。但是事实并非总是如此,我的 ThoughWorks 同事所做的项目,以及很多其它遍布世界各地的软件项目,都不会把集成当回事。任何一个开发者本地的代码和项目共享基准代码的差别仅仅只有几小时的工作而已,而且这只要几分钟的时间就可以被集成回去。任何集成错误都可以很快被发现,并被快速修复。这鲜明的差别并非源于昂贵和复杂的工具。其中的精华蕴含于一个简单的实践:使用统一的代码仓库并频繁集成(通常每天一次)。

当我向别人介绍持续集成方法时,人们通常会有两种反应:“这(在我们这儿)不管用”和“做了也不可能有什么不同”。但如果他们真的试过了,就会发现持续集成其实比听起来要简单,并且能给开发过程带来巨大的改变。因此第三种常见的反应是:“我们就是这么做的,做开发怎可能不用它呢?”

“持续集成”一词来源于极限编程(Extreme Programming),作为它的12个实践之一出现。当我开始在 ThoughWorks 开始顾问职业生涯时,我鼓励我所参与的项目使用这种技巧。Matthew Foemmel 将我抽象的指导思想转化为具体的行动。我们看到了项目从少而繁杂的集成进步到我所描述的不当回事。Metthew和我将我们的经验写进了这篇论文的第一版里。这篇论文后来成了我网站里最受欢迎的文章之一。

尽管持续集成不需要什么特别的工具,我们发现使用一个持续集成服务器软件还是很有效果的。最出名的持续集成服务器软件是 CruiseControl,这是一个开源工具,最早由 ThoughWorks 的几个人开发,现在由社区维护。之后还有许多其他持续集成服务器软件出现,有些是开源的,有些则是商业软件,比如 ThoughtWorks Studio 的 Cruise

用持续集成构建特性

对我来说,解释持续集成最简单的方法就是用一个简单的例子来示范开发一个小 feature。现在假设我要完成一个软件的一部分功能,具体任务是什么并不重要,我们先假设这个 feature 很小,只用几个小时就可以完成。(我们稍后会研究更大的任务的情况。)

一开始,我将已集成的源代码复制一份到本地计算机。这可以通过从源码管理系统的 mainline 上 check out 一份源代码做到。

如果你用过任何源代码管理系统,理解上面的文字应该不成问题。但如果你没用过,可能会有读天书的感觉。所以我们先快速解释一个这些概念。源代码管理系统将项目的所有源代码都保存在一个“仓库(repository)”中。系统的当前状态通常被称为“mainline”。开发者随时都可以把mainline复制一份到他们自己的计算机,这个过程被称为“check out”。开发者计算机上的拷贝被称为“工作拷贝(working copy)”。(绝大部分情况下,你最终都会把工作拷贝的内容提交到mainline上去,所以两者实际上应该差不多。)

现在我拿到了工作拷贝,接下来需要做一些事情来完成任务。这包括修改产品代码和添加修改自动化测试。在持续集成中,软件应该包含完善的可自动运行的测试,我称之为自测试代码。这一般需要用到某一个流行的 XUnit 测试框架。

一旦完成了修改,我就会在自己的计算机上启动一个自动化 build。这会将我的工作拷贝中的源代码编译并链接成为一个可执行文件,并在之上运行自动化测试。只有当所有的 build 和测试都完成并没有任何错误时,这个 build 过程才可以认为是成功的。

当我 build 成功后,我就可以考虑将改动提交到源码仓库。但麻烦的情况在于别人可能已经在我之前修改过 mainline。这时我需要首先把别人的修改更新到我的工作拷贝中,再重新做 build。如果别人的代码和我的有冲突,就会在编译或测试的过程中引起错误。我有责任改正这些问题,并重复这一过程,直到我的工作拷贝能通过 build 并和 mainline 的代码同步。

一旦我本地的代码能通过 build,并和 mainline 同步,我就可以把我的修改提交到源码仓库。

然而,提交完代码不表示就完事大吉了。我们还要做一遍集成 build,这次在集成计算机上并要基于 mainline 的代码。只有这次 build 成功了,我的修改才算告一段落。因为总有可能我忘了什么东西在自己的机器上而没有更新到源码仓库。只有我提交的改动被成功的集成了,我的工作才能结束。这可以由我手工运行,也可以由 Cruise 自动运行。

如果两个开发者的修改存在冲突,这通常会被第二个人提交代码前本地做 build 时发现。即使这时侥幸过关,接下来的集成 build 也会失败掉。不管怎样,错误都会被很快检测出来。此时首要的任务就是改正错误并让 build 恢复正常。在持续集成环境里,你必须尽可能快地修复每一个集成 build。好的团队应该每天都有多个成功的 build。错误的 build 可以出现,但必须尽快得到修复。

这样做的结果是你总能得到一个稳定的软件,它可能有一些 bug,但可以正常工作。每个人都基于相同的稳定代码进行开发,而且不会离得太远,否则就会不得不花很长时间集成回去。Bug被发现得越快,花在改正上的时间就越短。

持续集成实践

从上面的故事我们大概了解了持续集成是如何在我们的日常工作中发挥作用的。但让一切正常运行起来还需要掌握更多的知识。我接下来会集中讲解一下高效持续集成的关键实践。

只维护一个源码仓库

在软件项目里需要很多文件协调一致才能 build 出产品。跟踪所有这些文件是一项困难的工作,尤其是当有很多人一起工作时。所以,一点也不奇怪,软件开发者们这些年一直在研发这方面的工具。这些工具称为源代码管理工具,或配置管理,或版本管理系统,或源码仓库,或各种其它名字。大部分开发项目中它们是不可分割的一部分。但可惜的是,并非所有项目都是如此。虽然很罕见,但我确实参加过一些项目,它们直接把代码存到本地驱动器和共享目录中,乱得一塌糊涂。

所以,作为一个最基本的要求,你必须有一个起码的源代码管理系统。成本不会是问题,因为有很多优秀的开源工具可用。当前较好的开源工具是 Subversion。(更老的同样开源的 CVS 仍被广泛使用,即使是 CVS 也比什么都不用强得多,但 Subversion 更先进也更强大。)有趣的是,我从与开发者们的交谈中了解到,很多商业源代码管理工具其实不比 Subversion 更好。只有一个商业软件是大家一致同意值得花钱的,这就是 Perforce

一旦你有了源代码管理系统,你要确保所有人都知道到哪里去取代码。不应出现这样的问题:“我应该到哪里去找xxx文件?” 所有东西都应该存在源码仓库里。

即便对于用了源码仓库的团队,我还是观察到一个很普遍的错误,就是他们没有把所有东西都放在源码仓库里。一般人们都会把代码放进去,但还有许多其它文件,包括测试脚本,配置文件,数据库Schema,安装脚本,还有第三方的库,所有这些build时需要的文件都应该放在源码仓库里。我知道一些项目甚至把编译器也放到源码仓库里(用来对付早年间那些莫名其妙的C 编译器很有效)。一个基本原则是:你必须能够在一台干净的计算机上重做所有过程,包括checkout和完全build。只有极少量的软件需要被预装在这台干净机器上,通常是那些又大又稳定,安装起来很复杂的软件,比如操作系统,Java开发环境,或数据库系统。

你必须把build需要的所有文件都放进源代码管理系统,此外还要把人们工作需要的其他东西也放进去。IDE配置文件就很适合放进去,因为大家共享同样的IDE配置可以让工作更简单。

版本控制系统的主要功能之一就是创建 branch 以管理开发流。这是个很有用的功能,甚至可以说是一个基础特性,但它却经常被滥用。你最好还是尽量少用 branch。一般有一个mainline就够了,这是一条能反映项目当前开发状况的 branch。大部分情况下,大家都应该从mainline出发开始自己的工作。(合理的创建 branch 的理由主要包括给已发布的产品做维护和临时性的实验。)

一般来说,你要把build依赖的所有文件放进代码管理系统中,但不要放build的结果。有些人习惯把最终产品也都放进代码管理系统中,我认为这是一种坏味道——这意味着可能有一些深层次的问题,很可能是无法可靠地重新build一个产品。

自动化build

通常来说,由源代码转变成一个可运行的系统是一个复杂的过程,牵扯到编译,移动文件,将 schema 装载到数据库,诸如此类。但是,同软件开发中的其它类似任务一样,这也可以被自动化,也必须被自动化。要人工来键入各种奇怪的命令和点击各种对话框纯粹是浪费时间,也容易滋生错误。

在大部分开发平台上都能找到自动化 build 环境的影子。比如 make,这在 Unix 社区已经用了几十年了,Java 社区也开发出了 Ant,.NET 社区以前用 Nant,现在用 MSBuild。不管你在什么平台上,都要确保只用一条命令就可以运行这些脚本,从而 build 并运行系统。

一个常见的错误是没有把所有事都放进自动化 build。比如:Build 也应该包括从源码仓库中取出数据库 schema 并在执行环境中设置的过程。我要重申一下前面说过的原则:任何人都应该能从一个干净的计算机上 check out 源代码,然后敲入一条命令,就可以得到能在这台机器上运行的系统。

Build 脚本有很多不同的选择,依它们所属的平台和社区而定,但也没有什么定势。尽管大部分的 Java 项目都用 Ant,还是有一些项目用 Ruby(Ruby Rake 是一个不错的 build 脚本工具)。我们也曾经用 Ant 自动化早期的 Microsoft COM 项目,事实证明很有价值。

一个大型 build 通常会很耗时,如果只做了很小的修改,你不会想花时间去重复所有的步骤。所以一个好的 build 工具应该会分析哪些步骤可以跳过。一个通用的办法是比较源文件和目标文件的修改时间,并只编译那些较新的源文件。处理依赖关系要麻烦一些:如果一个目标文件修改了,所有依赖它的部分都要重新生成。编译器可能会帮你处理这些事情,也可能不会。

根据你的需要,你可能会想 build 出各种不同的东西。你可以同时 build 系统代码和测试代码,也可以只 build 系统代码。一些组件可以被单独 build。Build 脚本应该允许你在不同的情况中 build 不同的 target。

我们许多人都用 IDE,许多 IDE 都内置包含某种 build 管理功能。然而,相应的配置文件往往是这些 IDE 的专有格式,而且往往不够健壮,它们离了 IDE 就无法工作。如果只是 IDE 用户自己一个人开发的话,这还能够接受。但在团队里,一个工作于服务器上的主 build 环境和从其它脚本里运行的能力更重要。我们认为,在 Java 项目里,开发者可以用自己的 IDE 做 build,但主 build 必须用 Ant 来做,以保证它可以在开发服务器上运行。

让你的build自行测试

传统意义上的 build 指编译,链接,和一些其它能让程序运行起来的步骤。程序可以运行并不意味着它也工作正常。现代静态语言可以在编译时检测出许多 bug,但还是有更多的漏网之鱼。

一种又快又省的查 bug 的方法是在 build 过程中包含自动测试。当然,测试并非完美解决方案,但它确实能抓住很多 bug——多到可以让软件真正可用。极限编程(XP)和测试驱动开发(TDD)的出现很好地普及了自测试代码的概念,现在已经有很多人意识到了这种技巧的价值。

经常读我的著作的读者都知道我是 TDD 和 XP 的坚定追随者。但是我想要强调你不需要这两者中任何一个就能享受自测试代码的好处。两者都要求你先写测试,再写代码以通过测试,在这种工作模式里测试

剩余内容已隐藏,支付完成后下载完整资料


资料编号:[154030],资料为PDF文档或Word文档,PDF文档可免费转换为Word

您需要先支付 30元 才能查看全部内容!立即支付

企业微信

Copyright © 2010-2022 毕业论文网 站点地图