持续集成系统_ci持续集成系统环境--gitlab gerrit jenkins完整对接 - CSDN
精华内容
参与话题
  • 持续集成(Continuous Integration)

    千次阅读 2015-02-07 23:22:56
    持续集成   作者:Martin Fowler 译者:滕云 原文发布时间:2006年5月1日 翻译时间:2012年2月25日 原文链接:http://www.martinfowler.com/articles/continuousIntegration.html (此翻译已获原...

    持续集成

     

    作者:Martin Fowler     译者:滕云

    原文发布时间:2006年5月1日     翻译时间:2012年2月25日

    原文链接:http://www.martinfowler.com/articles/continuousIntegration.html

    (此翻译已获原作者同意,事实上你不必这么做的,但请参考此FAQ中相关条款)

     

      持续集成是一种软件开发实践,在实践中项目成员频繁地进行集成,通常每个成员每天都会做集成工作,如此,每天整个项目将会有多次集成。每次集成后都会通过自动化构建(包括测试)来尽快发现其中的错误。许多团队都发现这种方法大大地减少了集成问题并且能够快速地开发出高内聚性的软件。本文简要地总结了持续集成技术及其现状。

      我还清楚地记得我刚加入一个大型软件项目时的情形,那时我正在英国一个电子公司做暑期实习。我的经理(属于QA部门)领我参观了一个巨大并很压抑的房间,里面全是格子间。经理告诉我这个项目已经开发了有些年头,现在正在做集成,并且已经集成了好几个月了。经理还告诉我说,没有人真正知道完成集成工作需要多少时间。由此我学到了软件项目的一个通病:软件集成是一个漫长并且无法预测的过程。

      然而,软件集成不必像这样的。在ThoughtWorks的大多数项目还有世界上许多其它组织的软件项目中,软件集成并不是什么难事。每个开发人员离共享的工程状态只有咫尺之遥,并且可以在几分钟之内将自己的代码集成进去。任何集成错误都能被快速地发现并得到快速的修正。

      这种鲜明的对比并不是源自于后者有多么昂贵或复杂的工具,而关键在于每人都频繁集成这种简单实践,通常是每天向一个被管控的代码库集成。

      当我向人们阐述这种实践时,通常得到两种反应:“(在我们这里)行不通”和“无关紧要”。当人们尝试了这种实践之后,他们发现其实做起来比说起来简单,而且这样的实践对于开发“至关重要”。因此有了第三种反应:“是的,我们就是这么做的,不然该怎么活啊?”

      “持续集成”源自于极限编程(XP),并且是XP最初的12种实践之一。当我以咨询师的角色加入ThoughtWorks时,我鼓励我的团队使用这种技术。Matthew Foemmel将我的建议变成了实实在在的行动,由此软件集成从少有发生并且复杂的状态变成了一桩易事。Matthew和我将我们的经验写在了本文的第一版中,而本文也是我的个人网站上最受欢迎的文章之一。

      虽然持续集成并不需要使用特别的工具来部署,但是我们发现拥有一台持续集成服务器将大有益处,其中最著名的有开源的CruiseControl,该软件最初由ThoughtWorks的几个员工开发,现在由一个很大的社区维护着。后来几款其它的持续集成服务器也相继出现了,有开源的,也有商业化的,包括ThoughtWorks Studios的Cruise。

     


     

      在开发中使用持续集成

      对于我来说,解释持续集成及其工作原理最简单的方法便是以一个小的软件功能的开发为例来进行演示。假设我们需要向软件添加一点功能,至于是什么样的功能并不重要,我们假定它很小并且可以在几个小时内完成。

    首先我们需要在本地机器上保留一份当前已经处于集成状态的代码的拷贝。我通过代码管理系统在代码库的主线(mainline)上拉下(check out)一份工作代码拷贝。

      上一段文字主要针对使用代码控制系统的人,对于不使用代码控制系统的人来说便是胡言乱语了。因此,我将向后者解释一下。代码控制系统用于将项目所有的代码保存在一个代码库(repository)中,项目当前的状态通常被称为主线。任何时候开发人员都可以从主线上获得一份拷贝到本地机器,这被称为“checking out”。本地机器上的代码拷贝称为“working copy”。(多数时候,实际上你是在更新(update)本地代码到主线状态,实践中它们是一样的效果。)

      现在,为了完成软件的功能添加,我对本地代码进行修改,其中既包括修改产品代码,也包括添加自动化测试。持续集成非常看重测试,并且在软件代码本身中达到了测试自动化——我将其称为自测试代码,通常使用流行的XUnit测试框架的一个版本。

      当我完成了功能开发(或者在我开发过程的不同阶段),我将在本地开发机上完成自动化构建。构建过程将编译并链接本地代码,然后跑自动化测试。只有当构建和测试都没有错误时,该次构建才能算是好的构建。

      有了本地的成功构建,我便可以考虑将我修改的代码提交到代码库了。但是,在我提交之前,其他开发人员可能已经向主线提交了他们的修改,所以首先我需要将他们的修改更新到我本地并且重新构建。如果他人的修改与我的修改有冲突,那么在本地编译或者测试阶段将会发生错误,这种情况下,我需要负责修改本地代码直到与主线代码保持适当同步为止。

      当本地代码与主线代码同步之后,我便可以向主线提交自己的修改了,代码库也得以更新。

      然而,单是提交了修改并不表示我的工作就完成了。我需要再次构建,但这次是在一台拥有主线代码的集成机器上进行。只有这次构建成功了才表示我的任务完成。通常会出现这样的情况:我忘了提交本地机器上的一些东西,因此代码库并没有得到适当的更新。只有我提交的修改在集成机器上成功构建之后,我的工作才算完成。这样的集成构建可以由我手动完成,也可以由Cruise自动完成。

      当两个开发者的代码有冲突时,通常会在第二个开发者更新本地代码时捕获到,否则,集成构建应该会失败。在这两种途径中,错误都可以被快速地发现。在持续集成环境中,你决不应该使失败的集成构建保留太长时间。一个好的团队每天都应该有许多成功的构建。当然,失败的构建也会时常发生,但需要尽快的修复。

      这样做的结果是,我们总会得到一个稳定并且工作正常的软件。每个人都围绕着一个共享并稳定的基础代码库工作,绝不离基础代码库太远以至于需要很长的时间将自己的修改集成到基础代码库中。如此这般,我们花在找bug上的时间减少了,因为bug在频繁的集成中经常出现。

      


     

      持续集成实践

      上文只是关于持续集成的一个概要和它在日常开发中的工作原理。让所有这些都能很好的运作显然不止于此。现在,就让我们来看看有效持续集成所需的关键实践。 

     

      维护一个单一的代码库

      软件项目需要大量的文件协同工作来构建出最终的产品。跟踪所有的文件需要大量的工作,尤其是在多个开发者参与的项目中。因此,我们可以并不惊奇的看到,不同的软件开发团队都在开发用于管理这些文件的工具——源代码管理工具,也叫配置管理,版本控制系统,代码库等。这些工具是多数软件项目不可分的组成部分。然而,令人伤心并吃惊的是,并不是所有的项目都使用了这样的工具。我的确见到(虽然很少)不使用这些工具的项目,它们使用本地和共享磁盘这种混乱的结合来共同工作。

      因此,做为最基本的持续集成实践,请保证你使用一款体面的代码管理系统。成本不是问题,有许多高质量的开源代码管理工具存在。当前的选择为Subversion(译者注:现在有了更新的hg和git)。(更老的开源工具CVS如今仍然被大量使用,虽然比没有强,但是Subversion是更现代的选择。)有趣的是,当我和一些开发者聊天时,我发现相比起多数商业化的代码管理系统,他们更喜欢Subversion。据我所知,唯一值得花钱买的只有Perforce

      当你有了代码管理系统之后,确保每个开发者都能方便的获得到源代码。不应该有人还在问:“foo-whiffle 文件在哪儿?”所有东西都必须在代码库里。

      虽然许多团队都在使用代码库,但是我经常发现,他们并不把所有东西都放在里面。如果大家需要使用一个文件,他们知道该文件放到代码库中,但是,构建所需的所有都应该包含在代码库里,包括测试脚本,属性文件,数据库模式文件,安装脚本和第三方库等。我所知道的有项目将编译器加到代码库中的(对于早期脆弱的C++编译器来说非常重要)。基本原则是:在一台新机器上check out代码后构建也能构建成功。新机器上的东西应该尽量的少,通常包括很大的,难于安装的,并且稳定的软件,比如操作系统,Java开发环境或者数据库管理系统等。

      你需要将构建所需的所有东西都加到代码管理系统中,同时也需要将大家经常操作的东西方进去,IDE配置便是一个很好的例子,这样便于大家共享IDE配置。

      版本控制系统的一大功能是它允许你创建多个分支,以此来处理不同的“开发流”。这种功能很有用,但却经常被过度使用以至给开发者带来了不少麻烦。所以,你需要将分支的使用最小化,特别建议使用主线,即项目中只有单一的开发分支,并且每人在多数时间里都在“离线”工作。

      总之,你应该将构建所需的所有东西都放在代码管理系统中,而不应该将构建的输出放进去。有些朋友确实将构建输出放在代码管理系统中,但我认为这是一个坏味道,可能导致更深的问题——通常是你无法完成重新构建。

     

      使构建自动化

      将源代码变成一个能运行的软件系统通常是一个复杂的过程,包括编译,文件搬移,加载数据库模式等等。但其中大多数任务都是可以自动化的,并且也应该被自动化。让人去输入奇怪的命令或点击对话框是非常耗时的,而且从根本上来说也是个错误的做法。

      构建所需的自动化环境对于软件系统来说是一个通用功能。Unix的Make已经诞生好多年了,Java社区有Ant, .NET社区有Nant,现在又有了MSBuild。当你用这些工具构建和启动系统时,请确保只使用一个命令完成任务。

      一个常见的错误是在自动化构建里并没有完全包括构建所需的东西。构建过程中应该从代码库里取得数据库模式文件并自动执行之。结合我上文所讲的原则来看,任何人都应该能够在一台新机器上拉下代码库中的代码,并只用一个命令将系统运行起来。

      构建脚本是多种多样的,通常特定于某个平台或社区,但情况并不必须如此。我们的多数Java项目都使用Ant,而另外有些用Ruby(Ruby世界的Rake是一个非常不错的构建工具)。我们用Ant完成了早期的一个微软COM工程的构建自动化,并从中大获裨益。

      大型的构建通常需要很长的时间,而在你只做了很小的修改的情况下,你是不想运行所有的构建步骤的。因此,优秀的构建工具能够分析出哪些地方需要做相应的修改,并将这个分析过程本身做为整个构建过程的一部分。通常的做法是检查源代码和目标文件的修改日期,只有当源代码的修改日期晚于其对应的目标文件时才执行编译。依赖关系因此变得微妙起来了:如果一个目标文件发生了修改,那些依赖于它的文件也需要重新构建。有些编译器能够处理这种依赖关系,而有些就不见得。

      根据自己的需要,你可以选择不同的东西进行构建。构建中既可以包括测试,也可以不包括,甚至可以包括不同的测试板块。有些组件可以进行单独构建。构建脚本应该能够允许你针对不同的情形进行不同的构建目标。

      我们大多数都使用IDE,而多数IDE都或多或少地集成了构建管理功能。但是这样构建文件通常是特定于IDE的,而且非常脆弱。此外,它们需要依赖于IDE才能工作。虽然对于开发者个人来说,在IDE中做这样的构建配置并无不妥,但对于持续集成服务器来说,一份能够被其它脚本调用的主构建脚本却是至关重要的。比如一个Java项目,各个开发者可以在自己的IDE中进行构建,但应该还有一个Ant主构建脚本来保证构建能在集成服务器上顺利完成。

     

      使构建自测试

      传统意义上的构建包括只编译,链接等过程。此时程序也许能运行起来,但这并不意味着系统就能正确地运行。虽然现在的静态语言已经能够捕捉到许多bug,但是漏网之鱼却更多。

      一种快速并高效发现bug的方法是将自动化测试包含到构建过程中。当然,测试也不见得完美,但的确能发现很多bug——足够多了。特别是随着极限编程(XP)的升温,测试驱动开发(TDD)也使自测试代码流行起来,越来越多的人开始注意到这种技术的价值所在。

      经常读我著作的读者可能知道我是一个TDD和XP的大粉丝,然而我想强调的是这两种方法和自测试并没有必然联系。TDD和XP都要求先写测试代码,再写功能代码使测试通过。在这种模式下,测试既用于发现bug,又用于完成系统设计。这是非常好的,但对于持续集成来说不必如此,因为此时我们自测试代码的要求并不那么高。(然而TDD是我写自测试代码的首选。)

      对于自测试代码而言,你需要一组自动化测试来检测一大部分代码库中的bug。测试能通过一个简单得命令来运行并且具备自检功能。测试的结果应该能指出哪些测试是失败的。对于自测试的构建来说,测试失败应导致构建失败。

      过去这些年里,TDD使开源的XUnit家族流行起来,成为了理想的测试工具。在ThoughtWorks,XUnit已经是非常有用的测试工具,我也经常建议人们使用。这组工具起初由Kent Beck开发,它们使自测试环境的搭建变得非常简单。

      XUnit当之无愧地是你进行代码自测试的起点。当然,你也应当多看看那些更侧向于端到端测试的工具,包括FITSeleniumSahiWatirFITnesse等等,我就不逐一列举了。

      当然,别指望测试就是万能的。常言道,测试并不代表就没有bug。

     

      每人每天都向主线提交代码

      集成首先在于交流,它使其他成员能够看到你所做的修改。在这种频繁的交流下,大家都能很快地知道开发过程中所做的修改。

      在向主线提交代码之前,开发人员必须保证本地构建成功。这当然也包括使测试全部通过。另外,在提交之前需要更新本地代码以匹配主线代码,然后在本地解决主线代码与本地代码之间的冲突,再在本地进行构建。如果构建成功,便可以向主线提交代码了。

      在这种频繁提交下,开发者可以快速地发现自己代码与他人代码之间的冲突。快速解决问题的关键在于快速地发现问题。几个小时的提交间隔使得代码冲突也可以在几个小时内发现,此时大家的修改都不多,冲突也不大,因此解决冲突也很简单。对于好几周都发现不了的冲突,通常是很难解决的。

      在更新本地代码库时就进行构建,这意味着我们既可以发现文本上的冲突,又可以发现编译冲突。既然构建是自测试的,那么运行时的冲突也可以被检测出来,而这样的冲突往往是一些特别烦人的bug。由于提交间隔只有短短的几个小时,bug便没多少藏身之处了。再者,因为每次提交的修改都不多,你可以使用diff-debugging来帮你找出这些bug。

      我的基本原则是:每个开发者每天都应当向代码库进行提交。在实践中,越是频繁提交,可能导致冲突的地方就越少,因而也越容易发现。

      频繁提交鼓励开发人员以几个小时为单位来分割他们的代码,这样便于跟踪进度。通常,人们一开始认为在短短的几个小时内做不了什么事情,但我们发现找个导师和多实践可以帮助他们学习。

     

      每次提交都应在集成机上进行构建

      有了每日提交,也就又了每日测试,这应该表明主线处于健康状态。但是在实践中,的确有出错的时候,原因之一在于纪律——有人并没有在提交之前进行本地更新和构建。另外,不同开发机之间的环境不同也是一个原因。

      因此,你应该保证在集成机上进行构建,只有当集成机上构建成功后,才表明你的任务完成了。由于提交者需要对自己的提交负责,他就得盯着主线上的构建,如果失败,马上修改。如果下班之前你提交的修改失败了,那么,对不起,请修改好了才回家。

      我见到过两种方式来保证主线构建的成功:一是手动构建,二是使用持续集成服务器。

      手动构建是最简单的,基本上与开发者在本地做的构建差不多——先到集成机上拉下主线的最新代码,然后运行构建命令,在构建过程中你得盯着构建过程,如果构建成功,表明你的任务完成。(另见Jim Shore的描述。)

      持续集成服务器则一直监视着代码库,一旦检测到有提交,便自动拉下代码到本机,然后开始构建,并将结构通知提交者。只有当提交者收到通知后——通常是以电子邮件的方式,才表明自己的任务完成。

      在ThoughtWorks,我们是持续集成服务器的忠实粉丝,我们领导了CruiseControlCruiseControl.NET的初期开发,此两者均是广为使用的CI服务器。从那时起,我们也开发了商业化的Cruise。在几乎每个项目中,我们都使用了CI服务器,并且结果是令人愉悦的。

      不是所有人都倾向于使用CI服务器的,Jim Shore便给出了一个很好的论述,在此论述中,他解释了为什么他更倾向于手动构建。我同意他的看法——CI不过是安装一些软件而已,所有的实践都应当旨在有效地完成持续集成。但同样,许多使用CI服务器的团队的确发现CI服务器是很好的工具。

      有很多团队定期的进行构建,比如每晚构建。这和持续构建并不是一回事,而且对于持续集成来说,也是不够的。持续集成的关键在于尽快地发现问题。而每晚构建意味着整个白天都发现不了bug,如此,需要很长的时间发现并清楚这些bug。

      持续构建的重点在于,如果主线构建失败,你应该马上进行修改。在持续集成中,你一直是在一个稳定的代码库基础上进行开发。主线构建失败并不是一件坏事,但是,如果这样的情况经常发生,那么就意味着开发人员对于本地更新并没在意或者在提交之前并没在本地构建。主线构建一旦失败,必须马上修正。为了避免主线构建失败,也许你可以试试 pending head

     

      快速构建

      持续集成的关键在于快速反馈,需要长时间构建的CI是极其糟糕的。我的多数同事都认为一个小时的构建时间对于CI来说决无道理可言。我也记得曾经有团队梦想着他们的构建能有多么多么的快,但有时我们不得不面对很难快速构建的情况。

      对于多数项目来说,将构建时间维持在10钟之内是合理的,这也是XP的方针之一,我们多数项目也达到了这个目标。这种做法是值得的,因为这样省下的时间是为开发者节约的。

      如果你的构建长到了一小时,那么想使其加速便不是那么容易了。对于企业级应用来说,我们发现构建时间的瓶颈通常发生在测试上,特别是那些需要于外部交互的测试——比如数据库。

      可能最好的解决办法是引入阶段性构建(也叫构建管道或者部署管道),因为构建事实上是分阶段性的。代码提交后首先触发的是构建称为提交构建,提交构建应该快速完成,而棘手的是怎么保持速度与查找bug之间的平衡。

      提交构建成功后,其他人便可自信的工作了。但是,你可能还有其它跑得比较慢的测试需要写,这时可以用额外的机器来专门跑这些耗时的测试。

      一个简单的例子是将构建分为两个阶段,第一个阶段完成编译,并且跑那些不需要外部交互的单元测试,数据库交互也通过stub的方式完全消除掉。这些测试可以很快跑完,原则是将其保持在10分钟之内。但是,对于那些需要大量外部交互——特别是涉及到真实数据库交互时才能发现的bug,这个阶段便无能为力了。第二个阶段跑的测试则需要操作真实的数据库了,同时还应包括端到端测试。这个阶段可能需要几个小时。

      在这种情况下,通常将第一阶段视为提交构建,并将此做为主要的CI周期。第二阶段则可在有必要时才进行,如果这个阶段构建失败,它也不需要像第一阶段那样“停下全部手头的工作”,但也应该得到尽快的修改。第二阶段的构建不见得需要保持一直通过,对于已经发现的bug来说,可以在之后几天修改。对于这个案例来说,第二阶段全是测试,因为通常情况下最慢的即是测试。

      如果第二阶段构建发现了bug,通常意味着应该在第一阶段中引入新的测试来予以保证。

      当然,以上的两阶段构建只是一个例子,你完全可以加入多个构建阶段。提交构建之后的其它构建是可以并行完成的,如果这些阶段的构建需要好几个小时,那么可以用几台机器来并行完成。通过这种并行化,你可以将提交构建之外的所有测试都引入到构建过程中来,比如性能测试。

     

      在与生产环境的拷贝环境中运行测试

      测试旨在发现可能在生产环境中出现的问题,因此如果你的测试环境与生产环境不同,那么测试很有可能发现不了生产环境中的bug。

      因此,你的测试环境应该尽量与生成环境相同。使用相同的数据库,相同的操作系统,并且版本都应该一样。另外,将生产环境中的库文件也放到测试环境中,即使构建时用不到这些库。IP地址和端口号也应当相同,当然还包括硬件。

      但事实上这是有限制的。如果你开发的是桌面软件,很难预测你的客户在使用哪些第三方库。再者,生产环境可能非常昂贵。即便存在这么多限制,你依然应当尽量去复制生产环境,并熟知因测试环境和生产环境的不同而可能导致的风险。

      如果你搭建的环境足够简单并没有多少烦人的外部交互,那么你的提交构建便可在仿真环境中进行。但是,由于系统反应慢等原因,你可能需要test doubles。因此,通常情况是在人工环境下跑提交构建以获取速度,而用一个生产环境的拷贝环境来跑其它测试。

      我注意到,虚拟化技术越来越引起人们的兴趣。由于虚拟机可以保存构建所需的所有东西,故在虚拟机中运行构建和测试相对比较容易。另外,虚拟机技术也允许你在一台机器上运行多个测试,或者可以模拟多台机器同时访问网络的情况。随着虚拟机性能逐渐提升,它将引起更多的注意。

     

      使任何人都能轻易获得可执行文件

      软件开发最困能的事情之一便是你不能保证所开发的是正确的软件。我们发现人们往往很难预知自己究竟想要什么,而相反,对已有的东西进行评判和修改却容易的多。敏捷开发过程则恰恰是符合人类这种行为习惯的。

      为此,项目中的所有成员都应能够获得最新的可执行文件并能成功的运行,目的可以包括做演示,浏览测试或者仅仅看看项目本周有何修改。

      这是很容易达到的:确保一个通用的地方来存放最新可执行文件。在同一个地方存放多个可执行文件也是很有用的。对于最新的可执行文件,应当保证能够通过提交测试。

      如果你的开发过程有一个很好的迭代计划,将每次迭代最后一次构建生成的可执行文件存放起来也是明智的做法。

     

      人人都能看到正在发生什么

      持续集成主要在于交流,因此应当保证每人都能轻易看到当前系统的状态和已做的修改。

      主线的构建状态是非常重要的,Cruise服务器包含一个网站,你可以在该网站上看到当前的构建状态和最后一次主线构建的结果,许多团队喜欢用比较显眼的标识来反应构建状态,比如在屏幕上放一盏灯,灯绿表示构建成功,灯红表示失败。尤其常见的是lava lamps——不仅表明构建状态,还可显示构建时间。如果红灯中有了气泡,则表明构建已经失败了很长一段时间了。每个团队都有自己的选择,当然,适合自己的才是最好的。

      对于手工完成的持续集成过程,这种可见性也是很重要的,构建机器的显示器应该能显示主线构建的状态。通常,正在做集成的人会放一个token在桌上来表明他正在做集成。人们喜欢在构建成功后播放一些简单的声音,比如闹铃之类的。

      当然,CI服务器的网站可以展示更多的信息。Cruise不但能可以显示是谁在构建,并且能显示最新提交的修改。另外,Cruise还可以查看提交历史,这样,团队成员便可以很清楚项目的进展情况。据我所知,有些团队的头便是通过这种方式来了解项目成员的工作情况和整个系统的修改情况。

      使用CI网站的另一个好处是,哪怕不在一起工作的人都可以看到当前项目的状态。再者,你也可以将不同项目的构建信息放到一起。

      并不是只有CI网站才能展示显示构建信息。由于构建的不稳定性是一直存在的,这时我们可以将全年的日历画在一张墙上,每天对应一个方块,如果构建成功,QA则在该天的方块贴上绿色标签,否则贴上红色标签。时间一久,这份日历便可显示出项目的稳定性进展情况。

     

      自动化部署

      做持续集成需要多种环境,不同的构建阶段需要不同的环境。每天,项目的可执行文件都会在这些环境之间搬来移去,于是你希望将这些过程自动化。因此,自动化部署脚本便很重要了,不仅包括测试环境的脚本,也包括针对生产环境的部署脚本。虽然我们不是每天都向生产环境部署,但自动化部署不仅可以加速部署过程,并且能够减少部署错误。

      如果你已经有了生产环境的自动化部署,那么也应该考虑一下相应的自动化回滚。由于失败是时而会发生的事情,在这种情况下,我们希望能快速回滚到失败之前的状态。这样一来,我们在部署是也不用那么畏首畏尾了,于是我们可以频繁的发布软件,用户亦能尽快的享受到新的功能。(Ruby on Rails社区有一款名为Capistrano的工具即是一个典型的例子。)

      在集群环境中,我看到有每次只向一个节点部署的情况,由此在几个小时之内逐渐完成所有节点的部署。

      对于一些面向大众的web应用,我所了解的另外一种很有趣的部署方式是,先试验性针对一部分用户进行部署,再通过这些用户的试用情况来决定是否向所有用户部署。自动化部署,做为CI的一项原则,能够很好的胜任这些工作。

      



      持续集成的好处

      总的来说,我认为持续集成的最大好处在于降低风险。我又想起了我在本文一开始提到的那个项目——已经处于项目的末期,但是仍然不知到何时才能结束。

      延期集成的缺点在于,很难预测集成到底要花多少时间,更糟的是,你很难了解集成的进展情况。

      持续集成正好解决了这些问题。每次集成的时间都不长,任何时候你都知道自己所处的情况,软件的哪些地方在工作,哪些没有。

      Bug——恶心的玩意儿,伤害我们的自信,搅乱我们的日程,还破坏我们的名声。如果在生产环境中遇到了bug,那么用户将会把气往你身上撒。而在开发环境中,bug拦着你的路,迫使你无法完成余下的工作。

      持续集成并不能消除bug,却能帮你快速的发现bug并予以清除。这种情况下,持续集成更像是自测试的代码。当遇到bug时,由于你只做了很小的修改,这样便大大缩小的bug的查找范围。另外,由于是你刚写的代码,你还记得很清楚,因此也使查找bug更加容易。你还可以使用diff debugging,将当前的代码版本和先前没有bug的版本进行比较。

      Bug也存在积累性,bug越多,越难清除。部分原因在于bug之间存在牵连。另外也存在心理因素,bug一多,人便没那么多精力去修了——这就是所谓的“Broken Windows 综合征”。

      因此,对于采用持续集成的团队,bug将大大减少,不管是在生产环境,还是在开发环境。但是,我想强调的是,你的获益程度取决于测试的好坏程度。你或许已发现,写出好多测试并不难。然而,要达到低bug率的程度依然是需要时间的,你还得不断地引入并改进自己的测试。

      有了持续集成,频繁部署也不是什么难事了。频繁部署的价值在于,你的客户可以快速的享用软件的新功能,并能快速的提出反馈。这将有利于清除客户和开发之间的障碍——我认为这是软件开发最大的障碍。

       


     

      引入持续集成

      然后你开始试着玩持续集成了,但该从何入手呢?上文中我所罗列持续集成实践可以给你带来太多的好处,但是你并不必在一开始就完全采用这些实践的。

    做持续集成没有套路,主要取决于你团队自身的情况,但是我们发现以下几点对于持续集成来说是比较通用的。

      (1)第一步需要将构建自动化,并将你所需的所有东西都放在代码管理系统中,以至于可以通过一个命令来构建整个系统。对很多项目来说,这并非易事。一开始,你可以按照需要进行构建,或者可以只做自动化的夜晚构建。虽然,这些做法都不能称为持续集成,但夜晚构建确是一个好的起点。

      (2)在构建中引入一些自动化测试,试着确定出现问题的主要范围,并用自动化测试去发现这些问题。对于已有的项目来说,很难建立起一组好的快速测试,这时你就得另寻它路了。

      (3)使提交构建快速完成。虽然好几个小时的持续集成比没有要好,但是如果你能将构建时间缩短到几十分钟,或者就短短的10分钟,这就再好不过了。

      (4)对于新项目,从项目开始就采用持续集成。注意构建时间,如果构建时间违背了“10分钟原则”,那么请尽快采取行动。

      (5)寻找帮助,找有经验的人帮助你。和其它的新技术一样,当不知到结果会是什么样时,很难开头。找一个导师可能要花钱,但是不找的话,你所付出的代价是时间的浪费和低下的生产力。(ThoughtWorks提供这样的咨询服务,毕竟你可能遇到的问题我们之前都遇到过。)

     

      



      总结

      自Matt和我发布了本文的第一版之后,持续集成逐渐变成了软件开发的主流技术,在ThoughtWorks,几乎所有的项目都使用到持续集成,同时我们也看到世界上其他组织也在使用持续集成技术。相比起充满争议的极限编程来说,持续集成很少得到负面的评论。

      如果你还没有采用持续集成,我强烈建议你试一试。如果你已经采用了持续集成,本文可能会帮助你进一步提高效率。这些年来,我们已经学到了许多关于持续集成的知识,我们也希望有更多可以学习和改进的地方。

    原文链接:点击打开链接

    展开全文
  • CI

    2017-07-26 09:37:29
    持续集成概述 什么是持续集成 随着软件开发复杂度的不断提高,团队开发成员间如何更好地协同工作以确保软件开发的质量已经慢慢成为开发过程中不可回避的问题。尤其是近些年来,敏捷(Agile) 在软件工程领域...

    持续集成概述

    什么是持续集成

    随着软件开发复杂度的不断提高,团队开发成员间如何更好地协同工作以确保软件开发的质量已经慢慢成为开发过程中不可回避的问题。尤其是近些年来,敏捷(Agile) 在软件工程领域越来越红火,如何能再不断变化的需求中快速适应和保证软件的质量也显得尤其的重要。

    持续集成正是针对这一类问题的一种软件开发实践。它倡导团队开发成员必须经常集成他们的工作,甚至每天都可能发生多次集成。而每次的集成都是通过自动化的构建来验证,包括自动编译、发布和测试,从而尽快地发现集成错误,让团队能够更快的开发内聚的软件。

    持续集成的核心价值在于:

    1. 持续集成中的任何一个环节都是自动完成的,无需太多的人工干预,有利于减少重复过程以节省时间、费用和工作量;
    2. 持续集成保障了每个时间点上团队成员提交的代码是能成功集成的。换言之,任何时间点都能第一时间发现软件的集成问题,使任意时间发布可部署的软件成为了可能;
    3. 持续集成还能利于软件本身的发展趋势,这点在需求不明确或是频繁性变更的情景中尤其重要,持续集成的质量能帮助团队进行有效决策,同时建立团队对开发产品的信心。

    持续集成的原则

    业界普遍认同的持续集成的原则包括:

    1)需要版本控制软件保障团队成员提交的代码不会导致集成失败。常用的版本控制软件有 IBM Rational ClearCase、CVS、Subversion 等;

    2)开发人员必须及时向版本控制库中提交代码,也必须经常性地从版本控制库中更新代码到本地;

    3)需要有专门的集成服务器来执行集成构建。根据项目的具体实际,集成构建可以被软件的修改来直接触发,也可以定时启动,如每半个小时构建一次;

    4)必须保证构建的成功。如果构建失败,修复构建过程中的错误是优先级最高的工作。一旦修复,需要手动启动一次构建。

    持续集成系统的组成

    由此可见,一个完整的构建系统必须包括:

    1. 一个自动构建过程,包括自动编译、分发、部署和测试等。
    2. 一个代码存储库,即需要版本控制软件来保障代码的可维护性,同时作为构建过程的素材库。
    3. 一个持续集成服务器。本文中介绍的 Jenkins 就是一个配置简单和使用方便的持续集成服务器。

    Jenkins 简介

    Jenkins 是一个开源项目,提供了一种易于使用的持续集成系统,使开发者从繁杂的集成中解脱出来,专注于更为重要的业务逻辑实现上。同时 Jenkins 能实施监控集成中存在的错误,提供详细的日志文件和提醒功能,还能用图表的形式形象地展示项目构建的趋势和稳定性。下面将介绍 Jenkins 的基本功能。

    Jenkins 的安装非常简单,只需要从 Jenkins 的主页上下载最新的 jenkins.war 文件然后运行 java -jar jenkins.war。同时,还可以点击 Jenkins 页面上的 launch 按钮完成下载和运行 Jenkins

    展开全文
  • ick 是一个持续集成(CI)系统。访问 http://ick.liw.fi/ 获取更多信息。-- Lars Wirzeniusick 是一个持续集成(CI)系统。访问...
        
    640?wx_fmt=jpegick 是一个持续集成(CI)系统。访问 http://ick.liw.fi/ 获取更多信息。-- Lars Wirzenius

    ick 是一个持续集成(CI)系统。访问 http://ick.liw.fi/ 获取更多信息。

    更加详细的内容如下:

    首个公开版本发行

    这个世界可能并不需要又一个持续集成系统(CI),但是我需要。我对我尝试过或者看过的持续集成系统感到不满意。更重要的是,有几样我感兴趣的东西比我所听说过的持续集成系统要强大得多。因此我开始编写我自己的 CI 系统。

    我的新个人业余项目叫做 ick。它是一个 CI 系统,这意味着它可以运行自动化的步骤来构建、测试软件。它的主页是 http://ick.liw.fi/下载[2]页面有指向源代码、.deb 包和用来安装的 Ansible 脚本的链接。

    我现已发布了首个公开版本,绰号 ALPHA-1,版本号 0.23。(LCTT 译注:截止至本译文发布,已经更新到 ALPHA-6)它现在是 alpha 品质,这意味着它并没拥有期望的全部特性,如果任何一个它已有的特性工作的话,那真是运气好。

    诚邀贡献

    ick 目前是我的个人项目。我希望能让它不仅限于此,同时我也诚邀更多贡献。访问治理[3]页面查看章程,入门[4]页面查看如何开始贡献的的小建议,联系[5]页面查看如何联络。

    架构

    ick 拥有一个由几个通过 HTTPS 协议通信使用 RESTful API 和 JSON 处理结构化数据的部分组成的架构。访问架构[6]页面了解细节。

    宣告

    持续集成(CI)是用于软件开发的强大工具。它不应枯燥、易溃或恼人。它构建起来应简单快速,除非正在测试、构建的代码中有问题,不然它应在后台安静地工作。

    一个持续集成系统应该简单、易用、清楚、干净、可扩展、快速、综合、透明、可靠,并推动你的生产力。构建它不应花大力气、不应需要专门为 CI 而造的硬件、不应需要频繁留意以使其保持工作、开发者永远不必思考为什么某样东西不工作。

    一个持续集成系统应该足够灵活以适应你的构建、测试需求。只要 CPU 架构和操作系统版本没问题,它应该支持各种操作者。

    同时像所有软件一样,CI 应该彻彻底底的免费,你的 CI 应由你做主。

    (目前的 ick 仅稍具雏形,但是它会尝试着有朝一日变得完美 —— 在最理想的情况下。)

    未来的梦想

    长远来看,我希望 ick 拥有像下面所描述的特性。落实全部特性可能需要一些时间。

    ◈ 各种事件都可以触发构建。时间是一个明显的事件,因为项目的源代码仓库改变了。更强大的是任何依赖的改变,不管依赖是来自于 ick 构建的另一个项目,或者是包(比如说来自 Debian):ick 应当跟踪所有安装进一个项目构建环境中的包,如果任何一个包的版本改变,都应再次触发项目构建和测试。◈ ick 应该支持构建于(或针对)任何合理的目标平台,包括任何 Linux 发行版,任何自由的操作系统,以及任何一息尚存的不自由的操作系统。◈ ick 应该自己管理构建环境,并且能够执行与构建主机或网络隔离的构建。这部分工作:可以要求 ick 构建容器并在容器中运行构建。容器使用 systemd-nspawn 实现。 然而,这可以改进。(如果您认为 Docker 是唯一的出路,请为此提供支持。)◈ ick 应当不需要安装任何专门的代理,就能支持各种它能够通过 ssh 或者串口或者其它这种中性的交流管道控制的操作者worker。ick 不应默认它可以有比如说一个完整的 Java Runtime,如此一来,操作者就可以是一个微控制器了。◈ ick 应当能轻松掌控一大批项目。我觉得不管一个新的 Debian 源包何时上传,ick 都应该要能够跟得上在 Debian 中构建所有东西的进度。(明显这可行与否取决于是否有足够的资源确实用在构建上,但是 ick 自己不应有瓶颈。)◈ 如果有需要的话 ick 应当有选择性地补给操作者。如果所有特定种类的操作者处于忙碌中,且 ick 被设置成允许使用更多资源的话,它就应该这么做。这看起来用虚拟机、容器、云提供商等做可能会简单一些。◈ ick 应当灵活提醒感兴趣的团体,特别是关于其失败的方面。它应允许感兴趣的团体通过 IRC、Matrix、Mastodon、Twitter、email、SMS 甚至电话和语音合成来接受通知。例如“您好,感兴趣的团体。现在是四点钟您想被通知 hello 包什么时候为 RISC-V 构建好。”

    请提供反馈

    如果你尝试过 ick 或者甚至你仅仅是读到这,请在上面分享你的想法。在联系[5]页面查看如何发送反馈。相比私下反馈我更偏爱公开反馈。但如果你偏爱私下反馈,那也行。


    via: https://blog.liw.fi/posts/2018/01/22/ick_a_continuous_integration_system/

    作者:Lars Wirzenius[8] 译者:tomjlw 校对:wxy

    本文由 LCTT 原创编译,Linux中国 荣誉推出

    640?wx_fmt=png
    展开全文
  • 持续集成(CI)系统

    2020-03-31 14:55:31
    持续集成(CI)系统 gitlab、gerrit、jenkins三大系统整体框架 开发本地从gerrit下载代码进行开发后将代码git push review到Gerrit系统上, Jenkins 在监听 Gerrit 上的项目事件会触发构建任务来测试代码,...

                                持续集成(CI)系统

     

    gitlab、gerrit、jenkins三大系统整体框架

    开发本地从gerrit下载代码进行开发后将代码git push review到Gerrit系统上, Jenkins 在监听 Gerrit 上的项目事件会触发构建任务来测试代码,Jenkins把测试结果通过 ssh gerrit 给这个项目打上 Verified (信息校验)成功或失败标记,成功邮件通知审核人员 Review(代码审核),审核人通过查看提交的文件进行人工检查代码,判断合格后合并提交,本次提交merge后会自动同步到gitlab备份。

    一,gitlab

    主要用途:代码备份、在线浏览。在本集成系统中gitlab不提供修改和人为提交功能。

    GitLab 是一个用于仓库管理系统的开源项目,使用Git作为代码管理工具,并在此基础上搭建起来的web服务。安装方法是参考GitLab在GitHub上的Wiki页面。

    界面如图下:

     

    二、gerrit

    Gerrit,一种免费、开放源代码的代码审查软件,使用网页界面。利用网页浏览器,同一个团队的软件程序员,可以相互审阅彼此修改后的程序代码,决定是否能够提交,退回或者继续修改。

     

    主要用途:代码审核

    开发需要做的是:
    (1)向管理员申请账号,拿着账号根据《gerrit注册用户及使用指导》(这里不提下载请度娘一下)对接gerrit系统,连接成功并修改用户名后通知管理员(由管理员注册邮箱并使用邮箱添加权限)
    (2)下载代码-本地开发-代码提交审核
    常用命令:
    git clone gerrit仓库地址 分支名(无分支名则默认master)
    ./gerrit_env_branch 自己的名字 评审人的名字 git仓名 分支名

    gerrit_env_branch脚本如下:

    #!/bin/bash
    
    BRANCH=master
    
    if [ ! -n "$1" ];
    then
    	echo "[error]: please input your name"
    	exit;
    elif [ ! -n "$2" ];
    then
    	echo "[error]: please input reveiwer name"
    	exit;
    elif [ ! -n "$3" ];
    then 
    	echo "[error]: please input your project name"
    	exit;
    elif [ -n "$4" ];
    then 
    	echo "[Notice] Use branch $4"
    	BRANCH=$4
    fi
    
    echo welcome $1,now begin config......
    
    #config git user name and email
    git config --global user.name "$1"
    git config --global user.email $1@yourmail.cn
    
    #download commit-msg for change-Id
    echo "Download the commit-msg file from gerrit server..."
    scp -P 29418 -p $1@192.168.10.53:hooks/commit-msg .git/hooks/
    chmod 777 .git/hooks/commit-msg
    echo "Dowmload completed."
    
    #check the git config file 
    if grep -q review .git/config;
    then
    	echo "recovery git config file......"
    	cp .git/.config-bak .git/config
    else
    	cp .git/config .git/.config-bak
    
    fi
    
    #modify the git config file,add reviewer
    echo "[remote \"review\"]
    	url = ssh://$1@192.168.10.53:29418/$3
    	push = HEAD:refs/for/$BRANCH%r=$2@yourmail.cn,cc=yourmail@roadrover.cn" >> .git/config
    echo Config Success Done!
    


    git add 修改的文件名
    git commit
    git push review
    (3)登录gerrit页面跟踪审核状态,如果是jenkins门禁失败,分析失败原因(可能是漏提交文件、依赖还未合并、分支切换未通知管理员同步切换等),如果不是代码本身问题告知管理员解决。
    附:审核失败不可再通过Abandon Change按钮撤销,需要git rebase -i + git commit —amend + 重新提交审核,具体操作留给邱工作说明~

    下图为某次提交的审核状态

     

     

    三、jenkins

    Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能。Jenkins是一个开源的、可扩展的持续集成、交付、部署(软件/代码的编译、打包、部署)的基于web界面的平台。允许持续集成和持续交付项目,无论用的是什么平台,可以处理任何类型的构建或持续集成。

    1,下载:https://jenkins.io/zh/

    2,主要用途:分布式运行多任务、持续的软件版本发布/测试项目、监控外部调用执行的工作。

    =================================================================

    需要开发做的工作:

    1. 代码提交地址变更:gitlab —->>> gerrit
      前期代码提交地址是gitlab(因为项目前期,管理员这边还未参与,gitlab上的仓库都是由应用/系统负责人创建,开发往gitlab提交代码),当管理员介入时,需要负责人提供该项目的仓库地址并给管理员开通master权限,管理员迁移仓库到gerrit后会将gitlab仓库其他成员的权限修改为Reporter(只允许下载)
      特别注意:
      一旦仓库切到gerrit之后,开发须使用gerrit下载代码提交并走审核,不可再直接往gitlab提交,如需要创建分支也找管理员创建。

    2. 门禁配置
      jenkins的门禁工程由管理员创建,门禁工程所做的事是:
      第一、编译
      第二、静态代码检查
      后面会加git commit规范检查和上机做monkey测试。
      需要应用开发做的是:
      (1)提供管理员依赖仓的地址+分支名
      (2)在app/build.gradle增加findbugs任务

    task findbugs(type: FindBugs) {//
     ignoreFailures = true
     effort = "default"
     reportLevel = "medium"
     //过滤器
     excludeFilter = new File("${project.rootDir}/findbug_filter.xml")
     //这里填写项目classes目录
     classes = files("ivi-radio/build/intermediates/classes")
     source = fileTree('src/main/java')
     classpath = files()
     reports {
         //只能开启一个
         xml.enabled = true
         html.enabled = false
     }

    3.  jenkins版本工程配置
    工程配置由管理员完成,需要系统开发做的是:
    (1)提供代码目录架构,并指明仓库地址
    (2)提供编译命令
    jenkins日常使用:
    1.构建版本
    构建触发方式: (构建结果可配置邮件通知)
    第一种:手动触发,由管理员或者开发自己构建(需要自行注册jenkins账号,然后由管理员添加build权限)
    第二种:定时触发,根据项目需要通知管理员配置构建时间
    2.升级包下载
    3.修改记录查看
    4.构建log查看
     

    展开全文
  • 集成系统:输入指定的软件资产,输出根据软件资产生产出的软件产品以及其他副产品的系统。 对于一般系统而言(以VC开发为例),软件的生产过程包括:源码获取,源码检查,源码编译,测试,部署。经...
  • 检查centos7 系统自带JDK 是否安装 jenkins 是不支持在centos 系统自带的JDK 环境中工作的 [root@HAmaster soft]# yum list installed | grep java 如果系统自带了JDK 如何卸载 卸载JDK相关文件: yum ...
  • 持续集成篇_01_持续集成介绍及组成

    万次阅读 2016-04-23 09:02:14
    持续集成介绍及组成
  • 其中现在流行的一种做法是持续集成(CI,Continuous Integration)。 持续集成最初由Grady Booch在布区方法中提出,之后成为了极限编程(extreme programming)的一部分,目的是防止集成问题堆积成为“集成地狱...
  • 持续集成、持续交付、持续部署(CI/CD)简介 概述: 软件开发周期中需要一些可以帮助开发者提升速度的自动化工具。其中工具最重要的目的是促进软件项目的持续集成与交付。通过CI/CD工具,开发团队可以保持...
  • 如何使用jenkins进行持续集成测试

    万次阅读 2019-02-27 16:13:20
    上篇,将Jenkins的持续集成测试环境搭建成功了,接下来,开始我们的创建任务和运行构建。 (一)创建任务 1.创建任务 点击首页“创建一个新任务”的链接,如下: 2.选择 Jenkins 任务类型 Jenkins 提供了四...
  • 使用Jenkins和Kubernetes搭建一个可伸缩的持续集成系统教程:Jenkins和它的插件体系、使用Docker启动Jenkins服务、Jenkins Pipelin 2.0和持续集成、基于Dockerd持续交付、基于Kubernetes的可伸缩持续集成。...
  • 构建基于Jenkins + Github的持续集成环境

    万次阅读 多人点赞 2012-09-15 14:02:00
    搭建持续集成首先要了解什么是持续集成,带着明确的目标去搭建持续集成环境才能让我们少走很多弯路。持续集成(Continuous integration)简称CI,是一种软件开发的实践,可以让团队在持续集成的基础上收到反馈并加以...
  • 今年7月份中下旬,笔者见过一个号称“资深开发者”的哥们(据说编程有十来年了),笔者问他:“你们平时用的持续集成工具都有哪些?”这哥们回答:“那些都是骗客户的,其实我们什么都不用,还是各干各的,然后让一...
  • 那什么是持续集成?Jenkins具体用来做什么,对软件开发有什么益处呢? 总得来说,这两者主要是涉及一个软件质量的主题,特别是团队开发软件项目。下面就来介绍介绍下这两者。 持续集成 持续集成,Continuous ...
  • 持续集成、持续交付、持续部署

    万次阅读 多人点赞 2018-11-27 12:56:23
    持续集成、持续交付、持续部署持续集成持续集成的优势持续交付持续部署DevOps总结参考资料 又到了例行的技术报告环节。想着在实验室里头絮絮叨叨的讲一些前端开发相关的内容,师兄师姐们不爱听,老大也会摆出经典的...
  • 经常会听到持续集成,持续交付,持续部署,三者究竟是什么,有何联系和区别呢? 假如把开发工作流程分为以下几个阶段: 编码 -> 构建 -> 集成 -> 测试 -> 交付 -> 部署 正如你在上图中看到,「...
  • 12.1 持续集成的作用、过程和优势  简单的说,持续集成就是快速且高频率地自动构件项目的所有源码,并为项目成员提供丰富的反馈信息。 --快速:集成的速度要尽可能的快,开发人员不希望自己的代码提交半天后才得到...
  • 搭建敏捷高效的持续集成管理平台 1、持续集成介绍  持续集成是一种软件开发实践  团队开发成员经常集成他们的工作,每次集成都通过自动化的构建  (包括自动化编译、测试、发布)来验证,从而尽快地发现集成错误...
  • jenkins+python自动化测试持续集成

    万次阅读 2018-09-01 16:26:51
    一、首先我们安装Jenkins,我这里采用的是.msi应用程序,根据提示进行安装(傻瓜式),最后会打开默认的网页地址:http://localhost:8080 如果端口有冲突,可以去Jenkins的安装目录下的这个文件去改端口: ...
  • 高可用/并发架构带来部署和运维挑战 更多的服务器,更复杂的软件架构,更多的工作节点…… 更多的发布,部署,测试和运维挑战。 问题:高可用和架构安全的关系 持续发布/部署需求 持续部署和持续发布[CI...是在持续集成
1 2 3 4 5 ... 20
收藏数 150,945
精华内容 60,378
关键字:

持续集成系统