开始学习持续集成所要了解的知识:分支策略,测试自动化,工具和最佳实践。git
持续集成的目的是将代码传递到存储库的主分支:github
持续集成有点关于工具以及团队中的思惟方式和文化。你但愿在开发的过程当中可以保持主分支的同时快速集成新代码。此工做主分支将在以后启用持续交付或持续部署(的操做)。可是,这些不是本文的内容。让咱们先来关注下持续集成。后端
实现持续集成有两大支柱。缓存
想象一下,一个五人组成的团队致力于一个SaaS产品。每一个人都开发一个单独的新功能。每一个功能的工做量大约是1或2周。有两种方式能够实现这个目标。安全
"功能分支"
上工做。一旦每一个人对本身的工做感到满意,此分支将被被合并到主分支。你认为哪一种方法效果最好?服务器
第一种方法最终将致使**“不可预测的释放综合症”**。长时效的特征分支为每一个开发人员创造了一种虚假的安全感和温馨感。因为分支分离了很长一段时间,没办法衡量将它们合并(到主分支)的难度。其最好的状况是出现些少的代码冲突,在最坏的状况下,基本的设计假设将受到挑战,事情将不得不从新进行...这是艰难的方式。架构
返工的工做将在时间压力下进行,致使质量降低和技术债务积累。这是个恶性循环。并发
请参考关于为什么不该该使用特性分支来处理脏细节的文章。工具
第二种方法是咱们实现持续集成所须要的方法。每一个开发人员都在本身的分支上工做。差别是:布局
每次推送都会将其更改合并到主分支,每一个开发人员天天会将其分支与最新的主分支版本同步几回。
经过这种方式,团队能够更快且轻松地修复冲突并协调设计假想。**早期发现五个小问题比发布日前发现1个大问题更好。**查看下面的“功能切换”
部分,了解如何将“正在进行的工做”集成到主分支。
以前的软件开发工程基于构建周期,而后是测试周期。这可能仍然适用“特征分支”方法(法一)。若是咱们天天数十次集成和合并代码,那么,手动测试就没有意义了。这将花费太长的时间。咱们须要自动检查以验证代码是否正常工做。咱们须要一个CI工具,帮助开发人员自动推送并运行构建和测试。
测试类型和内容应该为:
不幸的是,没有一种方式适合全部测试类型和内容。这要根据你的项目适当平衡。在CI阶段,不要运行大而耗时的测试套件。虽然这些测试提供了更好的安全性,但它们的代价就是对开发人员的延迟反馈。这将致使上下文工做切换,纯粹就是浪费时间。
长时间CI检查,个人意思是超过3分钟的(CI),消耗团队中的每一个开发人员的大量时间。
让咱们来比较下“好”和”坏“的工做流程
。“好”的工做流程:
“坏”的工做流程:
这糟糕的工做流程不只仅是浪费时间。对开发人员来讲也是使人沮丧的。高效的开发会使得开发人员很开心的。
你须要调整工具和工做流程以保证开发人员的满意度。
持续集成是指未来自不一样开发人员分支的代码集成到配置管理系中的公共分支。有可能你正在使用git。在git中,存储库中的默认主分支称为"master"
。一些团队建立了一个名为"develop"
的分支做为(开发时)持续集成的主分支。他们使用"master"
来跟踪交付和部署(develop分支将合并到master分支)。
你(的项目中)可能已经有了一个主分支,你的团队将代码推送或合并到那里。坚持(这样作)下去。
每一个开发人员都应该在本身的分支上工做。若是同时处理许多不一样的功能内容,可使用多个分支。虽然这多是"不专心"
工做的标志。只要代码连贯部分准备就绪,就能够推送到你的存储库。若是成功,CI将检查、启动并将代码合并到主分支。若是检查失败,您仍然在本身的分支上,能够修复须要的任何内容并再次推送。
上述过程当中的关键语是你代码连贯的部分。那么,你怎么知道它是连贯的?简单。
若是你可以轻松地想出一个好的提交信息,那就是连贯的。
另外一方面,若是你提交的信息须要分三次且带有许多形容词或副词,那可能并很差。屡次拆分你的工做内容,连贯的提交,而后推送代码。连贯的提交有助于代码的审查,且能让仓库的历史记录更容易被遵循。
不要乱推送任何东西,由于这(有可能)意味着一天的结束!
pull request (拉取请求)
是什么呢?拉取请求是种概念,其要求团队将你的分支合并到主分支。接受你的请求应该经过你的CI工具提供的状态和潜在代码审查。最终由负责合并拉取请求
的人手动合并。
拉取请求诞生于开源项目中。维护者须要一种结构化的方式来评估合并以前的贡献。拉取请求并非Git
的一部分。他们受到任何Git提供程序的支持(GitHub, BitBucket, GitLab, ...)。
请注意,在持续集成中,拉取请求并非必须的。而拉取请求的主要好处是支持代码审查过程,这过程没法经过设计自动化。
若是你正在使用拉取请求,适用(下面)相同的原则或(上面提到的)“分块工做”和“优化开发者时间”:
持续过程的核心是自动检查。它们确保在合并代码后,主分支代码能正常工做。若是它们失败,则代码不会合并。至少代码应该编译或转换,或者你的技术堆栈应该作点什么以使其为运行时作好准备。
在编译之上,你应该运行自动化测试以确保软件正常工做。测试覆盖率越高,在将新代码合并到主分支时你就越有信心。注意了!更好的覆盖率意味着更多测试和更长的执行时间。你须要找到正确的权衡。
当你彻底没有测试或者须要减小一些长时间运行的测试时,你要从哪里开始呢?专一于你项目或产品的相当重要的事项。
若是你要构建一个SaaS应用,则应该检查用户是否能够注册或登陆,以及执行SaaS提供的最基本操纵。除非你正在开发Salesforce竞争产品,不然你应该可以在几分钟内运行测试,若是不是立刻运行。若是要构建繁重的数据处理后端:使用有限的数据集来运行不一样的构建块。在持续集成中保持大型数据集的长时间运行。合并代码以后,能够触发长时间运行的测试。
持续集成的关键概念是尽快将代码放在主分支中,甚至工做正在进行中。若是功能不彻底正常,或者你不但愿暴露给测试的人员或终端用户。实现这一目标的方法就是功能切换。在启用/禁止
切换下启用新功能。这切换能够是编译时布尔标志,环境变量或运行时事物。正确的方法取决于你想要 实现的目标。
功能切换的第一个主要好处是,你能够根据需求将它们投入生产并启用/禁止
新功能。你可使用更改的环境变量来从新启动服务器,或者切换打开/关闭
一个新的UI仪表盘的布局。经过这种方式,你能够灵活地推出功能。若是在线上中致使意外问题,请将其禁用。或容许终端用户选择加入或退出该功能(使用UI切换)。
功能切换的第二个主要好处是它们会强制你考虑你正在执行的操纵与现有代码之间的界限。这是一个好的练习,如论什么时候,每次添加到现有系统时,都应该从这里开始。功能切换步骤使得该过程的这一步更加明显。
功能切换的惟一缺点是你须要按期从环境和代码中清除它们。一旦功能通过实测并被用户采用,它应该是默认(成功的)。应该清理切换的代码和旧版本的东西(若是有的话)。不要陷入“配置为切换”
系统的陷阱。你没法维护和测试切换的全部组合,(带来的缺点是)你最终拥有一个脆弱的架构。
谨记本文中的“好”和“坏”工做流程
。咱们但愿避免开发人员的上下文切换工做(的状况)。拿起你的手机,并开启3分钟的计时器。看看你等待构建完的时间有多长!3分钟应该是个绝对最大值,你能够集中精力并安全有效地从一个任务移动到另外一个任务。
对一些团队来讲,3分钟内的构建可能看起来很疯狂,但这绝对能够实现的。它和你组织工做的方式有关,而不是你使用的工具。优化构建的方法有:
强制缩短期来限制你的CI检查的好处在于它使你从根本上改善整个开发过程。
正如Jim Rohn所说:
“成为一个百万富翁,不是为了百万美圆,而是为了实现这一目标会让你很成功”
大多数持续集成工具在你的分支上运行CI构建,以确保它是否能够合并。可是这不是咱们感兴趣的内容。若是你知道本身在作什么,那么你推送的代码已经颇有可能生效了。你的CI工具应该验证的是你的分支和主分支合并正常。
你的CI工具应该执行分支到主分支的本地合并,并针对该分支来运行构建和测试。若是主分支在此期间没有变化,则能够自动合并你的分支。若是确实发生了更改,则应该再次运行CI检查,直到你的代码能够安全合并为止。若是你的CI工具不支持此类工做流程,请换一个工具。
有种误解是,可以跟踪Agile板或像JIRA之类的bug跟踪器中相关的代码是件很酷的(事情)。这是一个很好的教科书概念,可是对开发的过程的影响确定不值得付出努力。任务管理器提供了“功能和错误”
的视图。代码以很是不一样的方式构建和分层。尝试协调任务管理器中的项目和一组提交是没有意义的。若是你想知道为何编写一段代码,你应该可以从上下文和注释中获取信息。
工具仅仅是工具而已。设置工具多是(花费)一个小时的事情。若是你错误的使用工具,你将没法获得预期的效果。
谨记咱们为持续集成设定的目标:
真正的意义是将你的思惟方式转变为“不断为你的项目或产品提供价值”
。
将你的软件开发过程视为硬件生产设施。开发人员的代码表明可移动的部件。主要分支就是组装产品。
更快地将不一样部分集成在一块儿并检查其能正常工做,你最终将得到更好的工做产品。
一些实操例子:
“完成比完美更好”
。若是它正常工做,它在主分支中提供的价值比停滞在一旁几天要好。