自定义构建

Travis CI 构建配置和设置 #

Travis CI 上的构建主要通过存储在存储库中 .travis.yml 文件中的构建配置进行配置。这使得您的配置能够进行版本控制并具有灵活性。

对于高级用例,主构建配置文件 .travis.yml 可以使用构建配置导入功能导入其他共享配置源。

有关 Travis CI 构建配置格式的详细信息,请参阅我们的Travis CI 构建配置参考。有关 Travis CI 使用 YAML 作为语言来描述构建配置的更多信息,请参阅此处

其他功能可以通过存储库的设置进行控制,可以通过 Travis CI UI 或 Travis CI 命令行客户端进行控制。

构建超时 #

测试套件或构建脚本挂起是很常见的。Travis CI 对每个作业都有特定的时间限制,并且会在以下情况下停止构建并在构建日志中添加错误消息

  • 当作业在 10 分钟内未产生任何日志输出时。
  • 当公共存储库上的作业花费超过 50 分钟时。
  • 当私有存储库上的作业花费超过 120 分钟时。

构建可能挂起的常见原因

  • 等待键盘输入或其他形式的人机交互
  • 并发问题(死锁、活锁等)
  • 安装需要很长时间才能编译的原生扩展

构建没有超时;构建将运行所需的时间以完成所有作业,但如果任何作业达到超时限制,则会立即停止。

构建生命周期 #

构建生命周期文档现在有自己的页面了。

限制并发作业 #

最大并发作业数取决于系统的总负载,但您可能希望设置特定限制的一种情况是

  • 如果您的构建依赖于外部资源,并且可能与并发作业发生竞争条件。

您可以在每个存储库的设置窗格中设置最大并发作业数。

Settings -> Limit concurrent builds

或使用命令行客户端

$ travis settings maximum_number_of_builds --set 1

仅构建最新提交 #

如果您只对构建每个分支上的最新提交感兴趣,您可以使用此新功能自动取消队列中尚未运行的旧构建。现有构建将被允许完成。

“自动取消设置”位于每个存储库的“设置”选项卡中,您可以分别启用它以

  • “自动取消分支构建” - 取消分支中排队的构建,并显示在存储库的“构建历史记录”选项卡中。

  • “自动取消拉取请求构建” - 取消拉取请求的排队构建(您的更改/功能分支与其目标的未来合并结果),并显示在存储库的“拉取请求”选项卡中。

Auto cancellation setting

例如,在以下屏幕截图中,我们将提交 ca31c2b 推送到分支 MdA-fix-notice,而构建 #226 和 #227 处于排队状态。启用自动取消功能后,构建 #226 和 #227 会自动取消

Auto cancellation example

Git 克隆深度 #

请注意,如果您使用深度 1 并且有一个作业队列,当您推送新的提交时,Travis CI 不会构建队列中的提交。

您可以在 .travis.yml 中设置克隆深度

git:
  depth: 3

您还可以使用以下方法完全删除 --depth 标志

git:
  depth: false

某些存储库操作,例如常见的自动化代码审查脚本(例如 Ruby 的 Pronto),可能会由于有限的 git 克隆深度而失败,无法访问存储库中的所有对象。删除深度标志或运行 git fetch --unshallow 可能会解决此问题。

Git 克隆静默 #

默认情况下,Travis CI 在克隆存储库时不会使用静默标志 (-q)。如果要避免日志文件大小限制,或者只是不需要包含它,则启用静默标志可能很有用。

您可以在 .travis.yml 中启用静默标志

git:
  quiet: true

Git 子模块 #

Travis CI 默认情况下会克隆 Git 子模块。要避免这种情况,请设置

git:
  submodules: false

Git LFS #

使用 GitHub 进行身份验证 #

我们建议使用只读 GitHub OAuth 令牌在使用Git LFS时进行身份验证

before_install:
- echo -e "machine github.com\n  login $GITHUB_TOKEN" > ~/.netrc
- git lfs pull

连接到私有存储库时需要此身份验证,并且可以防止连接到开源存储库时出现速率限制。

LFS 目前不支持部署密钥,因此您应如上例所示使用 GitHub OAuth 令牌进行身份验证。

使用 Bitbucket 进行身份验证 #

我们建议使用只读 Bitbucket OAuth 令牌在使用Git LFS时进行身份验证

before_install:
- echo -e "machine bitbucket.com\n  login $BITBUCKET_TOKEN" > ~/.netrc
- git lfs pull

连接到私有存储库时需要此身份验证,并且可以防止连接到开源存储库时出现速率限制。

LFS 目前不支持部署密钥,因此您应如上例所示使用 Bitbucket OAuth 令牌进行身份验证。

