构建阶段

什么是构建阶段? #

构建阶段是一种将作业分组并并行运行每个阶段的作业,但按顺序运行一个阶段的方法。

在最简单和最常见的用例中,您现在可以使一个作业 *仅* 在几个其他并行作业成功完成的情况下运行。

假设您想针对各种运行时(Ruby 或 Node.js)版本测试像 Ruby gem 或 npm 包这样的库,以 并行 方式测试。并且您希望 *仅* 在所有测试都通过并成功完成的情况下发布您的 gem 或包。构建阶段使这成为可能。

当然,还有比这更复杂和更详细的用例。例如,您还可以使用构建阶段在一个阶段的单个作业中预热依赖项缓存,然后在第二个阶段的多个作业中使用该缓存。或者,您可以先生成 Docker 镜像并推送它,然后在多个作业中并行测试它。或者,您可以运行单元测试、部署到暂存环境、运行冒烟测试,然后才部署到生产环境。

构建阶段如何工作? #

构建阶段的概念功能强大且灵活,但简单易用。

阶段将并行运行的作业分组,不同的阶段按顺序运行。

一个阶段是一组可以并行运行的作业。但是,每个阶段都是一个接一个地运行的,并且只有在先前阶段的所有作业都成功完成的情况下才会继续。如果一个阶段中一个作业失败,该阶段中的所有其他作业仍将完成,但后续阶段的所有作业都将被取消,并且构建失败。

您可以在每个阶段配置任意数量的作业,并且可以根据您的交付过程需要创建任意数量的阶段。

在下面的示例中,我们在第一个名为 test 的阶段运行两个作业,然后在第二个名为 deploy 的阶段运行单个第三个作业。

Example screencast

如何定义构建阶段? #

以下是在您的 .travis.yml 文件中设置此构建配置的方法。

jobs:
  include:
    - stage: test
      script: ./test 1
    - # stage name not required, will continue to use `test`
      script: ./test 2
    - stage: deploy
      script: ./deploy

此配置创建了来自屏幕截图的构建。即,它创建了一个包含三个作业的构建,其中两个在第一个阶段(名为 test)中并行启动,而第三个阶段在第二个阶段(名为 deploy)中的作业仅在测试阶段成功完成之后启动。

构建配置参考 #

您可以在我们的 Travis CI 构建配置参考 中找到有关 构建阶段 的构建配置格式的更多信息。

命名您的构建阶段 #

阶段由其名称标识,这些名称由名称和表情符号组成。出于美观原因,阶段名称的第一个字母会自动大写,因此您不必在您的 .travis.yml 文件中处理大写字符串。

此外,您不必在每个作业中都指定名称(如上面的示例所示)。默认阶段是 test。没有阶段名称的作业将分配给先前的阶段名称(如果存在)或默认阶段名称(如果不存在先前的阶段名称)。这意味着,如果您在每个阶段的第一个作业上设置阶段名称,则构建将按预期工作。

例如,以下配置等效于上面的配置,但还在 deploy 阶段添加了第二个部署作业,该作业部署到不同的目标。如您所见,您只需指定一次阶段名称。

jobs:
  include:
    - script: ./test 1 # uses the default stage name "test"
    - script: ./test 2
    - stage: deploy
      script: ./deploy target-1
    - script: ./deploy target-2

在构建阶段中命名您的作业 #

您也可以在构建阶段中命名特定的作业。我们建议使用唯一的作业名称,但没有强制执行(尽管这在将来可能会改变)。在 jobs.include 部分定义的作业可以被赋予一个名为属性,如下所示。

jobs:
  include:
    - stage: "Tests"                # naming the Tests stage
      name: "Unit Tests"            # names the first Tests stage job
      script: ./unit-tests
    - script: ./integration-tests
      name: "Integration Tests"     # names the second Tests stage job
    - stage: deploy
      name: "Deploy to GCP"
      script: ./deploy

构建阶段和构建矩阵扩展 #

矩阵扩展 意味着某些顶级配置键扩展到一个作业矩阵。

例如

rvm:
  - 2.3
  - 2.4
jobs:
  include:
    - stage: deploy
      rvm: 2.4
      env:
        - FOO=foo
      script: ./deploy

这将分别在 Ruby 2.3 和 2.4 上运行两个作业,并将它们分配到默认阶段 test。部署阶段的第三个作业仅在测试阶段成功完成之后启动。

