毕业论文
您现在的位置: 版本控制 >> 版本控制资源 >> 正文 >> 正文

持续集成ContinuousIntegr

来源:版本控制 时间:2023/4/25
数字化伍德灯 https://m-mip.39.net/pf/mipso_7004403.html

我还依稀记得我做的第一个大型项目。那是一个英国的大型电汽公司,我暑期在那里实习。当时我有个经理,他是QA组的。他给了atourofasiteandweenteredahugedepressingwarehousestackedfullwithcubes.他告诉我,这个项目已经开发了好几年,现在正在集成阶段。已经集成好几个月了。当时myguide告诉我,大家都不知道还要集成多久才能成功。那个时候起,我就知道了这个道理:集成是个很长且未知性很强的过程。但其实集成并不一定得搞成这样。我在ThoughtWorks的同事,以及世界各地的开发者,他们做过的项目里,集成是个non-event。任何项目成员的工作,都会在几个小时里toasharedprojectstate,并且集成到那个状态里(需要润色)只需要几分钟。集成发生了错误,马上就会被发现,并且他们能够快速地修复。这种区别,并不是借由什么昂贵复杂的工具才能实现的。它的精华就藏在一些非常简单的实践里:团队中的每个人都要频繁地-通常是每天都要-把代码集成到一个中央的源代码仓库中去。当我和人们分享这些实践的时候,通常我会听到两种回答:「(至少在我们这)没用的」,以及「做了也不会有任何改进的」。而当他们真正去做的时候会发现,其实并没有听上去那么难,但它对开发流程改进效果明显。因此,人们的第三种反应是:「我们当然在做——这些都没做你们是怎么开发的?」「持续集成」这个词最初起源于极限编程,它是极限编程最初十二个开发流程的其中一个。我最初以咨询师的身份加入ThoughtWorks时,我鼓励当时所在的团队采用这个实践。是MatthewFoemmel把我模糊的提议细化成了可执行的action。然后我们发现,项目从原来的没有集成、极端复杂的集成,渐渐变成我所说的那种non-event的状态(需要润色)。这篇文章是Matthew和我总结了该项目的经验以后写下来的,事实上它也成了我博客上访问量最大的一篇文章。尽管持续集成这项实践并不需要特别的工具参与也可实施,但我们发现,有一台「持续集成服务器」的话会更有帮助。最有名的持续集成服务器是CruiseControl,它最早是ThoughtWorks几位同事写的一款开源工具,后来交给专门的社区来维护。后面又有一些其他的CI服务器出现,都是开源的商业软件,比如ThoughtWorksStudio开发的

Cruise

等。

buildingafeaturewithcontinuousintegration

要解释CI是什么,它怎么工作,我能想到最简单的方法莫过于以一个小型特性的开发为例子,快速为诸君展示下持续集成的工作流是什么样子。假设我们现在要对一个已有的软件做些更改,更改本身是什么并不重要,因此我们就先假设这是个小型的更改,几小时内即可完成。(后面我们会深入更大型的例子和其他相关问题)我会这样开始我的工作:首先,先把当前已集成的最新代码先签出到我的本地。这可以通过一个源代码管理工具来完成,你从主干代码上签出一份完全一样的代码到你的本地机器上。这对用过源代码管理系统的人来说可能很熟悉,但对于其他人来说可能很不明所以。如果你是后者,那我还是简单地介绍一下。源代码管理系统能替你将所有的源代码保存在一个仓库中。系统的当前状态通常被称为「主干」(mainline)。在任何时间点,开发者都可以将主干代码完整地拷贝到他自己的开发机,这个过程称为「签出」(checkingout)。拷贝到开发机上的这份拷贝通常称为「workingcopy」(一般来说你的改动都在你从主干签出来的workingcopy上-实践中它们通常是一回事)。然后,我可以在我自己的开发机上任意修改。我可能会改动产品代码,也可以会新增或修改原来的自动化测试。「持续集成」假定,ahighdegreeoftestswhichareautomatedintothesoftware:我称这些设施为

自测试的代码

