从前端开发人员到DevOps:CI / CD 简介


【编者的话】如果你是一名前端开发者,且认为作为一名开发人员只要管好前端这摊子就算大功告成了,那你就out了。原文作者从一个前端开发者的角度,阐述了DevOps的理念,并结合一些示例和实践,告诉我们了解并运用持续集成和持续部署的诸多好处。但我认为,原文作者从始至终传递给我们一种持续学习的精神,这一点同样值得我们学习。

介绍

对于有抱负的前端开发者而言,2019年是充满憧憬的一年。

有不计其数的教材、课件和教程,每天还有无数的博客和文章,像雨后春笋般层出不穷。任何想成为专业人士的人都可以获得他们需要的一切——通常还是免费的。

许多人抓住这个机会自学成才,而且他们当中很多人有机会参与完整的项目,可以迅速上手写功能模块,修改Bug并以适当的方式组建代码。

经过一段时间,有些比较幸运的前端开发者就会在互联网的某个角落看到他们自己实现的功能模块,作为一个web app、门户或者一个website——对于初级开发者而言,这真的是一个荣耀的时刻。但令人惊讶的是,他们中很少有人会问一个非常重要的问题:我们开发的应用程序,是怎么放到互联网上的?
1.png

大家普遍认为这是由开发人员完成的,只不过是更“高级别”的开发人员而已。可能一些人听说过DevOps,运营商,云管理员,系统管理员以及其他更具神秘气息的东西。

嗯,这是真的——在某种程度上,编码和测试成功后发生的一切通常都和脚本,Linux命令和容器之类的黑科技有关。还有一条不成文的规定是,只有组织中最有经验和最值得信赖的开发人员/管理员才有资格完成最后的交付工作。

有必要这样吗?这确实是有一定道理的——毕竟,这是一项复杂且极其重要的任务。但是否就意味着这些技能只属于某些精英?当然不是。

作为前端开发者,我们可以选择忽略这一切并相信其他人会完成剩下的所有事情——但我们不应该这样。IT世界的竞争瞬息万变,无论是前端还是后端,对于技术栈的点滴积累将会使你成为一名更具竞争力的开发者。

如果你想在开发方面进步的更快或者在同龄人中脱颖而出,你迟早会需要这些知识。下面就让我告诉你为什么你会需要这些知识。

为什么开发人员都应该尝试自动化处理

正如我们前面提到的那样,写代码只是软件开发这个浩大的工程的一部分。我们先来看看任何产品交付所需的基本步骤——不一定是软件:
2.png

严格来说,我们在这里讨论的不一定都是编码。我们关注的是主要的开发阶段完成之后会发生什么?为什么它会如此重要?因为它有可能会很复杂 - 解决方案越严谨,这部分就越复杂。

假设有一个具有一些特定功能的Web应用。我们假定该应用的版本会按照一个一个的功能定期发布,前提是发布到生产环境之前,每一个功能都会进行测试。
3.png

问题来了,我们一般不会只招一名程序员来完成这项工作, 即会有一个团队来负责这些功能。这些假设意味着——除了每个开发人员本地的编码环境和最终稳定的生产环境之外——最好还有一个“staging”环境来验证这些功能。在这个环境中,测试人员/客户可以在实际投入生产环境之前评估它们的质量。

现在我们越来越接近这样的架构:
4.png

正如你所看到的,事情变得越来越复杂(相信我,我们在这里谈论的真的是一个非常简单的例子),但我们在这里不会涉及产品生命周期管理,我们只关注技术。

假设前端开发人员需要几分钟来构建一个应用程序。如果关心代码质量,他们需要运行linting,单元测试,集成测试或者用其他的方式确认之后才能提交。这个过程很耗时。

最后,将打包好的程序放到服务器额外还需要几分钟时间。如果我们给一个程序员分配了以上所有这些任务,请记住我们还没有考虑其切换上下文所需的时间(例如,更改代码分支,重新聚焦到他们的工作上等等)。

现在,谁想要手动部署每个功能?如果每天都测试了三个新功能怎么办?如果有15个呢?依据不同的部署规模,很有可能需要一个以上的全职人员来处理上述任务。