使用 GitLab 进行身份验证 #

我们建议使用只读 GitLab OAuth 令牌在使用Git LFS时进行身份验证

before_install:
- echo -e "machine gitlab.com\n  login $GITLAB_TOKEN" > ~/.netrc
- git lfs pull

连接到私有存储库时需要此身份验证,并且可以防止连接到开源存储库时出现速率限制。

LFS 目前不支持部署密钥,因此您应如上例所示使用 GitLab OAuth 令牌进行身份验证。

使用 Assembla 进行身份验证 #

我们建议使用只读 Assembla OAuth 令牌在使用Git LFS时进行身份验证

before_install:
- echo -e "machine assembla.com\n  login $ASSEMBLA_TOKEN" > ~/.netrc
- git lfs pull

连接到私有存储库时需要此身份验证,并且可以防止连接到开源存储库时出现速率限制。

LFS 目前不支持部署密钥,因此您应如上例所示使用 Assembla OAuth 令牌进行身份验证。

Linux #

我们的 Ubuntu Trusty、Xenial 和 Bionic 镜像默认支持Git LFS

macOS #

通过 brew 安装 git-lfs 是在macOS中获取 Git LFS 的推荐方法。

os: osx

before_install:
- brew install git-lfs

before_script:
- git lfs pull

Git LFS 跳过涂抹 #

git clone 过程中,GitHub 会限制 Git LFS 请求的速率。如果您遇到速率限制问题,可以在初始 git clone 期间跳过获取 git-lfs 文件(相当于git lfs smudge --skip),并在构建的 before_install 阶段下载这些资源。为此,您可以在 .travis.yml 中使用以下配置

git:
  lfs_skip_smudge: true

Git 稀疏检出 #

Travis CI 支持 git稀疏检出功能。

要稀疏克隆您的存储库,请添加

git:
  sparse_checkout: skip-worktree-map-file

其中 skip-worktree-map-file 是当前仓库中现有文件的路径,其包含您希望放入 $GIT_DIR/info/sparse-checkout 文件中的数据,Git 文档中描述了该文件的格式

Git 行尾转换控制 #

Travis CI 使用平台相关的 core.autocrlf 行为克隆仓库。可以通过 .travis.yml 文件中的 autocrlf 属性修改此行为。有效值为 truefalseinput

要克隆仓库而不进行行尾转换,请添加

git:
  autocrlf: input

这等效于在克隆仓库之前使用 git config --global core.autocrlf input

禁用 git clone #

在某些工作流程中,例如 构建阶段,跳过自动 git clone 步骤可能会有益。

您可以通过添加以下内容来实现:

git:
  clone: false

请注意,如果使用此选项,则 TRAVIS_COMMIT_MESSAGE 环境变量将不会被定义。

在某些情况下,当一个仓库同时用于 Linux 和 Windows 时,可能需要设置 core.symlinks 选项。

要执行此操作,请执行以下操作:

git:
  symlinks: true

构建特定分支 #

Travis CI 使用包含触发构建的 Git 提交的分支中的 .travis.yml 文件。使用白名单包含分支,或使用黑名单排除分支。

请注意,在决定将某些分支列入白名单或黑名单时,还需要考虑自动 拉取请求构建

将分支列入白名单或黑名单 #

使用白名单指定要构建的分支,或黑名单指定不想构建的分支

# blocklist
branches:
  except:
  - legacy
  - experimental

# safelist
branches:
  only:
  - master
  - stable

请注意,白名单也会阻止构建带标签的提交。如果您的构建始终以 v1.3 的格式进行标记,则可以使用 正则表达式 将它们全部列入白名单,例如 /^v\d+\.\d+(\.\d+)?(-\S*)?$/

如果同时使用白名单和黑名单,则白名单优先。默认情况下,gh-pages 分支不会被构建,除非您将其添加到白名单中。

要构建所有分支,请执行以下操作:

branches:
  only:
  - gh-pages
  - /.*/

请注意,由于历史原因,.travis.yml 需要存在于项目所有活动分支上。

使用正则表达式 #

您可以使用正则表达式将分支列入白名单或黑名单

branches:
  only:
  - master
  - /^deploy-.*$/

分支列表中任何用 / 包围的名称都被视为正则表达式,并且可以包含 Ruby 正则表达式 支持的任何量词、锚点或字符类。

在最后一个 / 后面指定的选项(例如,不区分大小写的匹配的 i)不受支持,但可以内联给出。例如,/^(?i:deploy)-.*$/ 匹配 Deploy-2014-06-01 和以 deploy- 开头的其他分支和标签,不区分大小写。

跳过构建 #