。这些代码一般都使用了流行的XUnit测试框架。特性开发完成后(或在开发过程中的任意时间点),我会在我的部署机器上去触发一个自动化构建。它会拿到我当前的源代码去执行编译、链接,把它变成一个可执行文件,通常它还会执行自动化测试。只有当构建和测试都没有错误抛出,我们才认为整个构建成功了。构建完成后,我才会考虑将代码提交到源代码仓库中。我更改的文件,当然也可能已经同时被其他人所修改,并且提交到了主干上。因此我必须先把他们的最新代码签出来,与我的本地代码合并,并重新执行一次构建。如果签出的代码发生了冲突,它肯定会把编译或者测试给挂掉。这时我则有责任修复构建错误,并重复签出-执行构建这个操作,直到我的本地代码可以和主干代码同时存在为止。把我的workingcopy与主干代码同步完成并成功通过构建后,我终于可以将我的代码提交到主干上。这会更新源代码仓库。不过,提交完成并不是就完事了。此时,在持续集成服务器上,它会拉下新的主干代码,重新执行一次构建。只有当这次构建成功了,才能说我的更改完成了。我完全有可能忘记提交某些文件,导致构建只有在我自己的机器上才能成功。因此,只有集成服务器上的构建成功了,才能认为我的这次更改完成了。这次集成构建可以由我手动触发,也可以由Cruise自动触发。如果两个开发者提交的代码会有冲突,通常是在第二位开发者签出代码以合并workingcopy的时候被发现。否则的话,在他签出代码的时候集成构建肯定就已经挂了。不过无论如何,错误都会很快被揪出来。这个时候,最重要的任务就是修复失败的构建,让构建重新变绿。在一个持续集成的环境中,你永远不能让失败的构建状态持续太久。好的团队一天会有多次成功的构建。失败的构建可以出现,但应该被尽快修复。这样做的结果就是,你有了一个能稳定工作的软件,并且它只有很少的bug。每个人都从这个稳定的代码库上签出代码,开始工作,并且永远不会离这种稳定状态太远,他们随时都可以把代码集成回去。花在找bug上的时间将会大大减少,因为它们会被很快发现。

持续集成实践

上面的故事就是CI的一个概览,也是我们日常工作的缩影。让所有这些能流畅运作起来,显然不仅只有上面提到的这些。下面我会讲讲CI的一些关键实践,它们让CI高效运作。

维护单一的源代码仓库

软件项目的构建需要数以千计的文件。维护这些文件需要巨大的开销,特别是有多人在同一份代码上工作时。因此,这些年来业界有人开发出了一些工具来管理这些代码和文件。这些工具有很多叫法,比如源代码管理工具、配置管理工具、版本控制系统、仓库工具等。它们已成为项目开发中不可或缺的一部分。令人失望和惊讶的是,它们还不是

所有

项目的标配。有些项目就还在用本地的或共享硬盘来管理代码。这很少见,但我确实见过这样的项目。因此,确保你的项目至少有一个源代码管理系统。这是必须的配置。不用担心价格问题,因为有很多开源工具是免费的。当下,

Subversion

就是一个不错的选择,它是开源的。(

CVS

也有很多用户,虽远胜于无,但现在一般都会选择Subversion)。有趣的是,据我了解,大部分商业性的源代码管理工具并不如Subversion受到青睐。我一直听人说,唯一值得付钱的工具只有

Perforce

。有了源代码管理系统之后,确保大家都知道都通过它来获取源代码。不应再听见有人问「那个foo-whiffle文件在哪儿?」仓库里应该都找到一切。另外,尽管很多团队都在用代码仓库,但我还是注意到有个问题:他们没把所有必要的东西放到仓库里。他们会把代码提交到仓库里,但其实所有构建所必须的东西也应该提交到仓库中,包括测试脚本、配置文件、数据库schema、安装脚本、三方库等。就我所知还有团队将编译器也提交到了仓库中(早期C++编译器版本兼容问题多时显得尤为重要)。一般的准则是,你应该能够在一台干净的机器上,签出代码后就可以完整地构建出整个系统。构建机上只需要安装最少量需要的软件-通常是那些很大、安装复杂又稳定的文件,比如操作系统、Java开发环境、或者数据库系统等。构建所需要的所有东西都必须提交到源代码管理系统中。此外,日常工作所需的其他东西也可以提交进去。比如IDE配置就很值得提交进源代码管理系统,因为这样团队可以使用一份同样的IDE配置。版本管理系统的另一特性是,它允许你创建多分支,以应对不同特性的开发。这个特性很有用,但也经常被人们过度使用,进而带来了不少麻烦。建议只保持最小量的分支开发。更具体地讲,有一条单一的开发

主干

就够了,它包含了项目当前的所有代码。大多数情况下,团队成员都应该在这条主干上工作(允许使用分支的情形包括:修生产环境下发现的bug、短期技术探索)。通常,任何类型的构建所需要的所有东西,你都应该提交到源代码管理中。同时,所有的构建物都不应该提交。确实有人会把构建物提交到源代码管理系统中,但我觉得这是个坏味道——它通常暗示着其他深层问题的存在,通常是因为,团队不具备重复执行构建的能力。

将构建自动化

将源代码变成一个可运行的系统,通常涉及一系列复杂的流程,如编译、文件移动、将schema加载到数据库中等。不过,就如其他大部分的任务一样,这个过程也是可以被自动化的——既是可以,也就应该被自动化。依靠人工来键入奇怪的命令、在对话框中点击按钮等,纯属浪费时间,也很容易发生错误。automatedenvironmentsforbuildsarea

转载请注明:http://www.0431gb208.com/sjslczl/4375.html