这就是为什么我们需要在这里运用计算机诞生之初的思想:我们应该用一台机器来为我们做这件事。

持续集成和持续部署的好处

在我们讨论用于构建,测试和部署代码的特定软件解决方案之前,我们先来熟悉一下描述该过程的两个术语。你可能已经听说过它们了:
5.png

注意,通常CD部分代表持续交付,这个概念略有不同,我们将不会在这篇文章中讨论。这种容易引起混淆的缩写通常是许多学术讨论的基础。Atlassian有一篇很棒的文章解释了它们之间的差异。

为什么有两个单独的短语,它们到底是什么意思?不用担心——为了避免混淆,让我们先弄清楚一点,然后描述两者背后的普遍意义。

CI / CD的持续集成部分涵盖了应用程序完整性的重复测试。从技术角度来看,这意味着我们需要不断执行linting,运行unit / E2E测试,检查源代码质量等。通过持续的方式,意味着必须在push新代码之前完成 - 即它应该自动完成。

例如,CI流程中可以定义一系列单元测试,这些单元测试将在拉取代码请求时一起运行。这种情形下,每次更新代码时,例如对于开发分支,一些机器会检查它是否符合标准且没有错误。

CI / CD的持续部署通常涵盖了构建和将应用程序部署到可用环境的一系列过程——这也是自动完成的。例如,它可以从指定的分支(例如:master)获取我们的应用程序代码,使用适当的工具(例如webpack)构建,并将其部署到正确的环境(例如,托管服务)。

它并不只限于生产环境;例如,我们可以配置一个Pipeline(管道)来构建应用程序的“staging”版本,并将其部署到适当的主机用于测试。

这两个术语是软件生命周期管理理论中完全不同源的独立概念,但在实践过程中,它们通常以互补的方式共存于一个大型Pipeline(管道)。为什么它们如此密不可分?因为通常CI和CD存在部分重叠。

例如,我们可能有一个项目,E2E测试和部署都需要用webpack构建前端代码。同时,在大多数“严苛”的生产级项目中,还有许多流程既有CI又有CD。

现在让我们想象在一个功能众多的项目中,CI / CD可以做些什么呢?
6.png

我知道越深入这个主题,流程图就越复杂 ——但是,这样一来在项目会议中用白板表示时,就显得很酷!

现在试想一下我们可以从上面的流程中得到些什么呢?我们从因与果的角度来分析,可以通过抽象特定的场景形成假想的工作流程。例如:

一名开发人员尝试push代码到公共代码库,然后需要执行一组单元测试。

通过这种方式,我们可以清晰得知道什么时候开始行动 - 我们可以通过使用脚本或其他机制实现自动化。在将来使用CI / CD的过程中,你可以为这些场景化的Pipeline命名。

注意上面的粗体字:当和然后,每个阶段都需要一个动作触发。为了运行特定的Pipeline,我们需要某种kickstart或触发器。这些可能是:
  • 计时类触发器(“每天下午6点构建staging版本的应用程序”)
  • 代码库触发器(“每次发布新的拉取请求时运行单元测试。”)
  • 手动触发器(“项目经理启动应用程序构建过程并部署到生产环境。”)


当然也可以通过其他的触发器触发特定的Pipeline,尤其是当我们需要通过许多单独构建的部分集成一个复杂应用程序的时候。

好吧,理论说的差不多了,现在来说说为我们完成这些工作的软件。

CI / CD中用到的软件

基本上,每个CI / CD软件说到底只是某种类型的任务执行工具,当触发某些操作时会运行Job(任务)。我们的主要工作是通过配置的方式提示要完成哪些Job以及何时完成等。

基于这些基本描述,CI / CD软件有许多类型,规格和偏好 - 其中一些软件非常复杂以至于手册都有数百页。但也不用害怕:在本文结束之前,你将熟悉其中一个。

对新手而言,我们可以把CI / CD软件分为两类:
  • 可安装软件:可以在你的电脑上或某些远程机器上安装的应用程序或服务(例如,Jenkins,TeamCity)
  • SaaS:由一个外部公司通过Web界面的方式提供的应用程序或服务(例如,CircleCI,Azure DevOps)