如果您出于任何原因不想为特定提交运行构建,则可以通过提交消息中的命令指示 Travis CI 跳过构建此提交。

该命令应采用以下格式之一:

[<KEYWORD> skip]

[skip <KEYWORD>]

其中 <KEYWORD>citravistravis citravis-citravisci。例如,

[skip travis] Update README

请注意,如果多个提交一起推送,则跳过命令仅在 HEAD 提交的提交消息中存在时才有效。

构建矩阵 #

您还可以为构建矩阵定义排除项

jobs:
  exclude:
  - rvm: 1.9.3
    gemfile: gemfiles/Gemfile.rails-2.3.x
    env: ISOLATED=true
  - rvm: jruby
    gemfile: gemfiles/Gemfile.rails-2.3.x
    env: ISOLATED=true

所有构建矩阵目前都限制为最多 **200 个作业**,适用于私有和公共仓库。如果您使用的是开源计划,请记住 Travis CI 向社区免费提供此服务。因此,请仅指定您实际需要的矩阵。

命名矩阵中的作业 #

您可以为矩阵中的特定作业定义名称。我们建议使用唯一的作业名称,但不会强制执行(尽管这将来可能会改变)。在 matrix.include 部分定义的作业可以如下赋予作业名称:

language: python
jobs:
  include:
  - name: "3.5 Unit Test"
    python: "3.5"
    env: TEST_SUITE=suite_3_5_unit
  - name: "3.5 Integration Tests"
    python: "3.5"
    env: TEST_SUITE=suite_3_5_integration
  - name: "pypy Unit Tests"
    python: "pypy"
    env: TEST_SUITE=suite_pypy_unit
script: ./test.py $TEST_SUITE

由矩阵扩展生成的作业不能赋予名称属性。

排除作业 #

如果要从构建矩阵中排除的作业共享相同的矩阵参数,则可以仅指定这些参数并省略不同的部分。

假设您有

language: ruby
rvm:
- 1.9.3
- 2.0.0
- 2.1.0
env:
- DB=mongodb
- DB=redis
- DB=mysql
gemfile:
- Gemfile
- gemfiles/rails4.gemfile
- gemfiles/rails31.gemfile
- gemfiles/rails32.gemfile

这将生成一个 3×3×4 的构建矩阵。要排除所有 rvm 值为 2.0.0 gemfile 值为 Gemfile 的作业,您可以编写

jobs:
  exclude:
  - rvm: 2.0.0
    gemfile: Gemfile

这等效于

jobs:
  exclude:
  - rvm: 2.0.0
    gemfile: Gemfile
    env: DB=mongodb
  - rvm: 2.0.0
    gemfile: Gemfile
    env: DB=redis
  - rvm: 2.0.0
    gemfile: Gemfile
    env: DB=mysql

使用 env 值排除作业 #

使用 env 值排除作业时,该值必须完全匹配。

例如,

language: ruby
rvm:
- 1.9.3
- 2.0.0
- 2.1.0
env:
- DB=mongodb SUITE=all
- DB=mongodb SUITE=compact
- DB=redis
- DB=mysql
jobs:
  exclude:
    - rvm: 1.9.3
      env: DB=mongodb

定义了一个 3×4 的矩阵,因为 env 值与矩阵中定义的任何作业都不匹配。

要排除所有设置了 DB=mongodb 的 Ruby 1.9.3 作业,请编写

language: ruby
rvm:
- 1.9.3
- 2.0.0
- 2.1.0
env:
- DB=mongodb SUITE=all
- DB=mongodb SUITE=compact
- DB=redis
- DB=mysql
jobs:
  exclude:
    - rvm: 1.9.3
      env: DB=mongodb SUITE=all # not 'env: DB=mongodb  SUITE=all' or 'env: SUITE=all DB=mongodb'
    - rvm: 1.9.3
      env: DB=mongodb SUITE=compact # not 'env: SUITE=compact DB=mongodb'

显式包含作业 #

也可以使用 matrix.include 将条目包含到矩阵中

jobs:
  include:
  - rvm: ruby-head
    gemfile: gemfiles/Gemfile.rails-3.2.x
    env: ISOLATED=false

这会将特定作业添加到已填充的构建矩阵中。

如果您只想测试依赖项的最新版本以及运行时的最新版本,这将非常有用。

您可以使用此方法创建仅包含特定组合的构建矩阵。例如,以下内容创建一个包含 3 个作业的构建矩阵,该矩阵为每个 Python 版本运行测试套件

language: python
jobs:
  include:
  - python: "2.7"
    env: TEST_SUITE=suite_2_7
  - python: "3.8"
    env: TEST_SUITE=suite_3_8
  - python: "pypy"
    env: TEST_SUITE=suite_pypy
