vlambda博客
学习文章列表

读书笔记《hands-on-docker-for-microservices-with-python》创建管线和工作流

Creating a Pipeline and Workflow

在工作流中通过不同阶段自动运行的管道将及早发现问题并帮助您的团队以最有效的方式进行协作。

在本章中,我们将遵循持续集成实践,在每次更改时自动运行管道,以确保我们所有的代码都遵循高质量标准,并且运行并通过所有测试。我们还将准备一个容器以投入生产。

我们将了解如何利用 GitHub 和 Travis CI 等工具以最少的干预创建图像。

在本章中,我们将讨论以下主题:

  • Understanding continuous integration practices
  • Configuring Travis CI
  • Configuring GitHub
  • Pushing Docker images from Travis CI

在本章结束时,您将了解如何在每次代码更改时自动运行测试,以及如何创建一个安全网,使您能够更快、更高效地进行开发。

Technical requirements

Understanding continuous integration practices

持续集成(通常缩写为CI)是一系列确保代码始终处于工作状态的软件工程实践。

术语持续集成来自历史上必须频繁集成软件,通常每天多次集成。这是因为开发人员使用的本地代码不一定会自动与其他人的代码结合在一起。如今,使用 Git 等源代码控制版本控制软件可以自动使用某些元素。

持续集成强调始终拥有潜在可发布的代码。这使得发布可能非常频繁,代码增量很小。

Making more releases more often actually generates an increase in the quality of each release. More deployments also mean that each deployment is smaller, reducing the possibility of a big problem. Even if it sounds counterintuitive, faster deployment is highly correlated with higher quality in deployments and fewer production problems.

The objective here is to be able to increase the deployment speed. But for that, we need to be sure to build a good safety net that checks (automatically) that what we're doing is safe to release. That's where all the CI practices come into play.

在将所有流程和基础设施设置到位后,每天多次实施发布是很有可能的(假设代码生成速度足够快)。到达那里可能需要一段时间,但请务必花时间了解该过程并制作所有必要的工具,以确保您在不牺牲稳定性的情况下获得速度。而且,相信我,这是完全可以实现的!

Producing automated builds

CI 的核心元素是生成与源代码控制系统集成的自动化构建。 软件构建是(从源代码开始)执行一系列操作并产生输出的过程。如果项目是用编译语言编写的,则输出通常是编译后的程序。

如果我们想要拥有高质量的软件,那么构建的一部分涉及检查生成的代码是否符合代码标准。如果代码不遵循这些标准,则构建将返回错误。

A common way of describing errors on a build is to say that the build is broken. A build can break in different ways, and some kinds of error may stop it early (such as a compilation error before running tests) or we can continue to detect further issues (such as running all tests to return all possible errors).

可以作为构建的一部分的一些步骤示例如下:

  • Compiling the code.
Python 通常不需要编译,但如果您使用 C 扩展(用 C 编写并从 Python 导入的模块),则可能需要编译: https://docs.python.org/3/extending/) 或 Cython 等工具( https://cython.org/ )。

任何可以自动运行的东西都可以成为构建的一部分。可以随时生成本地构建,即使代码仍在进行中。这对于调试和解决问题很重要。但是自动构建将针对每个单独的提交运行,而不是在任何中间阶段。这使得检查哪些代码预计在生产中运行以及哪些代码仍在进行中变得非常明确。

请注意,单个提交可能仍在进行中,但无论如何都值得提交。也许这是朝着某个功能迈出的一步,不止一个人在处理代码的同一部分,或者它的工作分散了几天,代码在一天结束时被推送。无论如何,每次提交都是一个可重复的步骤,可以构建并检查构建是否成功。

为每个提交运行构建非常快速检测问题。如果提交很小,则很容易确定重大更改。它还可以轻松恢复破坏构建的更改并返回到已知的工作代码。

Knowing the advantages of using Docker for builds

构建的主要传统问题之一是拥有足够的构建环境,其中包含运行完整构建所需的所有依赖项。这可能包括诸如编译器、运行测试的测试框架、任何静态分析工具和包管理器之类的东西。版本的差异也可能产生错误。

正如我们之前所见,Docker 是封装我们软件的绝佳方式。它允许我们创建一个包含我们的代码和所有能够完成所有步骤的工具的图像。

