ci指的是什么 什么是ci

作者:成龙,腾讯前端开发工程师,负责腾讯文档的前端开发和R&D效率提升,AlloyTeam成员 。
介绍本文将重点介绍DevOps在持续集成阶段需要提供的能力,并对工作流的设计和流水线的优化做简要说明 。
“DevOps”一词来源于开发和运营的结合,即通过工具链连接软件交付过程中开发和测试运维之间的环节,通过自动化测试和监控,减少团队的时间损失,更高效稳定地交付产品 。
随着腾讯文档项目规模越来越大,功能特性和维护人员越来越多,特性交付频率和软件质量之间的矛盾日益尖锐 。如何平衡这两者成为团队目前迫切关注的焦点,因此实现一个完善的DevOps工具链被提上日程 。
当我们谈论CI时,我们在谈论什么?CI(Continuous Integration)即持续集成,是指频繁(一天多次)将代码集成到主干中的行为 。
注意,这既包括将代码持续集成到主干中的含义,也包括将源代码持续生成实际产品的过程 。因此,我们需要通过CI自动保证代码的质量,并将其构建产品转化为下一阶段可用的产品 。
因此,在CI阶段,我们至少要实现以下几个阶段:
1.静态代码检查
其中包括,ESLINT/TSLINT静态语法检查,验证git commit消息是否符合规范,提交的文件是否有对应的所有者需要审核等等 。这些静态检查可以通过直接扫描源代码来完成,无需编译过程 。
2.单元测试/集成测试/E2E测试
自动化是保证产品质量的关键 。测试用例的覆盖率和测试用例的质量直接决定了构建产品的质量 。因此,全面完善的测试用例也是实现持续交付的必备要素 。
3.汇编和整理产品 。
在中小型项目中,通常直接省略这一步,构建产品直接交给部署环节 。但是对于大型项目来说,频繁提交施工会产生大量的施工产品,需要妥善管理 。接下来我们将详细解释产品到产品的建立 。
集成工作流设计在正式接入CI之前,我们需要规划一个新的工作流程,以适应项目切换到高频集成后可能出现的问题和困难 。这里涉及到许多层次的转变 。除了敦促开发人员改变他们的习惯和培训新的过程,我们主要关心的是源存储库的更新触发持续集成步骤的方式 。
1.装配线的组织形式
我们需要一个适当的组织形式来管理CI渠道在什么阶段应该执行什么任务 。
市场上有很多CI工具可供选择 。仔细观察可以发现,无论是像Drone这样新兴的轻量级工具,还是已经成立的Jenkins,都支持这样一个特性:配置即代码,即使用配置文件来管理管道,要么是原生的,要么是通过插件 。
这样做的好处是相当大的 。首先,它不再需要专门用于管道管理的网页,这无疑为平台方降低了维护成本 。其次,对于用户来说,管道配置集成在源代码仓库中,可以享受与源代码的同步升级,这样CI流程也可以得到git的版本管理的规范和审核 。
在建立了管道的组织形式之后,我们还需要考虑版本的发布模式和源库的分支策略,这直接决定了我们应该如何规划代码集成的管道 。
2.发布模式的选择
在《持续交付2.0》一书中提到,发布模式有三个要素:交付时间、特性数量和交付质量 。
这三者相互平衡 。在人力资源和资源相对固定的情况下,只能保证两个 。
传统的基于项目的发布模式牺牲了交付时间,只有在所有功能都已经开发完成并经过充分的人工测试后,才发布新版本 。但这样会使交付周期变长,而且由于功能数量多,开发过程中的不可控风险会更高,可能导致版本不能按时交付 。不符合一个成熟的大型项目连续交付的要求 。
对于持续集成的思想,当我们的集成频率足够高,自动化测试足够成熟稳定的时候,完全没有必要在一个版本中堆叠所有的特性 。每开发一个特性,都会自动测试,然后发布 。接下来,节点只需要自动发布特定时间段内的稳定等待特征 。这对于发布频率更高更短的现代大型项目来说,无疑是一个最优的解决方案 。
3.分支策略
和大多数团队一样,我们最初的开发模式是分支开发,主干发布的思路,分支策略采用了业界最成熟完善的Git-Flow模式 。
可以看出,这种模式在功能开发、bug修复、版本发布甚至热修复中都已经考虑到了,是一种可以在生产环境中应用的工作流 。但是,整体结构变得极其复杂,不便于管理 。比如执行一个hotfix的操作流程是:从最新版本之前使用的主干分支中拉出hotfix分支,修复后放入develop分支,等待下一个版本拉出放入release分支,发布完成后再放回主干 。
此外,对于Git-Flow的每个特性分支,并没有严格的关闭时间,因此对于较大的需求,关闭时间间隔可能会很长,这可能会导致在关闭主干时需要解决大量的冲突,从而导致项目工期的不合理延长 。对此,做过大规模改造重建的同学应该深有体会 。
鉴于此,我们决定大胆采用骨干开发、骨干发布的分支策略 。
我们要求开发团队的成员尽可能每天向主干提交他们的分支代码 。当达到发布条件时,直接从主干中拉出发布分支进行发布 。如果发现缺陷,直接在主干上修复,根据需要樱桃挑到相应版本的发布分支 。
这样开发者只需要两个分支,主干和自己的工作分支,只需要push和merge两个git命令就可以完成所有分支 。同时,由于合并频率的增加,每个人需要解决的冲突数量大大减少,这无疑解决了很多开发者的痛点 。
需要注意的是,分支策略和版本发布模式并没有什么灵丹妙药 。我们采用的策略不一定适合所有团队的项目 。提高集成频率可以让产品尽快快速迭代,但无疑会让人工对新开发的特性进行充分的测试和验证变得困难 。
为了解决这个矛盾,需要强大的基础设施和长期的习惯培养来支撑 。这里,难点分为以下几种 。你可以针对这些难点做一些考虑,来决定是否有必要采用主干开发的方法 。
1)完美和快速的自动化测试 。只有当单元测试、集成测试和E2E测试的覆盖率极高,并且通过变异测试得到的测试用例是高质量的,才能从整体上保证项目质量 。但是,它要求团队中的所有开发人员都要习惯TDD(测试驱动开发),这是一个相当长的培养工程文化的过程 。
2)业主责任制的代码审查机制 。让开发人员有主人翁意识,对自己负责的模块进行逐行审核,可以避免代码修改时设计架构中的很多破坏性修改和坑 。本质难点其实是开发者的习惯培养 。
3)大量的基础设施投资 。高频率的自动化测试实际上是一种消耗资源的操作,尤其是对于E2E测试 。每个测试用例都需要一个无头浏览器的支持 。另外,为了提高测试效率,需要多核机器并行执行 。这里的每一项都是大量的资源投入 。
4)快速稳定的回滚能力和准确的在线及灰度监控等 。只有在高度自动化的全链路监控下,这种机制下发布的新版本才能稳定运行 。我将在下面的文章中详细介绍这里的构造 。
【ci指的是什么 什么是ci】大型项目中产物-

    推荐阅读