script: ./test.py $TEST_SUITE

显式包含的作业继承数组中的第一个值 #

显式包含的作业将继承定义的扩展键的第一个值。

在此包含 3 个作业的 Python 构建矩阵的示例中,matrix.include 中的每个作业都将 python 值设置为 '3.8'。您可以为特定条目显式设置 python 版本

language: python
python:
  - '3.8'
  - '3.7'
  - '2.7'
jobs:
  include:
    - python: '3.8' # this is not strictly necessary
      env: EXTRA_TESTS=true
    - python: '3.7'
      env: EXTRA_TESTS=true
script: env $EXTRA_TESTS ./test.py $TEST_SUITE

允许失败的作业 #

您可以在构建矩阵中定义允许失败的作业。

允许失败的作业是指构建矩阵中允许失败的作业,而不会导致整个构建失败。例如,这使您可以添加实验性和准备性构建,以针对您尚未准备好正式支持的运行时版本或配置进行测试。

在构建矩阵中将允许失败的作业定义为键值对

jobs:
  allow_failures:
  - rvm: 1.9.3

有条件地允许作业失败 #

允许失败的作业可以使用键 if 包含 条件

例如,以下内容将仅允许在 master 分支上使用 rvm: 1.9.3 的作业失败

jobs:
  allow_failures:
  - rvm: 1.9.3
    if: branch = master

使用 allow_failures 匹配作业 #

当根据 allow_failures 中给出的定义匹配作业时,allow_failures 中条目上指定的所有属性都必须完全匹配,并且 allow_failures 元素中的所有键都必须存在于构建矩阵的顶层(即,不在 matrix.include 中)。

allow_failures 示例 #

考虑

language: ruby

rvm:
- 2.0.0
- 2.1.6

env:
  global:
  - SECRET_VAR1=SECRET1
  jobs:
  - SECRET_VAR2=SECRET2

jobs:
  allow_failures:
    - env: SECRET_VAR1=SECRET1 SECRET_VAR2=SECRET2

在这里,没有作业被允许失败,因为没有作业的 env 值为 SECRET_VAR1=SECRET1 SECRET_VAR2=SECRET2

接下来,

language: php
php:
- 5.6
- 7.0
jobs:
  include:
  - php: 7.0
    env: KEY=VALUE
  allow_failures:
  - php: 7.0
    env: KEY=VALUE

如果没有顶层 env,则不会有作业被允许失败。

快速完成 #

如果构建矩阵中的一些作业被允许失败,则在这些作业完成之前,构建不会被标记为已完成。

要尽快将构建标记为已完成,请将 fast_finish: true 添加到 .travis.yml 文件的 matrix 部分,如下所示:

jobs:
  fast_finish: true

现在,构建结果将在所有必需的作业完成后立即确定,并根据这些结果确定,而其余的 allow_failures 作业将继续运行。

安装第二种编程语言 #

如果您需要在当前构建环境中安装第二种编程语言,可以在构建的 before_install 阶段执行此操作。

例如,您可以使用以下方法在 Python 构建中安装自定义版本的 Ruby:

language: python

before_install:
- rvm install 2.1.5

您还可以像这样在 Node.js 构建中安装自定义 PHP 版本:

language: node_js

before_install:
- phpenv global 7.0

还可以使用其他语言安装方法,例如 apt-get、Python 的 pyenv、Node.js 的 nvm 等。

实现复杂的构建步骤 #

如果您有一个复杂的构建环境,难以在 .travis.yml 中配置,请考虑将步骤移动到单独的 shell 脚本中。该脚本可以是仓库的一部分,并且可以轻松地从 .travis.yml 中调用。

有关如何执行此操作的更多信息,请参阅 复杂的构建命令

自定义主机名 #

如果您的构建需要设置自定义主机名,则可以在 .travis.yml 中指定单个主机或主机列表。Travis CI 将自动在 /etc/hosts 中为 IPv4 和 IPv6 设置主机名。

addons:
  hosts:
  - travis.test
  - joshkalderimis.com

我可以使用哪些仓库提供商或版本控制系统? #

travis-ci.com 上构建和测试托管在 GitHub 上的开源和私有仓库。Travis CI 还可以与 Atlassian BitbucketGitLab 和 Assembla (https://www.assembla.com/) 集成。

Travis CI 目前不支持托管在其他版本控制系统(如 Mercurial)上的 git 仓库。

.travis.yml 中可以使用哪个 YAML 版本? #

Travis CI 使用 Ruby libYAML 库,这意味着您的 .travis.yml 必须是有效的 YAML 1.1

故障排除 #

查看 常见构建问题 列表。