简介
本指南将向您展示如何创建一个持续集成 (CI) 工作流,用于构建和测试 Ruby 应用程序。如果您的 CI 测试通过,您可能希望部署代码或发布 gem。
先决条件
我们建议您具备 Ruby、YAML、工作流配置选项以及如何创建工作流文件的基本了解。更多信息,请参阅
使用 Ruby 工作流模板
为了快速入门,请将工作流模板添加到存储库的 .github/workflows
目录中。
GitHub 提供了一个适用于大多数 Ruby 项目的 Ruby 工作流模板。本指南后续部分将提供如何自定义此工作流模板的示例。
-
在 GitHub 上,导航到存储库的主页。
-
在存储库名称下方,点击 Actions.
-
如果您存储库中已存在工作流,请点击**新建工作流**。
-
“选择工作流”页面显示了一系列推荐的工作流模板。搜索“ruby”。
-
点击**持续集成**筛选工作流选择。
-
在“Ruby”工作流上,点击**配置**。
-
根据需要编辑工作流。例如,更改您要使用的 Ruby 版本。
注意
- 此工作流模板包含一个未经 GitHub 认证的操作。第三方提供的操作受单独的服务条款、隐私政策和支持文档的约束。
- 如果您使用第三方操作,则应使用提交 SHA 指定的版本。如果操作进行了修改,并且您想使用较新版本,则需要更新 SHA。您可以通过引用标签或分支来指定版本,但是操作可能会在没有警告的情况下更改。有关更多信息,请参阅“GitHub Actions 安全加固”。
-
点击**提交更改**。
ruby.yml
工作流文件将添加到存储库的.github/workflows
目录中。
指定 Ruby 版本
指定 Ruby 版本最简单的方法是使用 GitHub 上 Ruby 组织提供的 ruby/setup-ruby
操作。此操作会将任何受支持的 Ruby 版本添加到工作流中每个作业运行的 PATH
中。有关更多信息和可用的 Ruby 版本,请参阅 ruby/setup-ruby
。
使用 Ruby 的 ruby/setup-ruby
操作是在 GitHub Actions 中使用 Ruby 的推荐方法,因为它确保了在不同运行器和不同 Ruby 版本之间的一致行为。
setup-ruby
操作以 Ruby 版本作为输入,并在运行器上配置该版本。
steps:
- uses: actions/checkout@v4
- uses: ruby/setup-ruby@ec02537da5712d66d4d50a0f33b7eb52773b5ed1
with:
ruby-version: '3.1' # Not needed with a .ruby-version file
- run: bundle install
- run: bundle exec rake
或者,您可以将 .ruby-version
文件检入存储库的根目录,setup-ruby
将使用该文件中定义的版本。
使用多个 Ruby 版本进行测试
您可以添加矩阵策略,以使用多个 Ruby 版本运行工作流。例如,您可以针对 3.1、3.0 和 2.7 版本的最新修补程序版本测试您的代码。
strategy:
matrix:
ruby-version: ['3.1', '3.0', '2.7']
ruby-version
数组中指定的每个 Ruby 版本都会创建一个运行相同步骤的作业。${{ matrix.ruby-version }}
上下文用于访问当前作业的版本。有关矩阵策略和上下文的更多信息,请参阅“GitHub Actions 的工作流语法”和“访问有关工作流运行的上下文信息”。
包含矩阵策略的完整更新工作流可能如下所示
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# GitHub recommends pinning actions to a commit SHA.
# To get a newer version, you will need to update the SHA.
# You can also reference a tag or branch, but the action may change without warning.
name: Ruby CI
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
ruby-version: ['3.1', '3.0', '2.7']
steps:
- uses: actions/checkout@v4
- name: Set up Ruby ${{ matrix.ruby-version }}
uses: ruby/setup-ruby@ec02537da5712d66d4d50a0f33b7eb52773b5ed1
with:
ruby-version: ${{ matrix.ruby-version }}
- name: Install dependencies
run: bundle install
- name: Run tests
run: bundle exec rake
使用 Bundler 安装依赖项
setup-ruby
操作将自动为您安装 bundler。版本由您的 gemfile.lock
文件确定。如果您的 lockfile 中不存在版本,则将安装最新的兼容版本。
steps:
- uses: actions/checkout@v4
- uses: ruby/setup-ruby@ec02537da5712d66d4d50a0f33b7eb52773b5ed1
with:
ruby-version: '3.1'
- run: bundle install
缓存依赖项
setup-ruby
操作提供了一种在运行之间自动处理 gem 缓存的方法。
要启用缓存,请设置以下内容。
steps:
- uses: ruby/setup-ruby@ec02537da5712d66d4d50a0f33b7eb52773b5ed1
with:
bundler-cache: true
这将配置 bundler 将您的 gem 安装到 vendor/cache
。对于工作流的每次成功运行,GitHub Actions 将缓存此文件夹并在后续工作流运行中重新下载。gemfile.lock
的哈希值和 Ruby 版本将用作缓存密钥。如果您安装了任何新 gem 或更改了版本,则缓存将失效,bundler 将执行全新安装。
在没有 setup-ruby 的情况下进行缓存
为了更好地控制缓存,您可以直接使用 actions/cache
操作。有关更多信息,请参阅“缓存依赖项以加快工作流速度”。
steps:
- uses: actions/cache@v3
with:
path: vendor/bundle
key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
restore-keys: |
${{ runner.os }}-gems-
- name: Bundle install
run: |
bundle config path vendor/bundle
bundle install --jobs 4 --retry 3
如果您使用矩阵构建,则需要将矩阵变量包含在缓存密钥中。例如,如果您为不同的 Ruby 版本 (matrix.ruby-version
) 和不同的操作系统 (matrix.os
) 设置了矩阵策略,则您的工作流步骤可能如下所示
steps:
- uses: actions/cache@v3
with:
path: vendor/bundle
key: bundle-use-ruby-${{ matrix.os }}-${{ matrix.ruby-version }}-${{ hashFiles('**/Gemfile.lock') }}
restore-keys: |
bundle-use-ruby-${{ matrix.os }}-${{ matrix.ruby-version }}-
- name: Bundle install
run: |
bundle config path vendor/bundle
bundle install --jobs 4 --retry 3
矩阵测试您的代码
以下示例矩阵测试了 Ubuntu 和 macOS 上所有稳定版本和 MRI、JRuby 和 TruffleRuby 的头部版本。
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# GitHub recommends pinning actions to a commit SHA.
# To get a newer version, you will need to update the SHA.
# You can also reference a tag or branch, but the action may change without warning.
name: Matrix Testing
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ${{ matrix.os }}-latest
strategy:
fail-fast: false
matrix:
os: [ubuntu, macos]
ruby: [2.5, 2.6, 2.7, head, debug, jruby, jruby-head, truffleruby, truffleruby-head]
continue-on-error: ${{ endsWith(matrix.ruby, 'head') || matrix.ruby == 'debug' }}
steps:
- uses: actions/checkout@v4
- uses: ruby/setup-ruby@ec02537da5712d66d4d50a0f33b7eb52773b5ed1
with:
ruby-version: ${{ matrix.ruby }}
- run: bundle install
- run: bundle exec rake
代码风格检查
以下示例安装 rubocop
并使用它来检查所有文件。有关更多信息,请参阅 RuboCop。您可以 配置 Rubocop 以决定具体的代码风格检查规则。
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# GitHub recommends pinning actions to a commit SHA.
# To get a newer version, you will need to update the SHA.
# You can also reference a tag or branch, but the action may change without warning.
name: Linting
on: [push]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ruby/setup-ruby@ec02537da5712d66d4d50a0f33b7eb52773b5ed1
with:
ruby-version: '2.6'
- run: bundle install
- name: Rubocop
run: rubocop -f github
指定 -f github
表示 RuboCop 输出将采用 GitHub 的注释格式。任何代码风格检查错误都将在引入它们的拉取请求的**已更改文件**选项卡中内联显示。
发布 Gem
您可以配置您的工作流,以便在您的 CI 测试通过时将您的 Ruby 包发布到您想要的任何包注册表。
您可以使用存储库机密存储发布包所需的任何访问令牌或凭据。以下示例创建并发布了一个包到 GitHub Package Registry
和 RubyGems
。
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# GitHub recommends pinning actions to a commit SHA.
# To get a newer version, you will need to update the SHA.
# You can also reference a tag or branch, but the action may change without warning.
name: Ruby Gem
on:
# Manually publish
workflow_dispatch:
# Alternatively, publish whenever changes are merged to the `main` branch.
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build:
name: Build + Publish
runs-on: ubuntu-latest
permissions:
packages: write
contents: read
steps:
- uses: actions/checkout@v4
- name: Set up Ruby 2.6
uses: ruby/setup-ruby@ec02537da5712d66d4d50a0f33b7eb52773b5ed1
with:
ruby-version: '2.6'
- run: bundle install
- name: Publish to GPR
run: |
mkdir -p $HOME/.gem
touch $HOME/.gem/credentials
chmod 0600 $HOME/.gem/credentials
printf -- "---\n:github: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
gem build *.gemspec
gem push --KEY github --host https://rubygems.pkg.github.com/${OWNER} *.gem
env:
GEM_HOST_API_KEY: "Bearer ${{secrets.GITHUB_TOKEN}}"
OWNER: ${{ github.repository_owner }}
- name: Publish to RubyGems
run: |
mkdir -p $HOME/.gem
touch $HOME/.gem/credentials
chmod 0600 $HOME/.gem/credentials
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
gem build *.gemspec
gem push *.gem
env:
GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"