注意
GitHub Enterprise Server 目前不支持 GitHub 托管的运行器。 可以在 GitHub public roadmap 上查看有关未来支持计划的更多信息。
Introduction
This guide shows you how to create a continuous integration (CI) workflow that builds and tests a Ruby application. If your CI tests pass, you may want to deploy your code or publish a gem.
Prerequisites
We recommend that you have a basic understanding of Ruby, YAML, workflow configuration options, and how to create a workflow file. For more information, see:
Using a Ruby workflow template
若要快速开始使用,请将工作流模板添加到存储库的 .github/workflows
目录。
GitHub provides a workflow template for Ruby that should work for most Ruby projects. The subsequent sections of this guide give examples of how you can customize this workflow template.
-
在 GitHub 上,导航到存储库的主页面。
-
在存储库名称下,单击 “操作”。
-
如果存储库中已有工作流,请单击“新建工作流”。
-
The "Choose a workflow" page shows a selection of recommended workflow templates. Search for "ruby".
-
Filter the selection of workflows by clicking Continuous integration.
-
On the "Ruby" workflow, click Configure.
If you don't find the "Ruby" workflow template, copy the following workflow code to a new file called
ruby.yml
in the.github/workflows
directory of your repository.YAML name: Ruby on: push: branches: [ "main" ] pull_request: branches: [ "main" ] permissions: contents: read jobs: test: runs-on: ubuntu-latest strategy: matrix: ruby-version: ['2.6', '2.7', '3.0'] steps: - uses: actions/checkout@v4 - name: Set up Ruby # To automatically get bug fixes and new Ruby versions for ruby/setup-ruby, # change this to (see http://github.com/ruby/setup-ruby#versioning): # uses: ruby/setup-ruby@v1 uses: ruby/setup-ruby@55283cc23133118229fd3f97f9336ee23a179fcf # v1.146.0 with: ruby-version: ${{ matrix.ruby-version }} bundler-cache: true # runs 'bundle install' and caches installed gems automatically - name: Run tests run: bundle exec rake
name: Ruby on: push: branches: [ "main" ] pull_request: branches: [ "main" ] permissions: contents: read jobs: test: runs-on: ubuntu-latest strategy: matrix: ruby-version: ['2.6', '2.7', '3.0'] steps: - uses: actions/checkout@v4 - name: Set up Ruby # To automatically get bug fixes and new Ruby versions for ruby/setup-ruby, # change this to (see http://github.com/ruby/setup-ruby#versioning): # uses: ruby/setup-ruby@v1 uses: ruby/setup-ruby@55283cc23133118229fd3f97f9336ee23a179fcf # v1.146.0 with: ruby-version: ${{ matrix.ruby-version }} bundler-cache: true # runs 'bundle install' and caches installed gems automatically - name: Run tests run: bundle exec rake
-
Edit the workflow as required. For example, change the Ruby versions you want to use.
注意
- 此工作流模板包含未通过 GitHub 认证的操作。 第三方提供的操作受单独的服务条款、隐私政策和支持文档管辖。
- 如果使用来自第三方的操作,则应使用提交 SHA 指定的版本。 如果操作已被修改,并且需要使用较新版本,则需要更新 SHA。 可以通过引用标记或分支来指定版本,但操作可能会在没有事先警告的情况下更改。 有关详细信息,请参阅“Security hardening for GitHub Actions”。
-
Click Commit changes.
Specifying the Ruby version
The easiest way to specify a Ruby version is by using the ruby/setup-ruby
action provided by the Ruby organization on GitHub. The action adds any supported Ruby version to PATH
for each job run in a workflow. For more information and available Ruby versions, see ruby/setup-ruby
.
Using Ruby's ruby/setup-ruby
action is the recommended way of using Ruby with GitHub Actions because it ensures consistent behavior across different runners and different versions of Ruby.
The setup-ruby
action takes a Ruby version as an input and configures that version on the runner.
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
Alternatively, you can check a .ruby-version
file into the root of your repository and setup-ruby
will use the version defined in that file.
Testing with multiple versions of Ruby
You can add a matrix strategy to run your workflow with more than one version of Ruby. For example, you can test your code against the latest patch releases of versions 3.1, 3.0, and 2.7.
strategy:
matrix:
ruby-version: ['3.1', '3.0', '2.7']
Each version of Ruby specified in the ruby-version
array creates a job that runs the same steps. The ${{ matrix.ruby-version }}
context is used to access the current job's version. For more information about matrix strategies and contexts, see GitHub Actions 的工作流语法 and 访问有关工作流运行的上下文信息.
The full updated workflow with a matrix strategy could look like this:
# 此工作流使用未经 GitHub 认证的操作。
# 它们由第三方提供,并受
# 单独的服务条款、隐私政策和支持
# 文档。
# GitHub 建议将操作固定到提交 SHA。
# 若要获取较新版本,需要更新 SHA。
# 还可以引用标记或分支,但该操作可能会更改而不发出警告。
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
Installing dependencies with Bundler
The setup-ruby
action will automatically install bundler for you. The version is determined by your gemfile.lock
file. If no version is present in your lockfile, then the latest compatible version will be installed.
steps:
- uses: actions/checkout@v4
- uses: ruby/setup-ruby@ec02537da5712d66d4d50a0f33b7eb52773b5ed1
with:
ruby-version: '3.1'
- run: bundle install
Caching dependencies
The setup-ruby
actions provides a method to automatically handle the caching of your gems between runs.
To enable caching, set the following.
steps:
- uses: ruby/setup-ruby@ec02537da5712d66d4d50a0f33b7eb52773b5ed1
with:
bundler-cache: true
This will configure bundler to install your gems to vendor/cache
. For each successful run of your workflow, this folder will be cached by GitHub Actions and re-downloaded for subsequent workflow runs. A hash of your gemfile.lock
and the Ruby version are used as the cache key. If you install any new gems, or change a version, the cache will be invalidated and bundler will do a fresh install.
Caching without setup-ruby
For greater control over caching, you can use the actions/cache
action directly. For more information, see Caching dependencies to speed up workflows.
steps:
- uses: actions/cache@v4
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
If you're using a matrix build, you will want to include the matrix variables in your cache key. For example, if you have a matrix strategy for different ruby versions (matrix.ruby-version
) and different operating systems (matrix.os
), your workflow steps might look like this:
steps:
- uses: actions/cache@v4
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
Matrix testing your code
The following example matrix tests all stable releases and head versions of MRI, JRuby and TruffleRuby on Ubuntu and macOS.
# 此工作流使用未经 GitHub 认证的操作。
# 它们由第三方提供,并受
# 单独的服务条款、隐私政策和支持
# 文档。
# GitHub 建议将操作固定到提交 SHA。
# 若要获取较新版本,需要更新 SHA。
# 还可以引用标记或分支,但该操作可能会更改而不发出警告。
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
Linting your code
The following example installs rubocop
and uses it to lint all files. For more information, see RuboCop. You can configure Rubocop to decide on the specific linting rules.
# 此工作流使用未经 GitHub 认证的操作。
# 它们由第三方提供,并受
# 单独的服务条款、隐私政策和支持
# 文档。
# GitHub 建议将操作固定到提交 SHA。
# 若要获取较新版本,需要更新 SHA。
# 还可以引用标记或分支,但该操作可能会更改而不发出警告。
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
Specifying -f github
means that the RuboCop output will be in GitHub's annotation format. Any linting errors will show inline in the Files changed tab of the pull request that introduces them.
Publishing Gems
You can configure your workflow to publish your Ruby package to any package registry you'd like when your CI tests pass.
You can store any access tokens or credentials needed to publish your package using repository secrets. The following example creates and publishes a package to GitHub Package Registry
and RubyGems
.
# 此工作流使用未经 GitHub 认证的操作。
# 它们由第三方提供,并受
# 单独的服务条款、隐私政策和支持
# 文档。
# GitHub 建议将操作固定到提交 SHA。
# 若要获取较新版本,需要更新 SHA。
# 还可以引用标记或分支,但该操作可能会更改而不发出警告。
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 http://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}}"