はじめに
CircleCI と GitHub Actions の両方を使用すると、コードを自動的にビルド、テスト、発行、リリース、デプロイするワークフローを作成できます。 CircleCI と GitHub Actions は、ワークフロー構成でいくつかの類似点を共有します。
- ワークフローの設定ファイルはYAMLで書かれ、リポジトリに保存されます。
- ワークフローには1つ以上のジョブが含まれます。
- ジョブには1つ以上のステップもしくは個別のコマンドが含まれます。
- ステップもしくはタスクは、再利用とコミュニティとの共有が可能です。
詳しくは、「GitHub Actionsについて」をご覧ください。
主要な相違点
CircleCIから移行する際には、以下の差異を考慮してください。
- CircleCIの自動テストの並列性は、ユーザが指定したルールもしくは過去のタイミングの情報に基づいて、自動的にテストをグループ化します。 この機能は、 GitHub Actionsに組み込まれていません。
- コンテナはユーザのマッピングが異なるので、Dockerコンテナ内で実行されるアクションは、権限の問題に敏感です。
USER命令を Dockerfile で使用しないことにより、これらの問題の多くを回避できます。 GitHubホストランナー上の Docker ファイルシステムの詳細については、GitHub ホステッド ランナー を参照してください。
ワークフローとジョブの移行
CircleCI によって、workflows ファイルに __ が定義されます。これにより、1 つ以上のワークフローを構成できるようになります。
GitHub にはワークフローごとに 1 つのワークフロー ファイルが必要です。その結果、 workflowsを宣言する必要はありません。
config.yml に構成されている各ワークフローに対して、新しいワークフロー ファイルを作成する必要があります。
CircleCI と GitHub Actions の両方で、同様の構文を使用して構成ファイル内の jobs を構成します。 CircleCI ワークフローで requires を使用してジョブ間の依存関係を構成する場合は、同等の GitHub Actionsneeds 構文を使用できます。 詳しくは、「GitHub Actions のワークフロー構文」をご覧ください。
orbsからアクションへの移行
CircleCI と GitHub Actions の両方に、ワークフロー内のタスクを再利用して共有するためのメカニズムが用意されています。 CircleCIはorbsという概念を利用します。これはYAMLで書かれ、ワークフロー中で再利用できるタスクを提供します。 GitHub Actions には、JavaScript ファイルまたは Docker イメージを使用してビルドするアクションと呼ばれる、強力で柔軟な再利用可能なコンポーネントがあります。 GitHubの API や公開されているサードパーティ API との統合など、任意の方法でリポジトリと対話するカスタム コードを記述することで、アクションを作成できます。 たとえば、アクションで npm モジュールを公開したり、緊急の問題が発生したときに SMS アラートを送信したり、実稼働可能なコードをデプロイしたりできます。 詳しくは、「自動化の再利用」をご覧ください。
CircleCIは、YAMLのアンカーとエイリアスでワークフローの部分を再利用できます。 GitHub Actions では、再利用可能な YAML アンカーとエイリアスがサポートされ、さまざまな構成でジョブを実行するためのマトリックスも提供されます。 マトリックスの詳細については、「ワークフローでのジョブのバリエーションの実行」を参照してください。
Dockerイメージの利用
CircleCI と GitHub Actions の両方で、Docker イメージ内でのステップの実行がサポートされます。
CircleCIは、共通の依存関係を持つ一連のビルド済みのイメージを提供します。 これらのイメージには USER が circleci に設定されており、アクセス許可が GitHub Actionsと競合します。
GitHub Actionsに移行するときは、CircleCI の事前構築済みイメージから離れて移動することをお勧めします。 多くの場合、必要な追加の依存関係のインストールにアクションを使うことができます。
Docker ファイルシステムの詳細については、「GitHub ホステッド ランナー」を参照してください。
GitHubホストランナーイメージで使用できるツールとパッケージの詳細については、「GitHub ホステッド ランナー」を参照してください。
変数とシークレットの利用
CircleCI と GitHub Actions では、構成ファイルで変数を設定し、CircleCI または GitHub UI を使用してシークレットを作成できます。
詳細については、「変数リファレンス」および「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@v4
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@v5
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@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
詳しくは、「Docker サービス コンテナーとの通信」をご覧ください。
完全な例
以下は実際の例です。 左側には、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によって認定されていないアクションを使用します。
# それらはサードパーティによって提供され、
# 別個の利用規約、プライバシーポリシー、
# ドキュメントを参照してください。
# 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