真的很难说哪一个更具优势,就像本文的主题一样,它取决于应用程序的要求,组织的预算和政策以及其他因素。

值得一提的是,一些受欢迎的源代码托管商(例如,BitBucket)会维护自己的CI / CD Web服务,这些服务和源代码管理系统紧密联系,旨在简化配置过程。此外,一些云托管的CI / CD服务是免费且对公众开放的 - 只要该应用程序是开源的就可以。

一个广受欢迎的例子就是CircleCI。我们将充分利用它的优势,简单几步就可以为我们的前端应用程序示例配置一个功能齐全的CI / CD的Pipeline。

前提和计划

CircleCI是一个云上的CI / CD服务,它能够与GitHub集成从而轻松获取源代码。该服务有一个有趣的规则:即pipeline在源代码内部定义。这意味着所有的操作和连锁反应都通过在源代码中配置一个特殊文件来实现,在CircleCI中是通过配置.circleci文件夹的config.yml文件实现的。

本文为了实现教学目的,将执行以下操作:
  • 写一个简单的前端应用程序并将源代码公开放在GitHub上
  • 创建并push包含Pipeline的配置文件config.yml
  • 创建一个CircleCI帐户并关联GitHub帐户
  • 找一个地方部署应用程序(这里,我们使用Amazon S3的主机托管服务)
  • 最后,运行创建的Pipeline


整个过程不应超过30分钟。接下来,我们来看看准备工作的清单。你需要:


第一步:环境设置

首先,从上述代码库签一个分支并克隆到本地计算机。如果你是新人,可以看下这波操作都做了什么。上述操作执行成功后,跳转到目标目录并执行以下命令:
npm install
npm start

现在打开浏览器输入到http://localhost:8080,你应该看到这样的画面:
7.png

这是一个非常简单的前端应用程序,表明成功加载了.js.css文件。你可以查看源代码,它用了一个非常简单的实现机制。

当然,你也可以用该教程中使用你自己的应用,只需要适当的修改创建脚本的命令就可以。只要程序是基于npm之类的工具创建的标准应用,应该都没有问题。

在使用自动化流程进行持续集成、持续部署之前,需要先构建应用程序并手动存到S3。这样,我们才能保证目标环境的配置没有问题。

首先,我们在本地构建应用程序包。如果你使用我们提供的示例程序,就可以用npm run build命令来创建,然后在项目的根目录底下得到一个名为dist的文件夹:
8.png

好了,我们的应用程序已经构建并打包完毕。你可以在测试服务器上执行npx serve -s dist命令查看它的运行情况。这个例子会运行一个serve包,它是一个轻量的HTTP服务器,可用来分发dist目录下的内容。

运行完命令以后可以通过http://localhost:5000查看,你会发现和它在开发环境服务器中的运行结果一致。

OK,我们把应用部署到互联网上,这要从S3开始。

作为AWS生态圈的一部分,Amazon S3的概念非常简单:它提供了一个存储,可以上传任何类型的文件(包括静态HTML,CSS和JavaScript等)并启用简单的HTTP服务器来分发这些内容。最棒的是(在某些情况下)它是免费的!

首先,登录:
9.png

AWS登录步骤1:提供登录用的电子邮箱

10.png

AWS登录步骤2:输入密码

接下来,点击服务按钮并在存储项中选择S3,跳转到S3控制面板。
11.png

现在,我们将创建一个新的存储桶来存储我们的Web应用程序。首先,输入名称,名称只支持字母数字字符和连字符。然后,为存储桶选择适当的域。注意要记录这两个值,稍后会用到。
12.png

13.png

有一点非常重要就是设置适当的权限,这样文件才是公开的类型。因此,单击下一步直到出现设置权限选项,然后点击取消前三个框以启用文件的公开托管方式:
14.png

这样,HTTP服务器就能将上传的文件作为网站公开。在设置完存储桶之后,你可以访问并查看文件列表:
15.png

点击上传按钮,系统将提示你选择要上传的文件,你可以从dist文件夹中选择三个包文件上传。这里的操作和之前的一样,一定要到设置权限处选择管理公共权限框下的对该对象赋予公共读取权限,这点非常重要。

