The following text is a partial translation of the original English article, performed by ChatGPT (gpt-3.5-turbo) and this Jekyll plugin:
持续集成很简单。下载 Jenkins,安装,创建一个任务,点击按钮,然后会收到一封漂亮的邮件,告诉你构建失败了(我假设你的构建是自动化的)。接着,修复失败的测试(我假设你有测试),再收到一封更好看的邮件,告诉你构建成功了。
然后,发推文宣称你的团队正在使用持续集成。
然后,再过几周,开始将Jenkins的警报筛选出来,放入它们自己的文件夹,这样它们就不会再打扰你了。反正,你的团队没有时间也没有愿望每次有人弄坏单元测试时都去修复它们。
毕竟,我们都知道单元测试不适用于有截止日期的团队,对吧?
错误。持续集成可以并且必须运行。
What is Continuous Integration?
现在,软件开发是由团队完成的。我们在功能分支中进行开发,并在开发过程中隔离变更。然后,我们将分支合并到 master
分支中。在每次合并之后,我们会对整个产品进行测试,执行所有可用的单元测试和集成测试。这被称为持续集成(也称为”CI”)。
有时候,一些测试会失败。当这种情况发生时,我们说我们的“构建已损坏”。这种失败是质量控制的一个积极副作用,因为它在错误进入master
后立即引起了警示。
这是一个众所周知的做法,当修复该错误成为作者和整个团队的首要任务时。在持续集成服务器发出红旗后,应立即修复该错误。
《持续交付》(Jez Humble等人著)在第7章的第169至186页完美地解释了这种方法。
市场上有一些很不错的工具,可以自动化DevOps的流程。其中一些是开源的,你可以下载并安装在自己的服务器上。例如:Jenkins,Go,和CruiseControl。其中一些作为云服务提供,比如:Travis,Shippable,Wercker等等。
Why Continuous Integration Doesn’t Work?
CI很棒,但团队越大(以及代码库越大),构建破裂的次数就越频繁。而且,修复它们所需的时间也越长。我见过很多例子,一个努力工作的团队在几周或试图跟上后,开始忽视Jenkins提出的红旗。
团队根本无法及时修复所有错误。主要是因为业务有其他优先事项。产品负责人不理解“干净构建”的重要性,技术负责人也无法为修复单元测试争取时间。此外,导致错误的代码已经在“主分支”中,并且在大多数情况下,已经部署到生产环境并交付给最终用户。如果业务价值已经交付,修复一些测试的紧迫性是什么?
最后,大多数开发团队并不认真对待持续集成的警报。对于他们来说,Jenkins或Travis只是一些花哨的工具,在整个开发和交付过程中起不到什么作用。无论持续集成服务器说什么,我们仍然会向最终用户交付新功能。我们以后会修复我们的构建问题。这是很合乎逻辑的。
What Is a Solution?
四年前,也就是2010年,我在[php | Architect](http://www.phparch.com/magazine/2010-2/august/)杂志上发表了一篇名为《在分布式敏捷PHP项目中预防冲突》的文章。在这篇文章中,提出了一个解决方案(完整文章请见PDF),适用于Subversion和PHP。 |
从那时起,我在多个开源项目和一些商业项目中试验性地使用了这种方法,涉及PHP、Java、Ruby和JavaScript、Git和Subversion。在所有情况下,我的经验都是积极的,这也是为什么rultor.com诞生的原因(稍后再谈)。
所以,解决方案很简单—禁止任何人将任何内容合并到 master
分支,并创建一个任何人都可以调用的脚本。该脚本将进行合并、测试和提交操作。脚本将不会有任何例外。如果任何分支在单元测试中出现问题,整个分支都将被拒绝。
换句话说,在代码进入master
之前,我们应该提出那个红旗。我们应该把测试失败的责任归咎于其作者。
假设我正在自己的分支上开发一个功能。我已经完成了开发,但不小心破坏了一些测试。这种情况时有发生,我们都会犯错。我无法将我的更改合并到“master”分支中。Git只是拒绝我的“push”,因为我没有适当的权限。我所能做的就是调用一个神奇的脚本,让它合并我的分支。该脚本将尝试合并,但在推送到“master”之前,它将运行所有的测试。如果其中任何一个测试失败,我的分支将被拒绝。我的更改将不会被合并。现在这是我的责任—修复它们并再次调用该脚本。
一开始,这种方法会减慢开发速度,因为每个人都需要开始编写更干净的代码。然而,最终这种方法会带来巨大的回报。
Pre-flight Builds
一些CI服务器提供了预先构建的功能,这意味着在分支合并到master
之前对其进行测试。例如,Travis就具备这个功能,非常有帮助。当你对一个分支进行新的提交时,Travis会立即尝试构建,并在GitHub的拉取请求中报告是否存在问题。
请注意,预飞构建不会合并。它们只是检查您的个人分支是否干净。合并后,它很容易破坏master
。当然,这种机制不能保证没有协作者可以直接提交到master
,从而意外破坏它。预飞构建是一种预防措施,但并不完全解决问题。
Rultor.com
为了按照上面所述开始工作,你所需要做的就是撤销对master
分支(或者在Subversion中的/trunk
)的写权限。
很遗憾,在GitHub上这是不可能的。唯一的解决方法是只通过fork和pull request来进行工作。只需将所有人从“协作者”列表中移除,他们将只能通过pull request提交更改。
然后,开始使用Rultor.com,它将帮助您测试、合并和推送每个拉取请求。基本上,Rultor是我们上面所讨论的那个脚本。它作为一个免费的云服务可用。
附注:本文的简短版本也在devops.com上发表。
Are you allowed to PUSH to the master/develop/trunk of your Version Control System (VCS)? #devops
— Yegor Bugayenko (@yegor256) June 23, 2019
Translated by ChatGPT gpt-3.5-turbo/35 on 2023-09-09 at 05:59