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 컨테이너에서 실행되는 작업은 권한 문제에 민감합니다. _Dockerfile_의 USER 명령을 사용하지 않으면 많은 문제를 방지할 수 있습니다. GitHub 호스팅 실행기의 Docker 파일 시스템에 대한 자세한 내용은 "GitHub 호스팅 실행기 사용"을(를) 참조하세요.

워크플로 및 작업 마이그레이션

CircleCI는 config.yml 파일에서 workflows를 정의합니다. 이를 통해 둘 이상의 워크플로를 구성할 수 있습니다. GitHub Enterprise Cloud에는 워크플로당 하나의 워크플로 파일이 필요하므로 workflows를 선언할 필요가 없습니다. _config.yml_에 구성된 각 워크플로에 대한 새 워크플로 파일을 만들어야 합니다.

CircleCI와 GitHub Actions는 비슷한 구문을 사용하여 구성 파일에서 jobs를 구성합니다. CircleCI 워크플로에서 requires를 사용하는 작업 간의 종속성을 구성하는 경우 해당 GitHub Actions needs 구문을 사용할 수 있습니다. 자세한 내용은 "GitHub Actions에 대한 워크플로 구문"을 참조하세요.

작업으로 orbs 마이그레이션

CircleCI 및 GitHub Actions는 워크플로에서 작업을 재사용하고 공유하는 메커니즘을 제공합니다. CircleCI는 YAML로 작성된 orbs라는 개념을 사용하여 워크플로에서 다시 사용할 수 있는 작업을 제공합니다. GitHub Actions에는 JavaScript 파일 또는 Docker 이미지로 빌드하는 작업이라는 강력하고 유연하며 재사용 가능한 구성 요소가 있습니다. GitHub Enterprise Cloud의 API 및 공개적으로 사용 가능한 타사 API와의 통합을 포함하여 원하는 방식으로 리포지토리와 상호 작용하는 사용자 지정 코드를 써서 작업을 만들 수 있습니다. 예를 들어 작업은 npm 모듈을 게시할 수 있고 긴급한 이슈가 발생할 때 SMS 알림을 보낼 수 있으며 프로덕션 준비 코드를 배포할 수 있습니다. 자세한 내용은 "작업 만들기"을 참조하세요.

CircleCI는 YAML 앵커 및 별칭을 사용하여 워크플로 부분을 다시 사용할 수 있습니다. GitHub Actions는 행렬을 사용한 재사용성에 대한 가장 일반적인 요구 사항을 지원합니다. 행렬에 대한 자세한 내용은 "작업에 행렬 사용"을(를) 참조하세요.

Docker 이미지 사용

CircleCI 및 GitHub Actions는 Docker 이미지 내부의 실행 단계를 지원합니다.

CircleCI는 일반적인 종속성이 있는 미리 빌드된 이미지 집합을 제공합니다. 해당 이미지에는 USERcircleci로 설정되어 있으며 이로 인해 사용 권한이 GitHub Actions와 충돌합니다.

GitHub Actions로 마이그레이션할 때는 CircleCI의 미리 빌드된 이미지를 사용하지 않는 것이 좋습니다. 대부분의 경우 작업을 사용하여 필요한 추가 종속성을 설치할 수 있습니다.

Docker 파일 시스템에 대한 자세한 내용은 "GitHub 호스팅 실행기 사용"을(를) 참조하세요.

GitHub 호스팅 실행기 이미지에서 사용할 수 있는 도구 및 패키지에 대한 자세한 내용은 "GitHub 호스팅 실행기 사용"을(를) 참조하세요.

변수 및 비밀 사용

CircleCI와 GitHub Actions은(는) 구성 파일에서 환경 변수를 설정하고 CircleCI 또는 GitHub Enterprise Cloud UI를 사용하여 비밀을 생성할 수 있습니다.

자세한 내용은 "variables" 및 "GitHub Actions에서 비밀 사용"을(를) 참조하세요.

캐싱

CircleCI 및 GitHub Actions는 구성 파일에서 파일을 수동으로 캐시하는 메서드를 제공합니다.

다음은 각 시스템에 대한 구문의 예입니다.

캐싱을 위한 CircleCI 구문

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

캐싱을 위한 GitHub 액션 구문

- 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에는 CircleCI의 Docker 계층 캐싱(또는 DLC)에 해당하는 것이 없습니다.

작업 간에 데이터 유지

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

자세한 내용은 "서비스 컨테이너 정보"을(를) 참조하세요.

완성된 예제

다음은 실제 사례입니다. 왼쪽은 thoughtbot/administrator 리포지토리에 대한 실제 CircleCI _config.yml_입니다. 오른쪽은 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에서 인증되지 않은 작업을 사용합니다.
# 작업은 타사에서 제공하며
# 별도의 서비스 약관, 개인정보처리방침, 지원 설명서에서 규정됩니다.
# 참조하세요.

# 커밋 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