瞧!文件已经在了,最后一步是要在S3上启用托管服务。通过存储桶视图找到属性按钮,打开静态网站托管选项:
16.png

你需要添加index.html作为索引文档,它将作为应用程序的入口。现在,一切准备就绪。在对话框的开头会生成一个新站点的链接,点击就可以查看刚才部署的应用:
17.png

太棒了,我们有了一个网站——可惜这不是这次的目标,因为到此为止什么都没自动化。你肯定不希望用这种方式登录S3控制台并在每次更新时上传一堆文件,那是机器要做的事。

那么,我们来建一个持续部署的流程吧!

第二步:准备CircleCI配置

如果仔细查看代码库中的示例程序,你会看见一个CD的定义文件,打开.circleci/config.yml文件。
version: 2.1
orbs:
aws-s3: circleci/aws-s3@1.0.4
jobs:
build:
docker:
  - image: circleci/python:2.7-node
environment:
  AWS_REGION: us-east-1
steps:
  - checkout
  - run: npm install
  - run: npm run build
  - aws-s3/sync:
      from: dist
      to: 's3://demo-ci-cd-article/'
      arguments: |
        --acl public-read \
        --cache-control "max-age=86400" \
      overwrite: true
workflows:
version: 2.1
build:
jobs:
  - build:
      filters:
        branches:
          only: master

如上所述,config.yml是CircleCI可识别的文件,它包含了CD过程中定义好的pipeline信息。本文的例子中,26行代码包含了以下的内容:
  • 构建应用程序需要哪些工具
  • 构建应用程序需要哪些命令
  • 应用程序在哪里以及如何部署


如果你不熟悉YAML文件,你会注意到它大量使用制表格式。这就是这类文件的组织结构:每一部分都有子节点,而层次结构由一个有双空格组成的tab标志。

现在,我们来逐层看一下文件结构:
version: 2.1
orbs:
aws-s3: circleci/aws-s3@1.0.4

上面几行代码包含了解析器的版本信息,并定义了部署过程中会用到的附属包(CircleCI命名规则中的“orbs”)。在这里,我们需要导入一个名为aws-s3的orb ,它包含把文件发送到S3存储桶所需的工具。
jobs:
build:
docker:
  - image: circleci/python:2.7-node
environment:
  AWS_REGION: us-east-1
steps:
  - checkout
  - run: npm install
  - run: npm run build
  - aws-s3/sync:
      from: dist
      to: 's3://demo-ci-cd-article/'
      arguments: |
        --acl public-read \
        --cache-control "max-age=86400" \
      overwrite: true

上面几行代码包含了Job的定义信息,即Pipeline的核心内容。

这里要注意的一点是,像上述第二行中所示我们把Job命名为build,稍后我们会在CircleCI控制台的报告中看到这个名字。

下一行写着docker,这部分我们定义创建应用的容器(在哪台虚拟机运行)。如果不熟悉容器或者Docker,这一步你可以想象成选择一台虚拟机然后创建应用。

这里,有一台预装了Python和Node.js的Linux虚拟机,我们需要用Python运行AWS S3的工具,用Node创建前端应用。

environmentAWS_REGION是AWS运行用的环境变量,可以不用在意具体的参数。到此,S3就能运行了。

下一部分,steps更具自描述性。实际上,它是完成Job需要执行的一系列步骤。这部分的示范定义如下:
  • checkout:从代码库中获取源代码
  • run: npm install:安装依赖包
  • run: npm run build:Pipeline的核心,用于构建代码
  • aws-s3/sync:另一个重要步骤,它部署(“同步”)S3存储桶中给定的dist路径下的内容。注意,这个示例把demo-ci-cd-article作为存储桶的名字,你需要修改存储桶名字,使它和示例中的名称一致。


解析CircleCI配置

基本上,你可以把它想象成运行在本地的一个包含一组操作的job,这样就是告诉VM一步一步如何完成。当然,你也可以认为它是具备一些特定功能的特殊的shell脚本。

job有一个重要原则那就是每一个步骤都得成功。有任何一个命令失败,就不再执行后续操作,当前的pipeline的状态也会标记为FAILED。Job执行失败的信息会在CI / CD控制台中显示,包括相关错误日志,有助于排错。