在上一章中,我们看到了如何基于构建映像在单个命令中运行单元测试。映像本身可以运行自己的单元测试。这将测试环境抽象化并明确定义它。这里唯一需要的依赖是安装 Docker。

请记住,单个构建可以生成多个图像并使它们协同工作。我们在上一章中看到了如何运行单元测试——通过生成服务镜像和数据库镜像——但是还有更多可能的用法。例如,您可以检查在两个不同操作系统上运行的测试,从每个操作系统或不同的 Python 解释器版本创建两个图像,并检查测试是否通过所有这些。

使用 Docker 镜像可以在所有环境中实现标准化。我们可以使用我们在自动化环境中执行的相同命令,在开发环境中本地运行映像。这简化了错误和问题的查找,因为它在构建运行的任何地方创建了相同的环境,包括一个封装的操作系统。

不要小看这个元素。在此之前,开发人员在运行 Ubuntu 的笔记本电脑上工作并热衷于运行要部署在 CentOS 中的代码,需要安装一个 虚拟机 ( VM)并按照步骤创建一个类似于生产环境的环境。但是本地虚拟机总是会出现偏差,因为很难让每个开发人员的本地虚拟机与生产中的虚拟机保持同步;此外,任何自动构建工具也可能有要求,例如不支持在生产中运行的旧版本 CentOS。

更糟糕的是,有时会在同一个虚拟机上安装不同的项目,以避免每个项目只有一个虚拟机,这可能会导致兼容性问题。

Docker 极大地简化了这个问题,部分地迫使您显式地声明依赖项是什么,并减少了运行我们的代码实际所需的表面。

请注意,我们不一定需要创建运行整个构建的单个步骤;它可能是几个 Docker 命令,甚至使用不同的图像。但要求是它们都包含在 Docker 中,这是运行它所需的唯一软件。

使用 Docker 构建的主要产品是 Docker 镜像或镜像。我们需要正确标记它们,但前提是构建成功。

Leveraging the pipeline concept

CI 工具有助于阐明构建应如何进行并围绕管道的概念工作。管道是阶段的集合。如果其中任何一个不成功,则管道将停止。

管道中的每个阶段都可以生成可以在以后的阶段使用的元素,或者可以作为完整构建的最终产品使用。这些最终元素被称为工件。

我们来看一个管道的例子:

读书笔记《hands-on-docker-for-microservices-with-python》创建管线和工作流

第一阶段从源代码控制系统中提取最新提交。然后,我们构建所有容器并运行测试和静态分析。如果一切顺利,我们标记生成的 server 容器并将其推送到注册表。

The order in which these stages run should be oriented at detecting problems as quickly as possible to give quick feedback. For example, if the static-analysis stage is much faster than the test stage, putting the analysis stage first will make a failing build finish earlier. Be aware of which parts can be executed earlier to reduce the feedback time.

CI 工具通常允许在管道中进行很好的配置,包括并行运行不同阶段的可能性。为了能够并行运行阶段,它们需要能够并行化,这意味着它们不应更改相同的元素。

如果选择的 CI 工具允许并行运行阶段,则管道可以定义如下:

读书笔记《hands-on-docker-for-microservices-with-python》创建管线和工作流

请注意,我们并行构建数据库和测试图像。下一阶段构建其余元素,这些元素已经在缓存中可用,因此它会非常快。测试和静态分析都可以在两个不同的容器中并行运行。

这可能会加速复杂的构建。

Be sure to validate that the amount of time taken reduces. There are cases where the time taken will be very similar. For example, static analysis could be very fast or the hardware you run it on may be not powerful enough to build things in parallel, making the time taken to build in parallel and sequentially very similar. So, always validate your assumptions.

该管道在特定于 Travis CI 工具的脚本中进行了描述。稍后我们将看一个使用 Travis CI 的示例。

Branching, merging, and ensuring a clear main build

我们什么时候运行构建?每次推送一个提交。但每一个结果都不一样。在处理诸如 Git 之类的源代码控制系统时,我们通常有两种分支:

  • One main branch
  • Feature branches

它们实现了特定的功能或错误修复,准备就绪后将合并到主分支中,如下图所示:

读书笔记《hands-on-docker-for-microservices-with-python》创建管线和工作流

在这个例子中,我们看到了主分支(ma​​ster)是如何被分支来开发feature A的。 Feature A 之后简单介绍。有一个 功能 B 尚未合并,因为它还没有准备好。有了关于哪些构建成功与否的额外信息,我们可以知道何时将功能分支合并到主分支是安全的:

