{"meta":{"title":"构建和测试 Ruby","intro":"您可以创建持续集成 (CI) 工作流程来构建和测试您的 Ruby 项目。","product":"GitHub Actions","breadcrumbs":[{"href":"/zh/enterprise-cloud@latest/actions","title":"GitHub Actions"},{"href":"/zh/enterprise-cloud@latest/actions/tutorials","title":"教程"},{"href":"/zh/enterprise-cloud@latest/actions/tutorials/build-and-test-code","title":"构建和测试代码"},{"href":"/zh/enterprise-cloud@latest/actions/tutorials/build-and-test-code/ruby","title":"Ruby"}],"documentType":"article"},"body":"# 构建和测试 Ruby\n\n您可以创建持续集成 (CI) 工作流程来构建和测试您的 Ruby 项目。\n\n## 简介\n\n本指南介绍如何创建用来生成和测试 Ruby 应用程序的持续集成 (CI) 工作流程。 如果 CI 测试通过，您可能想要部署代码或发布 gem。\n\n## 先决条件\n\n建议基本了解 Ruby、YAML、工作流程配置选项以及如何创建工作流程文件。 有关详细信息，请参阅：\n\n* ```\n            [学习 GitHub Actions](/actions/learn-github-actions)\n  ```\n* ```\n          [用 20 分钟的时间来了解 Ruby](https://www.ruby-lang.org/en/documentation/quickstart/)\n  ```\n\n## 使用 Ruby 工作流模板\n\n若要快速开始使用，请将工作流模板添加到存储库的 `.github/workflows` 目录。\n\nGitHub 为 Ruby 提供了一个工作流模板，适用于大多数 Ruby 项目。 本指南的后续部分提供了如何自定义此工作流模板的示例。\n\n1. 在 GitHub 上，导航到存储库的主页面。1. 在仓库名称下，单击“<svg version=\"1.1\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" class=\"octicon octicon-play\" aria-label=\"play\" role=\"img\"><path d=\"M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm4.879-2.773 4.264 2.559a.25.25 0 0 1 0 .428l-4.264 2.559A.25.25 0 0 1 6 10.559V5.442a.25.25 0 0 1 .379-.215Z\"></path></svg> Actions”\\*\\*\\*\\*。\n\n   ![“github/docs”存储库的选项卡的屏幕截图。 “操作”选项卡以橙色边框突出显示。](/assets/images/help/repository/actions-tab-global-nav-update.png)1. 如果存储库中已有工作流，请单击“新建工作流”。\n\n2. “选择工作流”页面显示一系列推荐的工作流模板。 搜索“ruby”。\n\n3. 单击“持续集成”\\*\\*\\*\\* 以筛选工作流选择。\n\n4. 在“Ruby”工作流上，单击“**配置**”。\n\n5. 根据需要编辑工作流。 例如更改要使用的 Ruby 版本。\n\n   > \\[!NOTE]\n   >\n   > * 此工作流模板包含未通过 GitHub 认证的操作。 第三方提供的操作受单独的服务条款、隐私政策和支持文档管辖。\n   > * 如果使用来自第三方的操作，则应使用提交 SHA 指定的版本。 如果操作已被修改，并且需要使用较新版本，则需要更新 SHA。 可以通过引用标记或分支来指定版本，但操作可能会在没有事先警告的情况下更改。 有关详细信息，请参阅“[安全使用指南](/zh/enterprise-cloud@latest/actions/security-guides/security-hardening-for-github-actions#using-third-party-actions)”。\n\n6. 单击“提交更改”。\n\n工作流文件 `ruby.yml` 将添加到存储库的 `.github/workflows` 目录中。\n\n## 指定 Ruby 版本\n\n指定 Ruby 版本的最简单方法是使用 Ruby 组织在 GitHub 上提供的 `ruby/setup-ruby`操作。 对于工作流中运行的每个作业，该操作会将任何受支持的 Ruby 版本添加到 `PATH`。 有关详细信息和可用的 Ruby 版本，请参阅 [`ruby/setup-ruby`](https://github.com/ruby/setup-ruby)。\n\n推荐使用 Ruby 的 `ruby/setup-ruby` 操作为将 Ruby 与 GitHub Actions 配合使用，因为这样可以确保不同运行环境和不同版本的 Ruby 的行为一致。\n\n```\n          `setup-ruby` 操作将 Ruby 版本作为输入并在运行器上配置该版本。\n```\n\n```yaml\n# 此工作流使用未经 GitHub 认证的操作。\n# 它们由第三方提供，并受\n# 单独的服务条款、隐私政策和支持\n# 文档。\nsteps:\n- uses: actions/checkout@v5\n- uses: ruby/setup-ruby@ec02537da5712d66d4d50a0f33b7eb52773b5ed1\n  with:\n    ruby-version: '3.1' # Not needed with a .ruby-version file\n- run: bundle install\n- run: bundle exec rake\n```\n\n或者，您可以将 `.ruby-version` 文件放入存储库的根目录，然后 `setup-ruby` 将使用该文件中定义的版本。\n\n## 使用多个版本的 Ruby 进行测试\n\n您可以添加矩阵策略，以在多个版本的 Ruby 上运行工作流程。 例如，您可以根据版本 3.1、3.0 和 2.7 的最新修补程序版本测试代码。\n\n```yaml\nstrategy:\n  matrix:\n    ruby-version: ['3.1', '3.0', '2.7']\n```\n\n```\n          `ruby-version` 数组中指定的每个 Ruby 版本都会创建一个运行相同步骤的作业。 `${{ matrix.ruby-version }}` 上下文用于访问当前作业的版本。 有关矩阵策略和上下文的详细信息，请参阅“[AUTOTITLE](/actions/using-workflows/workflow-syntax-for-github-actions)”和“[AUTOTITLE](/actions/learn-github-actions/contexts)”。\n```\n\n包含矩阵策略的完整更新工作流程可能看起如下：\n\n```yaml\n# 此工作流使用未经 GitHub 认证的操作。\n# 它们由第三方提供，并受\n# 单独的服务条款、隐私政策和支持\n# 文档。\n\n# GitHub 建议将操作固定到提交 SHA。\n# 若要获取较新版本，需要更新 SHA。\n# 还可以引用标记或分支，但该操作可能会更改而不发出警告。\n\nname: Ruby CI\n\non:\n  push:\n    branches: [ main ]\n  pull_request:\n    branches: [ main ]\n\njobs:\n  test:\n\n    runs-on: ubuntu-latest\n\n    strategy:\n      matrix:\n        ruby-version: ['3.1', '3.0', '2.7']\n\n    steps:\n      - uses: actions/checkout@v5\n      - name: Set up Ruby ${{ matrix.ruby-version }}\n        uses: ruby/setup-ruby@ec02537da5712d66d4d50a0f33b7eb52773b5ed1\n        with:\n          ruby-version: ${{ matrix.ruby-version }}\n      - name: Install dependencies\n        run: bundle install\n      - name: Run tests\n        run: bundle exec rake\n```\n\n## 使用 Bundler 安装依赖项\n\n`setup-ruby` 操作将自动安装捆绑程序。 版本由 `gemfile.lock` 文件决定。 如果您的锁定文件中没有版本，则会安装最新的兼容版本。\n\n```yaml\n# 此工作流使用未经 GitHub 认证的操作。\n# 它们由第三方提供，并受\n# 单独的服务条款、隐私政策和支持\n# 文档。\nsteps:\n- uses: actions/checkout@v5\n- uses: ruby/setup-ruby@ec02537da5712d66d4d50a0f33b7eb52773b5ed1\n  with:\n    ruby-version: '3.1'\n- run: bundle install\n```\n\n### 缓存依赖项\n\n`setup-ruby` 操作提供在运行之间自动处理 Gem 缓存的方法。\n\n要启用缓存，请设置以下内容。\n\n```yaml\n# 此工作流使用未经 GitHub 认证的操作。\n# 它们由第三方提供，并受\n# 单独的服务条款、隐私政策和支持\n# 文档。\nsteps:\n- uses: ruby/setup-ruby@ec02537da5712d66d4d50a0f33b7eb52773b5ed1\n  with:\n    bundler-cache: true\n```\n\n这将配置捆绑程序以将 gem 安装到 `vendor/cache`。 对于工作流的每次成功运行，此文件夹将由 GitHub Actions 缓存，并重新下载用于后续的工作流运行。 你的 `gemfile.lock` 和 Ruby 版本的哈希用作缓存键。 如果安装任何新 Gem 或更改版本，缓存将失效，Bundler 将进行全新安装。\n\n```\n          **不使用 setup-ruby 的缓存**\n```\n\n为了更好地控制缓存，可以直接使用 `actions/cache` 操作。 有关详细信息，请参阅“[依赖项缓存参考](/zh/enterprise-cloud@latest/actions/using-workflows/caching-dependencies-to-speed-up-workflows)”。\n\n```yaml\nsteps:\n- uses: actions/cache@v4\n  with:\n    path: vendor/bundle\n    key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}\n    restore-keys: |\n      ${{ runner.os }}-gems-\n- name: Bundle install\n  run: |\n    bundle config path vendor/bundle\n    bundle install --jobs 4 --retry 3\n```\n\n如果您使用的是矩阵构建，您将会想要在缓存密钥中包含矩阵变量。 例如，如果提供了针对不同 Ruby 版本 (`matrix.ruby-version`) 和不同操作系统 (`matrix.os`) 的矩阵策略，工作流步骤可能如下所示：\n\n```yaml\nsteps:\n- uses: actions/cache@v4\n  with:\n    path: vendor/bundle\n    key: bundle-use-ruby-${{ matrix.os }}-${{ matrix.ruby-version }}-${{ hashFiles('**/Gemfile.lock') }}\n    restore-keys: |\n      bundle-use-ruby-${{ matrix.os }}-${{ matrix.ruby-version }}-\n- name: Bundle install\n  run: |\n    bundle config path vendor/bundle\n    bundle install --jobs 4 --retry 3\n```\n\n## 矩阵化测试你的代码\n\n下面的示例矩阵在 Ubuntu 和 macOS 上测试 MRI、JRuby 和 TruffleRuby 的所有稳定版本和头部版本。\n\n```yaml\n# 此工作流使用未经 GitHub 认证的操作。\n# 它们由第三方提供，并受\n# 单独的服务条款、隐私政策和支持\n# 文档。\n\n# GitHub 建议将操作固定到提交 SHA。\n# 若要获取较新版本，需要更新 SHA。\n# 还可以引用标记或分支，但该操作可能会更改而不发出警告。\n\nname: Matrix Testing\n\non:\n  push:\n    branches: [ main ]\n  pull_request:\n    branches: [ main ]\n\njobs:\n  test:\n    runs-on: ${{ matrix.os }}-latest\n    strategy:\n      fail-fast: false\n      matrix:\n        os: [ubuntu, macos]\n        ruby: [2.5, 2.6, 2.7, head, debug, jruby, jruby-head, truffleruby, truffleruby-head]\n    continue-on-error: ${{ endsWith(matrix.ruby, 'head') || matrix.ruby == 'debug' }}\n    steps:\n      - uses: actions/checkout@v5\n      - uses: ruby/setup-ruby@ec02537da5712d66d4d50a0f33b7eb52773b5ed1\n        with:\n          ruby-version: ${{ matrix.ruby }}\n      - run: bundle install\n      - run: bundle exec rake\n```\n\n## 嵌入代码\n\n以下示例安装 `rubocop` 并使用它对所有文件进行 lint 操作。 有关详细信息，请参阅 [RuboCop](https://github.com/rubocop-hq/rubocop)。 可以[配置 Rubocop](https://docs.rubocop.org/rubocop/configuration.html) 以决定具体的 Lint 分析规则。\n\n```yaml\n# 此工作流使用未经 GitHub 认证的操作。\n# 它们由第三方提供，并受\n# 单独的服务条款、隐私政策和支持\n# 文档。\n\n# GitHub 建议将操作固定到提交 SHA。\n# 若要获取较新版本，需要更新 SHA。\n# 还可以引用标记或分支，但该操作可能会更改而不发出警告。\n\nname: Linting\n\non: [push]\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v5\n      - uses: ruby/setup-ruby@ec02537da5712d66d4d50a0f33b7eb52773b5ed1\n        with:\n          ruby-version: '2.6'\n      - run: bundle install\n      - name: Rubocop\n        run: rubocop -f github\n```\n\n指定 `-f github` 意味着 RuboCop 输出将为 GitHub 的批注格式。 任何 Lint 分析错误都会在引入它们的拉取请求的**已更改的文件**选项卡中内联显示。\n\n## 发布 Gem\n\n您可以配置工作流程在 CI 测试通过时将 Ruby 包发布到您想要的任何包注册表。\n\n您可以使用仓库密码存储发布软件包所需的访问令牌或凭据。 以下示例创建包并将其发布到 `GitHub Package Registry` 和 `RubyGems`。\n\n```yaml\n# 此工作流使用未经 GitHub 认证的操作。\n# 它们由第三方提供，并受\n# 单独的服务条款、隐私政策和支持\n# 文档。\n\n# GitHub 建议将操作固定到提交 SHA。\n# 若要获取较新版本，需要更新 SHA。\n# 还可以引用标记或分支，但该操作可能会更改而不发出警告。\n\nname: Ruby Gem\n\non:\n  # Manually publish\n  workflow_dispatch:\n  # Alternatively, publish whenever changes are merged to the `main` branch.\n  push:\n    branches: [ main ]\n  pull_request:\n    branches: [ main ]\n\njobs:\n  build:\n    name: Build + Publish\n    runs-on: ubuntu-latest\n    permissions:\n      packages: write\n      contents: read\n\n    steps:\n      - uses: actions/checkout@v5\n      - name: Set up Ruby 2.6\n        uses: ruby/setup-ruby@ec02537da5712d66d4d50a0f33b7eb52773b5ed1\n        with:\n          ruby-version: '2.6'\n      - run: bundle install\n\n      - name: Publish to GPR\n        run: |\n          mkdir -p $HOME/.gem\n          touch $HOME/.gem/credentials\n          chmod 0600 $HOME/.gem/credentials\n          printf -- \"---\\n:github: ${GEM_HOST_API_KEY}\\n\" > $HOME/.gem/credentials\n          gem build *.gemspec\n          gem push --KEY github --host https://rubygems.pkg.github.com/${OWNER} *.gem\n        env:\n          GEM_HOST_API_KEY: \"Bearer ${{secrets.GITHUB_TOKEN}}\"\n          OWNER: ${{ github.repository_owner }}\n\n      - name: Publish to RubyGems\n        run: |\n          mkdir -p $HOME/.gem\n          touch $HOME/.gem/credentials\n          chmod 0600 $HOME/.gem/credentials\n          printf -- \"---\\n:rubygems_api_key: ${GEM_HOST_API_KEY}\\n\" > $HOME/.gem/credentials\n          gem build *.gemspec\n          gem push *.gem\n        env:\n          GEM_HOST_API_KEY: \"${{secrets.RUBYGEMS_AUTH_TOKEN}}\"\n```"}