Skip to main content

构建和测试 Ruby

您可以创建持续集成 (CI) 工作流程来构建和测试您的 Ruby 项目。

注: GitHub 托管的运行器目前在 GitHub Enterprise Server 上不受支持。 您可以在 GitHub 公共路线图 上查看有关未来支持计划的更多信息。

简介

本指南介绍如何创建用来生成和测试 Ruby 应用程序的持续集成 (CI) 工作流程。 如果 CI 测试通过,您可能想要部署代码或发布 gem。

基本要求

建议基本了解 Ruby、YAML、工作流程配置选项以及如何创建工作流程文件。 更多信息请参阅:

使用 Ruby 入门工作流程

GitHub 提供有 Ruby 入门工作流程,该工作流程将适用于大多数 Ruby 项目。 更多信息请参阅 Ruby 入门工作流程

要快速开始,请将入门工作流程添加到仓库的 .github/workflows 目录中。 下面显示的工作流假定仓库的默认分支是 main

# 此工作流使用未经 GitHub 认证的操作。
# 它们由第三方提供,并受
# 单独的服务条款、隐私政策和支持
# 文档管理。

# 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

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  test:

    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2
      - name: Set up Ruby
        uses: ruby/setup-ruby@359bebbc29cbe6c87da6bc9ea3bc930432750108
        with:
          ruby-version: '3.1'
      - name: Install dependencies
        run: bundle install
      - name: Run tests
        run: bundle exec rake

指定 Ruby 版本

指定 Ruby 版本的最简单方法是使用 Ruby 组织在 GitHub 上提供的 ruby/setup-ruby 操作。 该操作将任何受支持的 Ruby 版本添加到工作流程中运行的每个作业的 PATH。 有关详细信息和可用的 Ruby 版本,请参阅 ruby/setup-ruby

使用 Ruby 的 ruby/setup-ruby 操作是 Python 与 GitHub Actions 结合使用时的推荐方式,因为它能确保不同运行器和不同版本的 Ruby 行为一致。

setup-ruby 操作采用 Ruby 版本作为输入,并在运行器上配置该版本。

steps:
- uses: actions/checkout@v2
- uses: ruby/setup-ruby@359bebbc29cbe6c87da6bc9ea3bc930432750108
  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 的工作流程语法”和“上下文”。

包含矩阵策略的完整更新工作流程可能看起如下:

# 此工作流使用未经 GitHub 认证的操作。
# 它们由第三方提供,并受
# 单独的服务条款、隐私政策和支持
# 文档管理。

# 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@v2
      - name: Set up Ruby ${{ matrix.ruby-version }}
        uses: ruby/setup-ruby@359bebbc29cbe6c87da6bc9ea3bc930432750108
        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 文件决定。 如果您的锁定文件中没有版本,则会安装最新的兼容版本。

steps:
- uses: actions/checkout@v2
- uses: ruby/setup-ruby@359bebbc29cbe6c87da6bc9ea3bc930432750108
  with:
    ruby-version: '3.1'
- run: bundle install

测试代码的矩阵

下面的示例矩阵在 Ubuntu 和 macOS 上测试 MRI、JRuby 和 TruffleRuby 的所有稳定版本和头部版本。

# 此工作流使用未经 GitHub 认证的操作。
# 它们由第三方提供,并受
# 单独的服务条款、隐私政策和支持
# 文档管理。

# 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@v2
      - uses: ruby/setup-ruby@477b21f02be01bcb8030d50f37cfec92bfa615b6
        with:
          ruby-version: ${{ matrix.ruby }}
      - run: bundle install
      - run: bundle exec rake

嵌入代码

下面的示例安装 rubocop 并用它来嵌入所有文件。 更多信息请参阅 RuboCop。 您可以配置 Rubocop 来决定特定的嵌入规则。

# 此工作流使用未经 GitHub 认证的操作。
# 它们由第三方提供,并受
# 单独的服务条款、隐私政策和支持
# 文档管理。

# 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@v2
      - uses: ruby/setup-ruby@477b21f02be01bcb8030d50f37cfec92bfa615b6
        with:
          ruby-version: 2.6
      - run: bundle install
      - name: Rubocop
        run: rubocop

发布 Gem

您可以配置工作流程在 CI 测试通过时将 Ruby 包发布到您想要的任何包注册表。

您可以使用仓库密码存储发布软件包所需的访问令牌或凭据。 下面的示例创建包并将其发布到 GitHub Package 注册表RubyGems

# 此工作流使用未经 GitHub 认证的操作。
# 它们由第三方提供,并受
# 单独的服务条款、隐私政策和支持
# 文档管理。

# 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@v2
      - name: Set up Ruby 2.6
        uses: ruby/setup-ruby@477b21f02be01bcb8030d50f37cfec92bfa615b6
        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}}"