失败的原因有很多,比方说,对于一个执行自动测试的pipeline,它可能意味着一次单元测试的失败并且某个开发人员需要修复他的代码,或者也有可能是工具的配置有问题,从而导致构建和部署失败。无论是什么原因,CI / CD流程通常会通过电子邮件的方式通知管理员(或本人)执行失败的消息。

这就是为什么要以相对安全的方式定义jobs,以便在执行某一步出错时,确保之前的步骤不会产生任何永久的负面影响。

马上就要结束了,最后一部分是workflows
workflows:
version: 2.1
perform_build:
jobs:
  - build:
      filters:
        branches:
          only: master

在CircleCI中“workflow”是一组互相协作的Job。由于之前我们只定义了一个Job(build),我们可以暂时不考虑这部分。但是,通过定义工作流的方式可以实现一个很重要的功能:branch filtering(筛选分支)。

你可以看到配置文件中的最后2行定义了filters。在这个例子中,它包含了branches: only: master,即定义了只有主分支上的代码更新才会执行构建代码Job。

这样就可以通过CI / CD流程筛选出需要“watched(监控)”的分支。例如,可以在不同的分支上调用不同的工作流(包含不同的Job),然后构建单独的版本,或仅在特定情况下测试等。

最后一步:CircleCI实践

如果你还没有完成,通过登录GitHub的方式,关联你的GitHub帐户与CircleCI
18.png

登录GitHub并授权给CircleCI后,你会在导航栏看见一个Add Project(添加项目)的选项。点击它可以查看你在GitHub中的代码库列表:
19.png

不管是拷贝的示例还是你自己准备的应用(记住有一个.circleci/config.yml文件),先假设你已经有一个代码库了。
然后,在列表中找到该项目后单击旁边的Set Up Project(设置项目)选项。你会看到一个描述CircleCI规则的画面:
20.png

看到底部Start building(开始构建)的按钮了吗?是的,就是它。点击它来启用我们的自动化流程,让机器为我们工作。
点击这个按钮后,你会看到……一个错误提示。
21.png

好吧,我们还需要配置一个地方:让CircleCI API授权给AWS的机制。到目前为止,我们还没有把AWS密码放入代码,GitHub或CircleCI里,所以AWS还不知道我们要把东西放入S3,所以报错。

通过改CircleCI面板中的项目设置来配置。单击右上角的齿轮图标,然后在左边找AWS权限选项卡,你会看到以下画面:
22.png

Access Key ID(访问秘钥ID)Secret Access Key(加密访问秘钥)是AWS的2个鉴权值,用于对CircleCI等第三方服务的鉴权。例如,将文件上传到S3存储桶。最初,这些密钥将具有与分配给它们的用户相同的权限。

你可以通过AWS控制台的IAM生成这些信息。进入IAM,打开访问秘钥Access Key ID(访问秘钥ID)Secret Access Key(加密访问秘钥)】窗口,点击创建新的访问密钥,生成可以复制到CircleCI的密钥对:
23.png

单击Save AWS keys(保存AWS秘钥)就可以了。你可以在CircleCI上尝试重新初始化代码库,也可以用更加快捷的方式:找到失败的报告,然后点击Rerun workflow(重新执行)工作流程按钮。
24.png

现在所有的问题都搞定了,构建应用应该不会再出状况了。
25.png

太棒了!你可以登录S3控制台并检查文件的修改时间,可以证明文件是新上传的。不过还没完事呢,我们来看看“持续”部分是如何工作的。我将返回代码编辑器,说一下应用(index.html)的一个小的变动:
26.png

现在,我们可以将代码推送到代码库:
git add .
git commit -m “A small update!”
git push origin master

神奇的事情发生了。眨眼之间,在成功推送后,CircleCI已经在用更新后的代码构建应用了:
27.png

几秒钟后,会有一条执行SUCCESS的消息。现在,你可以刷新一下S3托管的web页面,就可以看到修改后的应用:
28.png

搞定!这一切都是自动执行的:推送完代码后互联网上的一些机器自动构建并部署到生产环境中。

进阶练习