读书笔记《hands-on-docker-for-microservices-with-python》创建管线和工作流

尚未合并的功能分支中的破坏不是很大,但是在它正在进行中时,预计会发生。同时,主分支的破损是应该尽快修复的事件。如果主分支状态良好,则意味着它有可能被释放。

GitHub 有一个模型:拉取请求。我们将配置拉取请求以自动检查构建是否已通过并避免合并。如果我们在合并回来之前强制任何功能分支也与主分支保持同步,那么主分支最终会非常稳定。

For dealing with branches in Git to define releases, the most popular model is Git-flow, defined in this influential blog post ( https://nvie.com/posts/a-successful-git-branching-model/). The following CI practices allow simplify things a bit and don't deal with elements such as release branches. This blog post is a highly recommended read.

在主分支中拥有不间断的成功构建线也非常有助于培养项目的稳定性和质量感。如果主分支损坏非常罕见,那么使用最新主分支创建新版本的信心非常高。

Configuring Travis CI

Travis CI (https://travis-ci.com/) 是一种流行的持续集成服务,可免费用于公共 GitHub 项目。与 GitHub 的集成非常简单,它允许您配置它运行的平台,例如 macOS、Linux 甚至 iOS。

Travis CI 与 GitHub 紧密集成,因此您只需登录 GitHub 即可访问它。我们将看到如何将我们的项目连接到它。

为清楚起见,只有本章中的代码与 Travis 相关联。

Travis 与其他 CI 工具的工作方式略有不同,它通过启动新 VM 来创建独立作业。这意味着为前一阶段创建的任何工件都需要复制到其他地方,以便在下一阶段开始时下载。

这有时会让事情变得有点不切实际,一个简单的解决方案是为每个单独的工作构建多次。

Configuring a remote system such as Travis CI can be a little frustrating sometimes, as it requires you to push a commit to be built to see if the configuration is correct. Also, it gets configured with a YAML file, which can be a bit temperamental in terms of syntax. It will take you a few attempts to get something stable, but don't worry. Once it is set up, you can change it only via a specific pull request as the configuration file is also under source control.

You can also check the requests in the Travis CI configuration to see if a .yml file creates a parse error.

You can check full Travis CI documentation here: https://docs.travis-ci.com/ .

要配置 Travis CI,我们首先从 GitHub 添加一个存储库。

Adding a repo to Travis CI

要将 repo 添加到 Travis CI,我们需要执行以下步骤:

  1. The first stage is to go to the Travis CI web page and log in with your GitHub credentials.
  2. Then, you'll need to grant Travis access to GitHub, by activating it.
  3. Then, select which repo you want to build.
The easiest starting point is to fork the repo with the examples from this book in https://github.com/PacktPublishing/Hands-On-Docker-for-Microservices-with-Python. Feel free to do so!

But remember to change the usernames, credentials, and registry information to match your own.

您需要拥有 GitHub 存储库的所有者权限,然后您就可以开始了!

Creating the .travis.yml file

Travis CI 的主要元素是创建 .travis.yml 文件。

Be sure to name it exactly like this (including the initial dot and the .yml extension) and include it in the root directory of your GitHub repo. If not, Travis CI builds won't start. Please note that, in the example repo, the file is in the root directory and not under the Chapter04 subdirectory.

.travis.yml 描述了构建及其不同的步骤。构建在一个或多个 VM 中执行。可以通过指定通用操作系统和特定版本来配置这些 VM。默认情况下,它们在 Ubuntu Linux 14.04 Trusty 中运行。您可以在此处找到有关可用操作系统的更多信息:https://docs.travis-ci .com/user/reference/overview/

使用 Docker 可以让我们抽象出大部分操作系统的差异,但我们需要确保我们使用的具体 dockerdocker-compose 版本是正确的。

我们将使用以下代码启动 .travis.yml,确保存在有效的 docker-compose 版本 (1.23.2):

services:
  - docker

env:
  - DOCKER_COMPOSE_VERSION=1.23.2

before_install:
  - sudo rm /usr/local/bin/docker-compose
  - curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-`uname -s`-`uname -m` > docker-compose
  - chmod +x docker-compose
  - sudo mv docker-compose /usr/local/bin
  - docker --version
  - docker-compose version

before_install 块将在我们所有的虚拟机中执行。现在,为了运行测试,我们添加一个 script 块:

script:
- cd ch4
- docker-compose build db
- docker-compose build static-analysis
- docker-compose build test-postgresql
- docker-compose run test-postgresql
- docker-compose run static-analysis

我们构建所有要使用的图像,然后运行测试。请注意,使用 PostgreSQL 数据库运行测试需要您构建 db 容器。

有一个关于这个的小细节 db 容器:Travis VM 不允许我们打开端口 5432。我们删除了 端口docker-compose 为此。请注意,这仅使 PostgreSQL 在外部可用于调试目的;在内部,容器可以通过它们的内部网络相互通信。

我们创建了一个 db-debug 服务的副本 db 但它公开了用于本地开发的端口。您可以在 docker-compose.yaml 文件位于 https://github.com/PacktPublishing/Hands-On-Docker-for-Microservices-with-Python/blob/master/Chapter04/docker-compose.yaml

这将运行所有测试。推入 repo 后,我们可以看到构建在 Travis CI 中开始:

读书笔记《hands-on-docker-for-microservices-with-python》创建管线和工作流

一旦完成,我们可以通过它被标记为绿色来判断构建成功。然后可以检查日志以获取更多信息:

读书笔记《hands-on-docker-for-microservices-with-python》创建管线和工作流

现在您可以在日志末尾看到测试:

读书笔记《hands-on-docker-for-microservices-with-python》创建管线和工作流

这对于检测问题和构建中断很有用。现在,让我们看看工作在 Travis 中是如何工作的。

Working with Travis jobs

Travis 将整个构建划分为一系列阶段,这些阶段将一个接一个地运行。在每个阶段,可以有多个工作。同一构建中的所有作业都将并行运行。

正如我们之前所见,我们可以将测试和静态分析配置为并行运行,方法是将 script 部分替换为 工作 部分:

jobs:
  include:
    - stage: tests
      name: "Unit Tests"
      script:
      - cd ch4
      - docker-compose build db
      - docker-compose build test-postgresql
      - docker-compose run test-postgresql
    - stage: tests
      name: "Static Analysis"
      script:
      - cd ch4
      - docker-compose build static-analysis
      - docker-compose run static-analysis

这在一个阶段隐含地创建了两个工作。该阶段名为 tests,作业名为 "Unit Tests""Static Analysis"

结果出现在 Travis 页面上:

读书笔记《hands-on-docker-for-microservices-with-python》创建管线和工作流

请注意,在这两种情况下,由于作业是独立的,因此它们需要构建所需的图像。由于单元测试作业需要构建 db 映像,这需要几分钟,它比静态分析要慢。

您可以查看每个作业的详细日志。请注意环境设置和 before_install 操作如何在所有作业中执行。

这种划分可以不仅可以相当显着地加快构建速度,还可以明确问题所在。一眼看去,你可以看到破坏因素要么是单元测试,要么是静态分析。这消除了混乱。

Sending notifications

默认情况下,Travis CI 将发送电子邮件通知构建结果,但仅在 构建被破坏或修复了破坏的构建时。 这避免了不断发送成功 电子邮件并仅在需要采取行动时采取行动。默认情况下,电子邮件仅发送给提交者(以及提交作者,如果不同)。

Note that there's a difference between failed builds and errored builds. The latter are failures in the job setup, which means that there's a problem in the before_install, install, or before_script sections, while failed builds arise because the script part returned a non-zero result. Errored builds are common while changing Travis configuration.

Travis 允许我们配置通知电子邮件并连接更多通知系统,包括 Slack、IRC 甚至 OpsGenie,它们能够根据待命时间表发送 SMS 消息。在此处查看完整文档以获取更多信息:https://docs.travis-ci.com/user /通知/

Configuring GitHub

为了充分利用我们配置的 CI 系统,我们需要确保在将构建合并到主分支之前检查它。为此,我们可以将 master in GitHub 配置为主分支,并在合并之前添加需求:

Be sure that the .travis.yaml file contains the proper credentials if you fork the repo. You'll need to update them with your own.
  1. Go to Settings and Branches in our GitHub repo and click Add rule.
  2. Then, we enable the Require status checks to pass before merging option with the status checks from travis-ci:
读书笔记《hands-on-docker-for-microservices-with-python》创建管线和工作流
  1. We also select the Require branches to be up to date before merging option. This ensures that there are no merges into master that haven't been run before.
Take a look at the other possibilities that GitHub offers. In particular, enforcing code reviews is advisable to make code to be reviewed before being merged and disseminating knowledge.
  1. After creating a new branch and a new pull request designed to fail static tests, we can see how tests are added to GitHub:
读书笔记《hands-on-docker-for-microservices-with-python》创建管线和工作流

Details 链接将您带到 Travis CI 和特定构建。您还可以查看构建的历史记录:

读书笔记《hands-on-docker-for-microservices-with-python》创建管线和工作流

构建完成后,GitHub 不会让您合并拉取请求:

读书笔记《hands-on-docker-for-microservices-with-python》创建管线和工作流

详细信息可以在 Travis CI 的构建页面上找到:

读书笔记《hands-on-docker-for-microservices-with-python》创建管线和工作流

修复问题并推送代码将触发另一个构建。这次就成功了,拉取请求合并成功。您可以查看每个提交如何拥有自己的构建信息,无论它是正确的还是不正确的:

读书笔记《hands-on-docker-for-microservices-with-python》创建管线和工作流

我们现在可以合并到 master 分支,确信 master 分支在运行测试时不会中断。

Note that there are two builds in the pull request: one for the branch and another for the pull request. By default, Travis CI has that configuration. If you force it to always create a pull request before merging, the request will be redundant, though it can help in some cases when the branch gets pushed before creating a pull request. You can enable or disable it in the Travis project configuration.

Another interesting feature that can be configured is automatically canceling builds if a newer commit is pushed. This helps to reduce the total number of builds in the system.

构建结果也可以在 GitHub 的 Commits 视图中查看。

Pushing Docker images from Travis CI

在我们的构建创建了一个 Docker 镜像之后,我们需要能够与团队的其他成员共享它或部署它。如前一章所述,我们将使用 Docker Hub 中的 Docker 注册表来推送镜像。

让我们从设置秘密变量开始。

Setting the secret variables

为了能够推送到 Docker 仓库,我们首先需要配置一个密码来登录 Docker 注册表。这需要通过 Travis CI 中的 secrets 配置来完成,以避免在 GitHub 存储库中提交敏感信息:

It's worth repeating: do not commit secrets in your GitHub repo. These techniques can be used for any other required secret.
  1. Install the travis command line using gem. This assumes that you have gem installed on your system (Ruby 1.93 or later). If you don't, check the installation instructions (https://github.com/travis-ci/travis.rb#installation):
$ gem install travis
  1. Log in to Travis:
travis login --pro

  1. Create a secure variable with the Docker Hub username:
$ travis encrypt --com DOCKER_USERNAME="<your user name>"
  1. You'll see output similar to the following:
secure: ".... encrypted data ...."
  1. Then, you need to add the encrypted data to the environment variables, as follows:
env:
  global:
    - DOCKER_COMPOSE_VERSION=1.23.2
    - secure: ".... encrypted data ...."
  1. Now, note the new global section and repeat step 3 with the Docker Hub password:
$ travis encrypt --com DOCKER_PASSWORD="<password>"
  1. Add another secure variable, after the first one:
env:
  global:
    - DOCKER_COMPOSE_VERSION=1.23.2
    - secure: ".... encrypted data ...."
    - secure: ".... encrypted data ...."

此操作创建两个环境变量,在构建期间可用。别担心——它们不会显示在日志中:

Setting environment variables from .travis.yml
$ export DOCKER_COMPOSE_VERSION=1.23.2
$ export DOCKER_PASSWORD=[secure]
$ export DOCKER_USERNAME=[secure]

我们现在可以在 before_install 部分添加正确的登录命令,以便 Docker 服务可以连接和推送图像:

before_install:
  ...
  - echo "Login into Docker Hub"
  - echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin

下一阶段是构建和标记生成的图像。

Tagging and pushing builds

以下代码将添加一个新阶段,该阶段将构建、标记并最终将结果推送到 Docker 注册表:

jobs:
  include:
    ...
    - stage: push
      script:
      - cd Chapter04
      - docker-compose build server
      - docker tag thoughts_server:latest <registry>/thoughts-backend:$TRAVIS_BRANCH

第一部分为服务器构建最终映像并使用分支名称对其进行标记。为了部署它,我们将添加一个 deploy 部分:

- stage: push
  script:
  ...
  - docker tag thoughts_server:latest <registry>/thoughts-backend:$TRAVIS_BRANCH
  deploy:
  - provider: script
    script: docker push <registry>/thoughts-backend:$TRAVIS_BRANCH
    on:
      branch: master 

当分支为 master 时,deploy 部分将执行 script 命令。现在,我们的构建还将生成最终图像并推送它。这将确保我们的注册表在我们的主分支中获得最新版本。

我们可以添加更多的 deploy 条件来推送标签;例如,如果我们创建一个新的 Git 标签,我们可以使用适当的标签推送结果图像。

Remember that tags, as discussed in the previous chapter, are a way to mark an image as significant. Normally, this will mean it's ready for some to be used outside automatic tests, for example, in deployment.

我们可以将标签添加到 deploy 部分:

      deploy:
      - provider: script
        script: docker push <registry>/thoughts-backend:$TRAVIS_BRANCH
        on:
          branch: master 
      - provider: script
        script: docker push <registry>/thoughts-backend:$TRAVIS_TAG
        on:
          tags: True

Note that here we push whether the branch is the master or there's a defined tag, as both conditions won't be matched.

您可以在此处查看完整的部署文档:https://docs.travis-ci.com/user/部署。我们已经介绍了 script 提供程序,这是一种创建我们自己的命令的方式,但它提供对 Heroku、PyPI(在创建 Python 包的情况下)和 AWS S3 等提供程序的支持。

Tagging and pushing every commit

可以将每个构建的映像推送到由其 Git SHA 标识的注册表。当进行中的工作可以共享用于演示目的、测试等时,这会很有用。

为此,我们需要在 before_install 部分中使用 Git SHA 创建一个环境变量:

before_install:
  ...
  - export GIT_SHA=`git rev-parse --short HEAD`
  - echo "Building commit $GIT_SHA"

push 部分然后添加图像的标签和推送:

- stage: push
  script:
  - cd Chapter04
  - docker-compose build server
  - docker tag thoughts_server:latest <registry>/thoughts-backend:$GIT_SHA
  - docker push <registry>/thoughts-backend:$GIT_SHA
  - docker tag thoughts_server:latest <registry>/thoughts-backend:$TRAVIS_BRANCH

由于此操作发生在 deploy 部分之前,因此它将在到达此部分的每个构建上生成。

This method will produce a lot of tags. Depending on how your registry manages them, that may be costly. Be sure that it is a sensible thing to do.

Keep in mind that this same approach can be used for other conditional pushes.

请注意,注册表需要根据您自己的注册表详细信息进行调整。如果您克隆示例存储库,则需要更改后者。

Summary

在本章中,我们介绍了持续集成实践并探讨了 Docker 如何帮助实现它们。我们还研究了如何设计一个管道,以确保我们的代码始终遵循高标准并尽快检测到偏差。在 GitHub 中使用 Git 分支和拉取请求也随之而来,因为我们可以确定何时可以将代码合并到主分支中并进行部署。

然后我们介绍了 Travis CI 作为与 GitHub 一起使用以实现持续集成的好工具,并讨论了它的特性。我们学习了如何在 Travis CI 中创建管道,从创建 .travis.yml 文件,如何配置作业,如何使构建推送经过验证的 Docker 镜像到我们的 Docker 注册表,以及如何被通知。

我们描述了如何加速并行运行部分,以及如何将值设置为机密。我们还配置了 GitHub,以确保 Travis CI 管道在将新代码合并到我们的主分支之前成功运行。

在下一章中,我们将学习基本的 Kubernetes 操作和概念。

Questions

  1. Does increasing the number of deployments reduce their quality?
  2. Describe what a pipeline is.
  3. How do we know if our main branch can be deployed?
  4. What is the main configuration source for Travis CI?
  5. When will Travis CI send a notification email by default?
  6. How can we avoid merging a broken branch into our main branch?
  7. Why should we avoid storing secrets in a Git repo?

Further reading

要了解有关持续集成和其他工具的更多信息,您可以查看持续集成和交付实践一书(https://www.packtpub.com/eu/virtualization-and-cloud/hands-continuous-integration-and-delivery ),它不仅涵盖 Travis CI,还涵盖其他工具,例如 Jenkins 和 CircleCI。如果您想深入了解 GitHub 及其所有可能性,包括如何有效协作以及它支持的不同工作流程,请在 GitHub Essentials (https://www.packtpub.com/eu/web-development/github-essentials-second-edition)。