Skip to main content

Миграция с CircleCI на GitHub Actions

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

Введение

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

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

Дополнительные сведения см. в разделе Общие сведения о GitHub Actions.

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

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

  • Автоматический параллелизм тестов в CircleCI автоматически группирует тесты в соответствии с заданными пользователем правилами или историческими сведениями о времени. Эта функциональность не встроена в GitHub Actions.
  • Действия, выполняемые в контейнерах Docker, чувствительны к проблемам с разрешениями, так как в контейнерах используется другое сопоставление пользователей. Многих из этих проблем можно избежать, не используя инструкцию USER в Dockerfile. Дополнительные сведения о файловой системе Docker на GitHubразмещенных в среде runners см. в разделе "Использование средств выполнения, размещенных в GitHub".

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

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

Как CircleCI, так и GitHub Actions настраивают jobs в файле конфигурации с использованием аналогичного синтаксиса. При настройке зависимостей между заданиями с помощью requires в рабочем процессе CircleCI вы можете использовать эквивалентный синтаксис needs GitHub Actions. Дополнительные сведения см. в разделе Синтаксис рабочего процесса для GitHub Actions.

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

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

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

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

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

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

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

Дополнительные сведения о файловой системе Docker см. в разделе "Использование средств выполнения, размещенных в GitHub".

Дополнительные сведения о средствах и пакетах, доступных на GitHubразмещенных образов runner, см. в разделе "Использование средств выполнения, размещенных в GitHub".

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

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

Дополнительные сведения см. в разделе "[AUTOTITLE" и "Хранение сведений в переменных](/actions/security-guides/using-secrets-in-github-actions)".

Кэширование

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

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

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

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

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

- name: Cache node modules
  uses: actions/cache@v3
  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 для сохранения данных между заданиями

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

...

- attach_workspace:
    at: /tmp/workspace

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

- 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@v4
  with:
    name: homework

Дополнительные сведения см. в разделе Хранение и предоставление общего доступа к данным из рабочего процесса.

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

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

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

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

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

---
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 для использования баз данных и контейнеров служб

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@v4
      - 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

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

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

Ниже приведен пример из практики. В левой части показан фактический файл config.yml CircleCI для репозиторияthoughtbot/administrator. Справа показан эквивалент в GitHub Actions.

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

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

# Этот рабочий процесс использует действия, которые не сертифицированы 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@v4
      - name: Setup Ruby
        uses: eregon/use-ruby-action@ec02537da5712d66d4d50a0f33b7eb52773b5ed1
        with:
          ruby-version: ${{ matrix.ruby }}
      - name: Cache dependencies
        uses: actions/cache@v3
        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