包含在 jobs.include 中的每个作业都继承了定义矩阵维度的数组的第一个值。在上面的示例中,如果没有显式设置 rvm: 2.4,则 included 作业将继承 rvm: 2.3

指定阶段顺序和条件 #

您可以在 stages 部分指定阶段的顺序。

stages:
  - compile
  - test
  - deploy

这主要用于将阶段“预先附加”到矩阵扩展生成的作业将分配到的 test 阶段。

在同一部分,您还可以指定阶段的条件,如下所示。

stages:
  - compile
  - test
  - name: deploy
    if: branch = master

有关指定条件的更多详细信息,请参阅 条件构建、阶段和作业

构建阶段和部署 #

您可以将构建阶段与 部署 相结合。

jobs:
  include:
    - script: ./test 1 # uses the default stage name "test"
    - script: ./test 2
    - stage: deploy
      script: skip     # usually you do not want to rerun any tests
      deploy: &heroku
        provider: heroku
        # ⋮

Travis CI 不会设置或覆盖您的任何脚本,大多数语言都定义了 默认测试脚本。因此,在许多情况下,您可能希望通过指定关键字 skipignore 来覆盖 script 步骤,在其他情况下,您可能希望覆盖其他步骤,例如 install 步骤,该步骤在几种语言上默认运行。

阶段和作业之间的持久化数据 #

重要的是要注意,作业不共享存储,因为每个作业都在新的虚拟机或容器中运行。如果您的作业需要共享文件(例如,使用“测试”阶段的构建工件在随后的“部署”阶段进行部署),您需要使用外部存储机制,例如 S3 和远程 scp 服务器。

请参阅下面的 S3 示例

示例 #

部署到 Heroku #

一个包含 5 个阶段的示例。

  • 两个作业在阶段 1 中并行运行单元测试。
  • 一个作业将应用程序部署到 Heroku 暂存环境。
  • 一个作业测试 Heroku 暂存环境的部署。
  • 一个作业将应用程序部署到 Heroku 生产环境。
  • 一个作业测试 Heroku 生产环境的部署。

您可以在此处找到更多 详细信息

部署到 Rubygems #

此示例有两个构建阶段。

  • 两个作业分别针对 Ruby 2.2 和 2.3 运行测试。
  • 一个作业将 gem 发布到 rubygems.org。

您可以在此处找到更多 详细信息

部署到 NPM #

此示例有两个构建阶段。

  • 四个作业针对 Node 版本 4 到 7 运行测试。
  • 一个作业将包部署(发布)到 NPM。

您可以在此处找到更多 详细信息

部署到 GitHub Releases #

此示例有两个构建阶段。

  • 四个作业运行测试。
  • 一个作业部署到 GitHub Releases。

您可以在此处找到更多 详细信息

将构建阶段与矩阵扩展结合 #

此示例有两个构建阶段。

  • 四个测试作业,从 rvmenv 矩阵键扩展而来。
  • 一个部署作业。

你可以在这里找到更多 详细信息

使用昂贵依赖项预热缓存 #

这使用两个构建阶段来预热具有昂贵依赖项的缓存,并优化测试运行时间。

  • 一个作业,用于为给定分支安装依赖项并预热缓存。
  • 三个使用缓存运行测试的作业。

你可以在这里找到更多 详细信息

共享 Docker 镜像 #

此示例包含 2 个构建阶段。

  • 一个作业构建并推送 Docker 镜像。
  • 两个拉取并测试镜像的作业。

你可以在这里找到更多 详细信息

通过 S3 在作业之间共享文件 #

这使用两个构建阶段,在阶段 2 中共享来自构建阶段 1 的文件。

  • 两个在 S3 上设置文件的作业。
  • 一个使用阶段 1 中两个文件的作业。

你可以在这里找到更多 详细信息

在不同阶段定义不同的步骤 #

此示例包含 2 个构建阶段。

  • 两个针对 Ruby 2.3.1 运行不同测试套件的作业。
  • 一个运行自定义部署脚本的作业,该脚本不需要运行默认的 installscript 步骤。

你可以在这里找到更多 详细信息

使用 YAML 别名定义步骤 #

此示例使用 YAML 别名来定义步骤。它有 3 个构建阶段。

  • 两个针对 Ruby 2.2 和 2.3 运行测试的作业。
  • 一个部署到暂存区的作业。
  • 三个针对暂存区运行测试的作业。

你可以在这里找到更多 详细信息