참고: GitHub 호스트 실행기는 현재 GitHub Enterprise Server에서 지원되지 않습니다. GitHub public roadmap에 예정된 향후 지원에 대해 자세히 알아볼 수 있습니다.
소개
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 Server에는 워크플로당 하나의 워크플로 파일이 필요하므로 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 Server의 API 및 공개적으로 사용 가능한 타사 API와의 통합을 포함하여 원하는 방식으로 리포지토리와 상호 작용하는 사용자 지정 코드를 써서 작업을 만들 수 있습니다. 예를 들어 작업은 npm 모듈을 게시할 수 있고 긴급한 이슈가 발생할 때 SMS 알림을 보낼 수 있으며 프로덕션 준비 코드를 배포할 수 있습니다. 자세한 내용은 "자동화 공유 중"을 참조하세요.
CircleCI는 YAML 앵커 및 별칭을 사용하여 워크플로 부분을 다시 사용할 수 있습니다. GitHub Actions는 행렬을 사용한 재사용성에 대한 가장 일반적인 요구 사항을 지원합니다. 행렬에 대한 자세한 내용은 "워크플로에서 작업 변형 실행"을(를) 참조하세요.
Docker 이미지 사용
CircleCI 및 GitHub Actions는 Docker 이미지 내부의 실행 단계를 지원합니다.
CircleCI는 일반적인 종속성이 있는 미리 빌드된 이미지 집합을 제공합니다. 해당 이미지에는 USER
가 circleci
로 설정되어 있으며 이로 인해 사용 권한이 GitHub Actions와 충돌합니다.
GitHub Actions로 마이그레이션할 때는 CircleCI의 미리 빌드된 이미지를 사용하지 않는 것이 좋습니다. 대부분의 경우 작업을 사용하여 필요한 추가 종속성을 설치할 수 있습니다.
Docker 파일 시스템에 대한 자세한 내용은 "GitHub 호스팅 실행기 사용"을(를) 참조하세요.
GitHub 호스팅 실행기 이미지에서 사용할 수 있는 도구 및 패키지에 대한 자세한 내용은 "GitHub 호스팅 실행기 사용"을(를) 참조하세요.
변수 및 비밀 사용
CircleCI와 GitHub Actions은(는) 구성 파일에서 환경 변수를 설정하고 CircleCI 또는 GitHub Enterprise Server UI를 사용하여 비밀을 생성할 수 있습니다.
자세한 내용은 "변수에 정보 저장" 및 "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@v3
with:
name: homework
path: math-homework.txt
...
- name: Download math result for job 1
uses: actions/download-artifact@v3
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