白话说 CI/CD

1,240 阅读7分钟

为什么需要 CI/CD

我们先通过两个改编于现实工作的小故事,来体会一下 CI/CD 能够为我们做什么。

故事一

今天 A 君为了和女朋友约会,在下班前完成了登入接口的开发,匆匆忙忙的提交了代码并推送到了远程仓库,然后在群里喊了一句: “帮我 review 下”,就准备收拾小书包离开公司了。

你或许觉得 A 君很奇怪,为什么一个程序员会有女朋友......

抛开女朋友先不管,其实 A 君这种让同事帮忙 review 代码的操作很正常,review 代码也是保证一个项目健壮的重要因素。但 A 君好像只是匆忙完成功能实现,还没来得及自测就推送代码让同事帮忙 review,这是一种不负责的表现。

在这个大家都很忙的时代,让人去介入一些耗费时间精力的事情,其本身就是一件成本很高的事儿。如果 A 君的代码存在着一些非常低级的错误,例如语法错误,传递错误参数等等,此时负责 review 的 B 君可能会掀桌子大骂道:“为什么我没有女朋友!不!为什么他代码这么烂!”。

像这种一般可以通过编程语言本身,工具,或是框架就可以发现的问题,还需要人去介入,那无疑是在浪费时间,人的时间是宝贵的,应该花在更有价值和意义的事情上,而不是成为一个语法检查工具甚至是一个单身的语法检查工具...总之,你能明白我在说啥。

如果有 CI/CD......

A 君把代码推送到远程仓库之后,触发 CI/CD 流程,结果显示没有通过构建阶段,构建时发生语法错误,导致构建失败。此时 A 君还没收拾好自己的小书包,就被系统告知代码集成失败了,没有任何其他同事参与到 review,因为这样的代码不值得被 review。那么!A 君到底是选择恋爱还是工作呢?

故事二

今天前端 C 君早早来到公司,万恶的产品经理 D 君今天迟到了半小时,D 君走到 C 君位置说道:“新的官网首页得加个 xxx 链接,文案是 xxx,需求任务后面补给你”。C 君改好之后,把新静态文件通过 FTP 工具上传到服务器,然后跟 D 君说了下,D 君瞧了瞧说道:“链接是 xxx 才对,噢!还有新的活动页!还有...”,就这样,他俩忙活了一早上,其中 C 君不停的修改上传修改上传,C 君爆发了:“为什么不配一个后台,这样很多东西就可以通过后台修改啦!”,此时 B 君冷冷的说道:“A 君不是被辞退了嘛,在招了,忍忍哈”。

如果有 CI/CD......

C 君每次按照 D 君的需求进行修改,修改完成后,他只需要把代码推送到远程仓库,触发 CI/CD 流程,很快,新的静态文件被部署到了服务器,C 君撩着妹喝着茶,按了一下 Command + R(windows 就 F5 吧)。

看完两个小故事,或许你多少能够体会带 CI/CD 能够为我们带来什么,但故事中省略了很多细节,你能够体会到就可以。

那么,CI/CD 到底是什么?

CI 持续集成(Continuous Integration)

In software engineering, continuous integration (CI) is the practice of merging all developers' working copies to a shared mainline several times a day.

维基百科

持续集成的概念还是比较容易理解的,如果直接翻译过来会显得“不讲道理”,我还是用自己的语言表达一下吧。

持续集成可以帮助我们频繁的将代码变更自动合并到主干或共享分支。一旦变更被合并,负责集成的系统就会运行自动化测试(一般是单元测试,集成测试)来验证这些变更,确保这些变更不会对应用造成破坏,这也说明了测试环节尤为重要。若没有通过自动化测试或是代码有冲突,那么整个集成操作会失败,系统会给出反馈,此时相关的开发人员介入并进行修正,之后再开启新的一轮集成,直到这些变更被成功集成到主干或共享分支。

其中主干和共享分支,我在之前的 Git主干与共享分支 已经分享过了。

持续集成实现起来相对简单,所以在一些需要加入 CI/CD 流程的项目中,一般会先实现持续集成的流程。

CD 持续交付(Continuous Delivery)

Continuous delivery (CD) is a software engineering approach in which teams produce software in short cycles, ensuring that the software can be reliably released at any time and, when releasing the software, doing so manually.

维基百科

持续交付可以让我们拥有一个可以随时部署的代码库。

持续集成的流程之后,引入更为复杂测试流程(如功能测试),即部署到测试服务器上,测试人员介入,进行测试环节,过程中测试人员会进行反馈,如果测试不通过则开发人员介入并进行修正。

在大部分项目中,除了测试环境与生产环境,还会有一个预演环境,预演环境尽可能模拟生产环境,在通过了测试环境的测试后,还需要通过预演环境的测试,这样,新增的变更才会被认为在生产环境下可用。

在流程的最后,我们得到了新的可用于部署到生产环境的代码库,这也就是用于交付的内容,其实这么说并不那么准确,因为交付的内容一般跟项目、编程语言等有关,例如现在项目是一个 Go 写的 API 服务,那么我们交付的内容很可能就是构建好的可执行文件,又或者说是一个打了某个标签的 Docker 镜像,而不是一堆代码文件,我想这么说,你应该能够理解了吧。

这样,我们完成了交付,至于什么时候部署,就取决于业务或者是版本发布窗口期等因素了。

CD 持续部署(Continuous Deployment)

Continuous deployment (CD) is a software engineering approach in which software functionalities are delivered frequently through automated deployments.

维基百科

持续部署持续交付的延伸,在持续交付的流程后加入自动部署的环节,也就是说,如果你完整的实现了 CI/CD,你的代码变更一般会在数分钟之内被部署到生产环境。

要知道理想很美好,现实很骨感,为什么这么说?

持续部署在最后的阶段是没有手动控制发布的闸门的,也就是说,一旦在测试环节有半点疏漏,测试没有完全覆盖新的变更,那很有可能就会造成一起事故,然后这起事故就会变成你的一个故事......扯远了,因此,持续部署非常考验自动化测试的水平。

即使我们能够实现完美的自动化测试,现实中还会有其他因素令你不能爽快的应用持续部署,例如业务、版本发布的窗口期等因素,当然啦,如果你要细分的话,一些修复线上漏洞的紧急变更还是可以应用持续部署的流程的,总之,一切从实际出发,这样才能做出最适合的选择。

预告

不知道你现在是否已经有了对 CI/CD 的基本认知了呢?白话说 CI/CD,我希望没有变成白说 CI/CD,哈哈哈。

后续的分享:在实践 CI/CD 之前,我会带着你认识一下 Github flow。