# Создание и тестирование для Ruby

Вы можете создать рабочий процесс непрерывной интеграции для сборки и тестирования проекта Ruby.

> \[!NOTE]
> GitHub Enterprise Serverразмещенные в данный момент средства выполнения не поддерживаются в GitHub.

## Введение

В этом руководстве показано, как получить рабочий процесс непрерывной интеграции (CI), который создает и тестирует приложение Ruby. Если тесты CI проходят правильно, может потребоваться развернуть код или опубликовать пакет.

## Необходимые компоненты

Рекомендуется иметь базовое представление о Ruby, YAML, параметрах конфигурации рабочих процессов, а также о том, как создавать файл рабочего процесса. Дополнительные сведения см. в разделе:

* [Learn GitHub Actions](/ru/enterprise-server@3.22/actions/how-tos/write-workflows)
* [Ruby за 20 минут](https://www.ruby-lang.org/en/documentation/quickstart/)

## Использование шаблона рабочего процесса Ruby

Чтобы быстро приступить к работе, добавьте шаблон рабочего процесса в `.github/workflows` каталог репозитория.

GitHub предоставляет шаблон рабочего процесса для Ruby, который должен работать для большинства проектов Ruby. В последующих разделах этого руководства приведены примеры настройки этого шаблона рабочего процесса.

1. На GitHubперейдите на главную страницу репозитория.

2. Под именем репозитория щелкните **<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**.

   ![Снимок экрана: вкладки для репозитория github/docs. Вкладка "Действия" выделена оранжевым контуром.](/assets/images/help/repository/actions-tab-global-nav-update.png)

3. Если в вашем репозитории уже используется рабочий процесс, нажмите кнопку **Создать рабочий процесс**.

4. На странице "Выбор рабочего процесса" показан выбор рекомендуемых шаблонов рабочих процессов. Найдите "ruby".

5. Отфильтруйте выбор рабочих процессов, щелкнув **"Непрерывная интеграция**".

6. В рабочем процессе Ruby нажмите кнопку **"Настроить**".

   Если вы не найдете шаблон рабочего процесса Ruby, скопируйте следующий код рабочего процесса в новый файл, который вызывается `ruby.yml` в `.github/workflows` каталоге репозитория.

   ```yaml copy
   # Этот рабочий процесс использует действия, которые не сертифицированы GitHub.
   # Они предоставляются сторонним поставщиком, и на них распространяются
   # отдельные условия обслуживания, политика конфиденциальности и поддержка
   # документации.
   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@v6
       - name: Set up Ruby
       # To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
       # change this to (see https://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
   ```

7. Измените рабочий процесс по мере необходимости. Например, измените версии Ruby, которые вы хотите использовать.

   > \[!NOTE]
   >
   > * Этот шаблон рабочего процесса содержит действие, которое не сертифицировано.GitHub Действия, предоставляемые сторонними сторонами, регулируются отдельными условиями обслуживания, политикой конфиденциальности и документацией по поддержке.
   > * При использовании действий со стороны сторонних производителей следует использовать версию, указанную с помощью фиксации SHA. Если действие будет изменено и вы хотите использовать более новую версию, необходимо обновить SHA. Вы можете указать версию, ссылаясь на тег или ветвь, однако действие может измениться без предупреждения. Дополнительные сведения см. в разделе [Справочник по безопасному использованию](/ru/enterprise-server@3.22/actions/reference/security/secure-use#using-third-party-actions).

8. Щелкните **Зафиксировать изменения**.

## Указание версии Ruby

Самый простой способ определить версию Ruby — использовать действие `ruby/setup-ruby`, предоставленное организацией Ruby на GitHub. Это действие добавляет любую поддерживаемую версию Ruby в `PATH` для каждого задания, выполняемого в рабочем процессе. Дополнительные сведения и доступные версии Ruby см. в описании [`ruby/setup-ruby`](https://github.com/ruby/setup-ruby).

Рекомендуется использовать действие Руби `ruby/setup-ruby` с GitHub Actions, так как это обеспечивает стабильное поведение между разными бегунами и разными версиями Руби.

Действие `setup-ruby` принимает версию Ruby в качестве входных данных и настраивает ее в средстве выполнения.

```yaml
# Этот рабочий процесс использует действия, которые не сертифицированы GitHub.
# Они предоставляются сторонним поставщиком, и на них распространяются
# отдельные условия обслуживания, политика конфиденциальности и поддержка
# документации.
steps:
- uses: actions/checkout@v6
- 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.

```yaml
strategy:
  matrix:
    ruby-version: ['3.1', '3.0', '2.7']
```

Каждая версия Ruby, указанная в массиве `ruby-version`, создает задание, которое выполняет одни и те же действия. Контекст `${{ matrix.ruby-version }}` используется для доступа к версии текущего задания. Дополнительные сведения о стратегиях матриц и контекстах см. в разделе \[AUTOTITLE и [Синтаксис рабочего процесса для GitHub Actions](/ru/enterprise-server@3.22/actions/reference/workflows-and-actions/workflow-syntax)]\(/actions/reference/workflows-and-actions/contexts).

Полный обновленный рабочий процесс с матричной стратегией может выглядеть следующим образом:

```yaml
# Этот рабочий процесс использует действия, которые не сертифицированы 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@v6
      - 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
```

## Установка зависимостей с использованием средства увязки в пакеты

Действие `setup-ruby` установит средство увязки в пакеты автоматически. Версия определяется по файлу `gemfile.lock`. Если в файле блокировки отсутствует версия, будет установлена последняя совместимая версия.

```yaml
# Этот рабочий процесс использует действия, которые не сертифицированы GitHub.
# Они предоставляются сторонним поставщиком, и на них распространяются
# отдельные условия обслуживания, политика конфиденциальности и поддержка
# документации.
steps:
- uses: actions/checkout@v6
- uses: ruby/setup-ruby@ec02537da5712d66d4d50a0f33b7eb52773b5ed1
  with:
    ruby-version: '3.1'
- run: bundle install
```

### Кэширование зависимостей

Действия `setup-ruby` предоставляют метод автоматической обработки кэширования пакетов между запусками.

Чтобы включить кэширование, укажите следующее.

```yaml
# Этот рабочий процесс использует действия, которые не сертифицированы GitHub.
# Они предоставляются сторонним поставщиком, и на них распространяются
# отдельные условия обслуживания, политика конфиденциальности и поддержка
# документации.
steps:
- uses: ruby/setup-ruby@ec02537da5712d66d4d50a0f33b7eb52773b5ed1
  with:
    bundler-cache: true
```

При этом средство увязки в пакеты будет настроено для установки пакетов в `vendor/cache`. Для каждого успешного выполнения рабочего процесса эта папка будет кэширована GitHub Actions и повторно загружена для последующих запусков рабочего процесса. Хэш версии `gemfile.lock` Ruby используется в качестве ключа кэша. Если вы устанавливаете новые пакеты или изменяете версию, кэш станет недействительным, а средство увязки в пакеты выполнит новую установку.

**Кэширование без использования setup-ruby**

Для более широкого контроля над кэшированием можно напрямую использовать действие `actions/cache`. Дополнительные сведения см. в разделе [Справочник по кэшированию зависимостей](/ru/enterprise-server@3.22/actions/reference/workflows-and-actions/dependency-caching).

```yaml
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
```

Если вы используете матричную сборку, потребуется включить матричные переменные в ключ кэша. Например, если у вас есть матричная стратегия для разных версий ruby (`matrix.ruby-version`) и различных операционных систем (`matrix.os`), шаги рабочего процесса могут выглядеть следующим образом:

```yaml
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
```

## Матричное тестирование кода

В следующем примере выполняется матричное тестирование всех стабильных выпусков и головных версий MRI, JRuby и TruffleRuby на базе Ubuntu и macOS.

```yaml
# Этот рабочий процесс использует действия, которые не сертифицированы 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@v6
      - uses: ruby/setup-ruby@ec02537da5712d66d4d50a0f33b7eb52773b5ed1
        with:
          ruby-version: ${{ matrix.ruby }}
      - run: bundle install
      - run: bundle exec rake
```

## Анализ кода

В следующем примере выполняется установка `rubocop` и его использование для анализа кода всех файлов. Дополнительные сведения см. в описании [RuboCop](https://github.com/rubocop-hq/rubocop). Вы можете [настроить Rubocop](https://docs.rubocop.org/rubocop/configuration.html), чтобы задать конкретные правила анализа.

```yaml
# Этот рабочий процесс использует действия, которые не сертифицированы GitHub.
# Они предоставляются сторонним поставщиком, и на них распространяются
# отдельные условия обслуживания, политика конфиденциальности и поддержка
# документации.

# GitHub рекомендует закрепить действия в фиксации SHA.
# Чтобы получить более новую версию, потребуется обновить SHA.
# Вы также можете ссылаться на тег или ветвь, однако действие может измениться без предупреждения.

name: Linting

on: [push]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: ruby/setup-ruby@ec02537da5712d66d4d50a0f33b7eb52773b5ed1
        with:
          ruby-version: '2.6'
      - run: bundle install
      - name: Rubocop
        run: rubocop -f github
```

Указание `-f github` означает, что выходные данные RuboCop будут находиться в GitHubформате заметки. Все ошибки подстроки будут отображаться на **вкладке "Файлы изменены** " запроса на вытягивание, который представляет их.

## Публикация пакетов

Вы можете настроить рабочий процесс для публикации пакета Ruby в любом подходящем реестре пакетов после прохождения тестов CI.

Вы можете хранить любые маркеры доступа или учетные данные, необходимые для публикации пакета, с помощью секретов репозитория. Следующий пример создаёт и публикует пакет для `GitHub Package Registry` и `RubyGems`.

```yaml
# Этот рабочий процесс использует действия, которые не сертифицированы 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@v6
      - 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}}"
```