当然,这只是一个简单的例子。现在我们来看一个更复杂的例子。例如,部署到多个环境并更改应用。

回到我们的示例代码,你会发现在package.json中有两个独立的构建脚本:一个用于production环境,一个用于staging环境。由于只是一个示例项目,所以不会发生大的变更。这里,它只是用一个不同的JavaScript控制台消息表示而已。

应用在staging环境运行之后打开浏览器,你可以在JavaScript控制台看到相应的日志信息:
29.png

现在,我们利用这个机制扩展构建应用的pipelines。请看以下的代码:
version: 2.1
orbs:
aws-s3: circleci/aws-s3@1.0.4
jobs:
build:
docker:
  - image: circleci/python:2.7-node
environment:
  AWS_REGION: us-east-1
steps:
  - checkout
  - run: npm install
  - run: npm run build
  - aws-s3/sync:
      from: dist
      to: 's3://demo-ci-cd-article/'
      arguments: |
        --acl public-read \
        --cache-control "max-age=86400" \
      overwrite: true
build-staging:
docker:
  - image: circleci/python:2.7-node
environment:
  AWS_REGION: us-east-1
steps:
  - checkout
  - run: npm install
  - run: npm run build:staging
  - aws-s3/sync:
      from: dist
      to: 's3://demo-ci-cd-article/'
      arguments: |
        --acl public-read \
        --cache-control "max-age=86400" \
      overwrite: true
workflows:
version: 2.1
build:
jobs:
  - build:
      filters:
        branches:
          only: master
build-staging:
jobs:
  - build-staging:
      filters:
        branches:
          only: develop

注意,我们添加了一个新的job和一个新的build-staging工作流程。有两点不同:新job调用前面提到的

npm run build:staging方法,同时用develop分支进行筛选。

这意味着所有到develop分支的推送都将用“staging”构建,而master分支上的所有变更都将保留其原始状态并触发“production”构建。在这里,双方都会在同一个S3存储桶中,但我们可以修改并让它们在相互隔离的目标环境中运行。

可以试一下:基于master分支创建一个新的develop分支并将代码推送到代码库。在CircleCI控制台,你会看到调用了不同的工作流程:
30.png

相应的变更推送到了S3存储桶,但这次在staging上构建来自develop分支的应用,实现了多版本的构建工作。很好,我们马上就能实现之前描述过的工作流程啦!

持续集成部分

我们已经完成了持续部署部分的内容,但什么是持续集成呢?正如之前说过的,这部分涉及到定期检查代码的质量,例如:执行测试。

如果仔细看示例的代码库就可以看到有一个单元测试样例,可以用npm run test命令执行该测试样例。它通过断言的方式比较了某些模式下虚函数的结果。
function getMessage() {
return 'True!';
}

// ...

module.exports = getMessage;


const getMessage = require('./jsChecker');
const assert = require('assert');

assert.equal(getMessage(), 'True!');

我们可以在管道中加入测试,然后设置成在每个拉取请求时执行就可以。实现方式是在config.yml里创建一个新job和一个新的工作流程:


config.yml
version: 2.1
orbs:
aws-s3: circleci/aws-s3@1.0.4
jobs:
build:
# ...
build-staging:
# ...
test:
docker:
  - image: circleci/python:2.7-node
steps:
  - checkout
  - run: npm install
  - run: npm run test
workflows:
version: 2.1
build:
# ...
build-staging:
# ...
test:
jobs:
  - test

我们已经定义了一个新job和一个名为test的工作流程,唯一的目的是触发npm run test脚本。然后,将此文件推送到代码库,看一下CircleCI控制台会发生什么:
31.png

一个新的工作流程被自动触发,并完成了一次成功的测试。接下来把它和GitHub的代码库进行对接,这样一来每次拉取特定分支的请求都会触发该job。要实现这一点,只需要打开GitHub页面并到Settings(设置)页面,选择Branches(分支)
32.png

单击Add rule(添加规则),就可以添加一个新的策略。该策略将在合并拉取请求之前强制执行一系列检查,其中一项检查就是调用CircleCI工作流程,如下所示:
33.png

