# Переход с CircleCI на GitHub Actions

GitHub Actions и CircleCI имеют несколько сходств в конфигурации, что делает миграцию на GitHub Actions относительно простой.

## Введение

CircleCI и GitHub Actions позволяют создавать рабочие процессы, которые автоматически выполняют сборку, тестирование, публикацию, выпуск и развертывание кода. CircleCI и GitHub Actions используют некоторые сходства в конфигурации рабочего процесса.

* Файлы конфигурации рабочего процесса записываются в YAML и хранятся в репозитории.
* В рабочем процессе может быть одно или несколько заданий.
* Задания включают один или несколько шагов или отдельных команд.
* Шаги или задачи можно повторно использовать и предоставлять сообществу.

Дополнительные сведения см. в разделе [Понимание GitHub Actions](/ru/actions/learn-github-actions/understanding-github-actions).

## Основные отличия

При миграции с CircleCI необходимо учитывать следующие различия.

* Автоматический параллелизм тестов в CircleCI автоматически группирует тесты в соответствии с заданными пользователем правилами или историческими сведениями о времени. Эта функциональность не встроена в GitHub Actions.
* Действия, выполняемые в контейнерах Docker, чувствительны к проблемам с разрешениями, так как в контейнерах используется другое сопоставление пользователей. Многих из этих проблем можно избежать, не используя инструкцию `USER` в *Dockerfile*. Дополнительные сведения о файловой системе Docker на GitHub, размещенных в runners, см. в разделе [Средства выполнения тестов, размещенные в GitHub](/ru/actions/using-github-hosted-runners/about-github-hosted-runners#docker-container-filesystem).

## Миграция рабочих процессов и заданий

CircleCI определяет `workflows` в файле *config.yml*, что позволяет настроить несколько рабочих процессов. Для GitHub требуется один файл рабочего процесса для каждого рабочего процесса, и, как следствие, не требуется объявлять `workflows`. Вам нужно будет создать по новому файлу рабочего процесса для каждого рабочего процесса, настроенного в файле *config.yml*.

Как CircleCI, так и GitHub Actions настраивают `jobs` в файле конфигурации с использованием аналогичного синтаксиса. При настройке зависимостей между заданиями с помощью `requires` в рабочем процессе CircleCI вы можете использовать эквивалентный синтаксис `needs` GitHub Actions. Дополнительные сведения см. в разделе [Синтаксис рабочего процесса для GitHub Actions](/ru/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idneeds).

## Перенос orbs в действия

И CircleCI, и GitHub Actions предоставляют механизм повторного использования и совместного использования задач в рабочем процессе. CircleCI использует концепцию с именем orbs, написанную в YAML, для предоставления задач, которые пользователи могут повторно использовать в рабочем процессе. GitHub Actions имеет мощные и гибкие многократно используемые компоненты, называемые действиями, которые создаются с помощью файлов JavaScript или образов Docker. Вы можете создать действия, написав пользовательский код, взаимодействующий с репозиторием любым способом, в том числе интеграция с API GitHubи любым общедоступным сторонним API. Например, действие может публиковать модули NPM, отправлять SMS-оповещения при возникновении неотложных проблем или развертывать готовый код. Дополнительные сведения см. в разделе [Повторное выполнение автоматизации](/ru/actions/creating-actions).

CircleCI может повторно использовать фрагменты рабочих процессов с привязками YAML и псевдонимами. GitHub Actions поддерживает привязки и псевдонимы YAML для повторного использования, а также предоставляет матрицы для выполнения заданий с различными конфигурациями. Дополнительные сведения о матрицах см. в разделе [Выполнение вариантов заданий в рабочем процессе](/ru/actions/using-jobs/using-a-matrix-for-your-jobs).

## Использование образов Docker

И CircleCI, и GitHub Actions поддерживают выполнение шагов внутри образа Docker.

CircleCI предоставляет набор предварительно созданных образов с общими зависимостями. В этих образах `USER` настроен как `circleci`, что приводит к конфликту разрешений с GitHub Actions.

Рекомендуется отказаться от предварительно созданных образов CircleCI при миграции на GitHub Actions. Во многих случаях вы можете использовать действия для установки необходимых дополнительных зависимостей.

Дополнительные сведения о файловой системе Docker см. в разделе [Средства выполнения тестов, размещенные в GitHub](/ru/actions/using-github-hosted-runners/about-github-hosted-runners#docker-container-filesystem).

Дополнительные сведения о средствах и пакетах, доступных на GitHubразмещенных образов runner, см. в разделе [Средства выполнения тестов, размещенные в GitHub](/ru/actions/using-github-hosted-runners/about-github-hosted-runners#supported-software).

## Использование переменных и секретов

CircleCI и GitHub Actions поддерживают переменные настройки в файле конфигурации и создание секретов с помощью пользовательского интерфейса CircleCI или GitHub .

Дополнительные сведения см. в разделе \[AUTOTITLE и [Справочник по переменным](/ru/actions/reference/variables-reference#default-environment-variables)]\(/actions/security-guides/using-secrets-in-github-actions).

## Кэширование

CircleCI и GitHub Actions предоставляют метод для ручного кэширования файлов в файле конфигурации.

Ниже приведен пример синтаксиса для каждой системы.

### Синтаксис CircleCI для кэширования

```yaml
- restore_cache:
    keys:
      - v1-npm-deps-{{ checksum "package-lock.json" }}
      - v1-npm-deps-
```

### Синтаксис GitHub Actions для кэширования

```yaml
- name: Cache node modules
  uses: actions/cache@v4
  with:
    path: ~/.npm
    key: v1-npm-deps-${{ hashFiles('**/package-lock.json') }}
    restore-keys: v1-npm-deps-
```

В GitHub Actions отсутствует эквивалент кэширования уровня Docker (или DLC) CircleCI.

## Сохранение данных между заданиями

И CircleCI, и GitHub Actions предоставляют механизмы сохранения данных между заданиями.

Ниже приведен пример синтаксиса конфигурации в CircleCI и GitHub Actions.

### Синтаксис CircleCI для сохранения данных между заданиями

```yaml
- persist_to_workspace:
    root: workspace
    paths:
      - math-homework.txt

...

- attach_workspace:
    at: /tmp/workspace
```

### Синтаксис GitHub Actions для сохранения данных между работами

```yaml
- name: Upload math result for job 1
  uses: actions/upload-artifact@v4
  with:
    name: homework
    path: math-homework.txt

...

- name: Download math result for job 1
  uses: actions/download-artifact@v5
  with:
    name: homework
```

Дополнительные сведения см. в разделе [Хранение и предоставление общего доступа к данным с артефактами рабочего процесса](/ru/actions/using-workflows/storing-workflow-data-as-artifacts).

## Использование баз данных и контейнеров служб

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

В CircleCI первый образ, указанный в файле *config.yaml*, является основным образом, используемым для выполнения команд. GitHub Actions использует явные разделы: `container` используется для основного контейнера, и дополнительные контейнеры перечисляются в `services`.

Ниже приведен пример синтаксиса конфигурации в CircleCI и GitHub Actions.

### Синтаксис CircleCI для использования баз данных и контейнеров служб

```yaml
---
version: 2.1

jobs:

  ruby-26:
    docker:
      - image: circleci/ruby:2.6.3-node-browsers-legacy
        environment:
          PGHOST: localhost
          PGUSER: administrate
          RAILS_ENV: test
      - image: postgres:10.1-alpine
        environment:
          POSTGRES_USER: administrate
          POSTGRES_DB: ruby26
          POSTGRES_PASSWORD: ""

    working_directory: ~/administrate

    steps:
      - checkout

      # Bundle install dependencies
      - run: bundle install --path vendor/bundle

      # Wait for DB
      - run: dockerize -wait tcp://localhost:5432 -timeout 1m

      # Setup the environment
      - run: cp .sample.env .env

      # Setup the database
      - run: bundle exec rake db:setup

      # Run the tests
      - run: bundle exec rake

workflows:
  version: 2
  build:
    jobs:
      - ruby-26
...

- attach_workspace:
    at: /tmp/workspace
```

### Синтаксис GitHub Actions для использования баз данных и сервисных контейнеров

<!-- markdownlint-disable search-replace -->

```yaml
name: Containers

on: [push]

jobs:
  build:

    runs-on: ubuntu-latest
    container: circleci/ruby:2.6.3-node-browsers-legacy

    env:
      PGHOST: postgres
      PGUSER: administrate
      RAILS_ENV: test

    services:
      postgres:
        image: postgres:10.1-alpine
        env:
          POSTGRES_USER: administrate
          POSTGRES_DB: ruby25
          POSTGRES_PASSWORD: ""
        ports:
          - 5432:5432
        # Add a health check
        options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5

    steps:
      # This Docker file changes sets USER to circleci instead of using the default user, so we need to update file permissions for this image to work on GH Actions.
      # See https://docs.github.com/actions/using-github-hosted-runners/about-github-hosted-runners#docker-container-filesystem

      - name: Setup file system permissions
        run: sudo chmod -R 777 $GITHUB_WORKSPACE /github /__w/_temp
      - uses: actions/checkout@v6
      - name: Install dependencies
        run: bundle install --path vendor/bundle
      - name: Setup environment configuration
        run: cp .sample.env .env
      - name: Setup database
        run: bundle exec rake db:setup
      - name: Run tests
        run: bundle exec rake
```

<!-- markdownlint-enable search-replace -->

Дополнительные сведения см. в разделе [Взаимодействие с контейнерами служб Docker](/ru/actions/using-containerized-services/about-service-containers).

## Полный пример

Ниже приведен пример из практики. В левой части показан фактический файл *config.yml* CircleCI для репозитория[thoughtbot/administrator](https://github.com/thoughtbot/administrate). Справа показан эквивалент в GitHub Actions.

### Полный пример для CircleCI

```yaml
---
version: 2.1

commands:
  shared_steps:
    steps:
      - checkout

      # Restore Cached Dependencies
      - restore_cache:
          name: Restore bundle cache
          key: administrate-{{ checksum "Gemfile.lock" }}

      # Bundle install dependencies
      - run: bundle install --path vendor/bundle

      # Cache Dependencies
      - save_cache:
          name: Store bundle cache
          key: administrate-{{ checksum "Gemfile.lock" }}
          paths:
            - vendor/bundle

      # Wait for DB
      - run: dockerize -wait tcp://localhost:5432 -timeout 1m

      # Setup the environment
      - run: cp .sample.env .env

      # Setup the database
      - run: bundle exec rake db:setup

      # Run the tests
      - run: bundle exec rake

default_job: &default_job
  working_directory: ~/administrate
  steps:
    - shared_steps
    # Run the tests against multiple versions of Rails
    - run: bundle exec appraisal install
    - run: bundle exec appraisal rake

jobs:
  ruby-25:
    <<: *default_job
    docker:
      - image: circleci/ruby:2.5.0-node-browsers
        environment:
          PGHOST: localhost
          PGUSER: administrate
          RAILS_ENV: test
      - image: postgres:10.1-alpine
        environment:
          POSTGRES_USER: administrate
          POSTGRES_DB: ruby25
          POSTGRES_PASSWORD: ""

  ruby-26:
    <<: *default_job
    docker:
      - image: circleci/ruby:2.6.3-node-browsers-legacy
        environment:
          PGHOST: localhost
          PGUSER: administrate
          RAILS_ENV: test
      - image: postgres:10.1-alpine
        environment:
          POSTGRES_USER: administrate
          POSTGRES_DB: ruby26
          POSTGRES_PASSWORD: ""

workflows:
  version: 2
  multiple-rubies:
    jobs:
      - ruby-26
      - ruby-25
```

### Полный пример GitHub Actions

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

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

name: Containers

on: [push]

jobs:
  build:

    strategy:
      matrix:
        ruby: ['2.5', '2.6.3']

    runs-on: ubuntu-latest

    env:
      PGHOST: localhost
      PGUSER: administrate
      RAILS_ENV: test

    services:
      postgres:
        image: postgres:10.1-alpine
        env:
          POSTGRES_USER: administrate
          POSTGRES_DB: ruby25
          POSTGRES_PASSWORD: ""
        ports:
          - 5432:5432
        # Add a health check
        options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5

    steps:
      - uses: actions/checkout@v6
      - name: Setup Ruby
        uses: eregon/use-ruby-action@ec02537da5712d66d4d50a0f33b7eb52773b5ed1
        with:
          ruby-version: ${{ matrix.ruby }}
      - name: Cache dependencies
        uses: actions/cache@v4
        with:
          path: vendor/bundle
          key: administrate-${{ matrix.image }}-${{ hashFiles('Gemfile.lock') }}
      - name: Install postgres headers
        run: |
          sudo apt-get update
          sudo apt-get install libpq-dev
      - name: Install dependencies
        run: bundle install --path vendor/bundle
      - name: Setup environment configuration
        run: cp .sample.env .env
      - name: Setup database
        run: bundle exec rake db:setup
      - name: Run tests
        run: bundle exec rake
      - name: Install appraisal
        run: bundle exec appraisal install
      - name: Run appraisal
        run: bundle exec appraisal rake
```