构建 Ruby 项目
本指南涵盖的内容 #
有关语言版本和其他构建环境特定信息,请访问我们的参考页面
本指南的其余部分介绍了在 Travis CI 上配置 Ruby 项目。如果您是 Travis CI 的新手,请先阅读我们的 教程 和 构建配置 指南。
指定 Ruby 版本和实现 #
Travis CI 上的 Ruby 环境使用 RVM 提供许多 Ruby 实现、版本甚至补丁级别。
要指定它们,请在您的 .travis.yml
文件中使用 rvm:
键
language: ruby
rvm:
- 2.5
- 2.6
- jruby
- truffleruby
请注意,
rvm:
键仅在 Ruby 构建环境中可用,而不在包含 ruby 实现的其他镜像中可用。
随着我们升级 RVM 和 Rubies,2.2
或 jruby
之类的别名会指向不同的确切版本和补丁级别。
使用 .ruby-version
#
如果 ruby 版本未由 rvm
键指定,则 Travis CI 会使用存储库根目录中 .ruby-version
文件中指定的版本(如果存在)。
Rubinius #
如果您使用的是 macOS 或 Trusty 环境,您还可以使用 Rubinius。要使用 Rubinius 进行测试,请将 rbx-X
或 rbx-X.Y.Z
添加到您的 .travis.yml
中,其中 X.Y.Z 指定了 http://rubies.travis-ci.org/rubinius 上列出的 Rubinius 版本。
language: ruby
dist: trusty
rvm:
- rbx-3
TruffleRuby #
要使用 TruffleRuby 进行测试,只需将 truffleruby
或 truffleruby-VERSION
添加到您的 .travis.yml
中
language: ruby
rvm:
- truffleruby # latest release
# or
- truffleruby-19.2.0 # specific version
请参阅 TruffleRuby 版本 页面以获取版本列表。请在 GitHub 上提交任何问题。
JRuby:不支持 C 扩展 #
请注意,Travis CI 上的 JRuby 不支持 C 扩展。这样做是为了让开发人员注意他们的项目可能存在不应在生产环境中使用 JRuby 的依赖项。在 JRuby 上使用 C 扩展在技术上是可行的,但在性能和稳定性方面并不是一个好主意,我们认为像 Travis CI 这样的持续集成服务应该重点突出这一点。
因此,如果您想针对 JRuby 运行 CI,请检查您的 Gemfile 是否考虑了 JRuby。如今,大多数流行的 C 扩展也有 Java 实现(json gem、nokogiri、eventmachine、bson gem)或 Java 替代方案(例如,基于 JDBC 的 MySQL、PostgreSQL 驱动程序等)。
默认构建脚本 #
在 Ruby 项目中,默认构建脚本是 rake
。将 rake
添加到 Gemfile 中的 :test
组。
构建配置参考 #
您可以在我们的 Travis CI 构建配置参考 中找到有关 Ruby 构建配置格式的更多信息。
依赖项管理 #
Bundler #
如果项目根目录中存在 Gemfile,或者构建矩阵中指定了 Gemfile,则 Travis CI 会使用 Bundler 安装 Ruby 项目的依赖项。
bundle install --jobs=3 --retry=3
如果项目根目录中存在 Gemfile.lock,我们会添加 --deployment
标志。
如果您想使用不同的方法来处理 Ruby 项目的依赖项,您可以覆盖 install
命令。
install: gem install rails
默认情况下,gem 会安装到项目根目录中的 vendor/bundle。
Bundler 2.0 #
2019 年 1 月 3 日,Bundler 团队发布了 Bundler 2.0,它需要 Ruby 2.3+。随后的 2.0.1 版本将所需的 RubyGems 版本降至 2.5.0,该版本在 Ruby 2.3+ 上默认可用。
因此,无需为 Bundler 2 更新 RubyGems。
TravisCI 默认使用 Bundler 1。如果您的 Gemfile.lock
包含 BUNDLED WITH 1.x
部分(或没有此部分),则默认行为就足够了,无需进行任何更改。
如果您发现构建由于“bundler 未安装”错误而失败,或者想要使用 Bundler 2.0,请尝试以下解决方案之一
-
如果您使用的是 Ruby 2.3 或更高版本,并且希望升级到 Bundler 2.0,请在您的
.travis.yml
中使用以下内容before_install: - gem install bundler
-
如果您使用的是低于 2.6 版本的 Ruby,并且想要使用 Bundler 2.x,请确保升级到更新版本的 RubyGems。在与较旧版本的 Ruby 捆绑在一起的 RubyGems 的默认版本中,
Gemfile.lock
中的 Bundler 版本必须与正在使用的版本完全匹配,否则会出错。在更新版本的 RubyGems 中修复了此问题。before_install: - yes | gem update --system --force - gem install bundler
由于涉及较旧版本的 RubyGems 与一个错误的 binstub 捆绑在一起的另一个问题,该问题会提示用户进行交互式确认,因此有必要将
yes
管道到gem update --system
命令中。 -
如果您使用的是 Ruby 2.3.x,但希望明确保留在 Bundler 1.x 上(例如,出于依赖项原因,例如 Rails 4.2.x),请编写
before_install: - gem uninstall -v '>= 2' -i $(rvm gemdir)@global -ax bundler || true - gem install bundler -v '< 2'
上面的
gem uninstall
命令会删除在 RVM 安装 Ruby 期间安装到 RVM 的“全局”gemset 中的任何 Bundler 2.x,该 gemset 将被选为默认的bundle
命令。我们忽略了该命令的失败,因为失败最有可能意味着没有匹配的 Bundler 版本可以卸载。
您的构建配置可能需要结合使用这些解决方法。
缓存 Bundler #
Bundler 安装可能需要一段时间,从而减慢构建速度。您可以告诉 Travis CI 缓存已安装的捆绑包。
在您的第一个构建中,我们会预热缓存。在第二个构建中,我们会拉取缓存,使 bundle install
仅需几秒钟即可运行。
通过排除非必需依赖项来加速构建 #
许多项目在它们的默认 gem 集中包含像 ruby-debug
、unicorn
或 newrelic_rpm
这样的库。
这会大大减慢安装过程,并且通常在运行测试时不需要这些库。这也包括编译本机代码的库,从而使安装和整体测试时间更长。
最重要的是,您只需要在生产环境中使用的库(例如 Unicorn、New Relic 库等),这些库会隐式地拉取 ruby_core_source
或 linecache19
,当 Travis CI 升级 Ruby 版本和补丁级别时,这些库会失败。
对于您只在生产环境中需要的 gem(例如 Unicorn、New Relic 库等),情况也是如此。
您可以通过将这些库移动到 Gemfile 中的单独部分(例如 production
)来加快安装过程。
group :production do
gem 'unicorn'
gem 'newrelic_rpm'
end
调整您的 Bundler 参数以显式排除此组
bundler_args: --without production
享受更快的构建速度,这也减少了编译问题的可能性。
自定义 Bundler 参数和 Gemfile 位置 #
默认的 Gemfile 位置是项目根目录下的 Gemfile
。
要指定自定义 Gemfile 名称或位置
gemfile: gemfiles/Gemfile.ci
如果您以这种方式指定 Gemfile 的位置,则如果找不到该文件,构建将失败。
您可以将 额外参数 传递给 bundle install
bundler_args: --binstubs
针对依赖项的多个版本进行测试 #
许多项目需要针对 Rack、EventMachine、HAML、Sinatra、Ruby on Rails 等多个版本的依赖项进行测试。
要针对依赖项的多个版本进行测试
- 在项目的仓库根目录中创建一个用于存放 Gemfile 的目录,例如
./gemfiles
。 - 向其中添加一个或多个 Gemfile。
- 在您的
.travis.yml
中设置gemfile
键。
Thoughtbot 的 Paperclip 针对多个 ActiveRecord 版本进行了测试
gemfile:
- gemfiles/rails2.gemfile
- gemfiles/rails3.gemfile
- gemfiles/rails3_1.gemfile
另一种方法是使用环境变量,并让您的测试运行器使用这些变量。例如,Sinatra 针对多个 Tilt 和 Rack 版本进行了测试
env:
- "rack=1.3.4"
- "rack=master"
- "tilt=1.3.3"
- "tilt=master"
ChefSpec 针对多个 Chef 版本进行了测试
env:
- CHEF_VERSION=14.3.37
- CHEF_VERSION=13.10.0
- CHEF_VERSION=12.22.5
这种技术通常也用于针对多个数据库、模板引擎、托管服务提供商等进行测试。
$BUNDLE_GEMFILE
环境变量 #
当 gemfile
被定义并且仓库中存在 Gemfile 文件时,我们将定义环境变量 $BUNDLE_GEMFILE
,bundle install
将使用该环境变量来解析依赖项。
如果您需要在一个作业中使用多个 Gemfile,请通过传递 --gemfile=
标志来覆盖 $BUNDLE_GEMFILE
bundle install --gemfile=my_gemfile
JRuby:针对多个 JDK 进行测试 #
通过在您的 .travis.yml
中使用 jdk
键,针对多个 JDK 测试项目。
jdk:
- oraclejdk7
- openjdk7
- oraclejdk8
您测试的每个 JDK 都会与所有其他配置产生排列组合,因此为了避免多次运行 CRuby 1.9.3 的测试,您需要添加一些矩阵排除项(在我们 构建配置指南 中有介绍)。
language: ruby
rvm:
- 1.9.2
- jruby-18mode
- jruby-19mode
- jruby-head
jdk:
- openjdk6
- openjdk7
- oraclejdk7
jobs:
exclude:
- rvm: 1.9.2
jdk: openjdk6
- rvm: 1.9.2
jdk: openjdk7
- rvm: 1.9.2
jdk: oraclejdk7
例如,请参阅 travis-support。
使用 Java 10 及更高版本 #
有关使用 OpenJDK 和 OracleJDK 10 及更高版本进行测试的信息,请参阅 Java 文档。
升级 RubyGems #
Travis CI 的 Ruby 环境中安装的 RubyGems 版本取决于最新 Bundler/RubyGems 组合中安装的版本,并尽可能保持最新状态。
如果您需要最新版本的 RubyGems,可以将以下内容添加到您的 .travis.yml
中
before_install:
- gem update --system
- gem --version
要降级到特定版本的 RubyGems
before_install:
- gem update --system 2.1.11
- gem --version
请注意,这会影响您的总体测试时间,因为需要额外的网络下载和安装。