通过勾选Require status checks to pass before merging(合并之前要检查状态)并勾选的ci/circleci: test,就可以将规则设置为在拉取前执行该工作流。

该规则可以通过创建一个新的拉取请求来测试,然后打开Checks(检查)面板来查看测试情况:
34.png

当然,也可以测试该规则无效的情况。你可以提交一个会导致测试失败的变更,把它放到一个新分支上并执行一个拉取请求:
35.png

我们模拟了一个失败的测试,输出结果如下:
assert.equal(getMessage(), 'True!');
-->
> node src/modules/jsChecker.test.js
assert.js:42
throw new errors.AssertionError({
^
AssertionError [ERR_ASSERTION]: 'True, but different!' == 'True!'
at Object.<anonymous>

现在这个拉取请求将无法合并,因为它引入了导致测试失败的代码:
36.png

赞!我们的示例项目成功覆盖了连续测试的各种情况,只要测试用例没问题,就不可能把错误的代码引入到生产分支。同样的机制还可用于执行代码linting,静态代码分析,E2E测试和其他自动化检查等。

好的,就这样!虽然我们的示例项目非常简单,但它展现了真实且有效的CI / CD流程。无论是集成还是部署都由云上的工具执行,所以开发者可以将所有注意力集中到编码上。

无论涉及多少人,机器都将不知疲倦地工作,并检查一切是否到位。虽然设置这一切也需要花费一些时间,但从长远看,把机械性操作进行自动化处理是非常有意义的一件事。

当然,它不是永远的免税天堂:迟早会产生额外的费用。例如,CircleCI每月提供1,000分钟的免费构建。对于小型团队和简单的开源项目来说足够了,但对大型的企业级项目而言肯定会超过这个配额。

延伸阅读

我们学习了许多基础的知识,但这篇文章还有许多重要的内容还没来得及讲解。

有一点就是如何更好的使用环境变量。通常我们都不会直接在源代码中保存密码,API密钥和其他敏感信息。当引入CI / CD自动化流程后,首先需要向机器提供适当的变量,就像我们在示例中使用AWS密码一样。

除此之外,环境变量来可以用来控制构建的过程,例如:应该构建哪个或者应该在特定版本中启用哪些特征之类。你可以通过它们在CircleCI中的使用这篇文章中获得更多的信息。

另一个是:许多CI / CD流程引入了组件管理的概念。组件是对特定构建过程中产生的代码的通称。例如,一个包或具有特定版本的应用程序的容器镜像都可以看做组件。

在特定组织中,由于各种原因导致对组件版本的管理变得格外重要。例如:它们可能会被归类和归档以便用于回滚或其他用途。

另一个重要的部分是角色、权限和安全性。这篇文章涉及到定义Pipelines和工作流的基础操作,但在大型、真实的项目中,有必要将组织的流程和策略等考虑在内。例如,我们希望某个Pipeline只能由公司组织架构中的某个人调用或批准。

另一个例子是对特定管道的设置或VM的配置进行细粒度的控制。但同样,这取决于用什么软件以及特定项目或公司的要求,好的自动化流程没有一个单一的范式,就像好的IT项目没有单一的模式一样。

总结

好了,言归正传。

不知道这篇文章会让你有什么样的收获?重要的是,现在你已经对一些“重大”的项目中发生的事情有了一个大致的了解。无论使用何种方法和软件,一些基本的规则总是相似的:有任务、管道和代理执行此工作流程。希望通过这篇文章,会让你对许多概念有一个新的认识。最后,你可以试着创建实际工作中用到的CI / CD Pipeline,并用自动化的方式将应用部署到云上。

接下来你还可以做什么呢?

当然,继续扩充你的知识,努力做的更好。如果你正在为公司开发项目,可以尝试写写代码,创建你自己的测试/部署pipeline。你可以(甚至应该)在你的下一个开源项目中引入自动化测试、打包等。您还可以了解更多的CI / CD软件:例如Travis,Jenkins或Azure DevOps。

此外,你还可以查看我的个人资料中与前端开发相关的其他帖子。祝你好运!

原文链接:From front-end developer to a DevOps: An intro to CI/CD (翻译:Tiny Guo)

0 个评论

要回复文章请先登录注册