ノート: GitHubホストランナーは、現在GitHub Enterprise Serverでサポートされていません。 GitHubパブリックロードマップ で、計画されている将来のサポートに関する詳しい情� �を見ることができます。
はじめに
CircleCIとGitHub Actionsは、どちらも自動的にコードのビルド、テスト、公開、リリース、デプロイを行うワークフローを作成できます。 CircleCIとGitHub Actionsは、ワークフローの設定において似ているところがあります。
ワークフローの設定ファイルはYAMLで書かれ、リポジトリに保存されます。
ワークフローには1つ以上のジョブが含まれます。
ジョブには1つ以上のステップもしくは個別のコマンドが含まれます。
ステップもしくはタスクは、再利用とコミュニティとの共有が可能です。
詳しい情� �については、「GitHub Actionsの中� �的概念 」を参照してく� さい。
主要な差異
CircleCIから移行する際には、以下の差異を考慮してく� さい。
CircleCIの自動テストの並列性は、ユーザが指定したルールもしくは過去のタイミングの情� �に基づいて、自動的にテストをグループ化します。 この機能はGitHub Actionsには組み込まれていません。
コンテナはユーザのマッピングが異なるので、Dockerコンテナ内で実行されるアクションは、権限の問題に敏感です。 これらの問題の多くは、Dockerfile 中でUSER
命令を使わなければ回避できます。 GitHub Enterprise Serverホストランナー上の Docker のファイルシステ� に関する詳しい情� �については「GitHub Enterprise Server ホストランナーの仮想環境 」を参照してく� さい。
ワークフローとジョブの移行
CircleCIはconfig.yml ファイル中でworkflows
を定義するので、複数のワークフローを設定できます。 GitHub Enterprise Serverはワークフローごとに1つのワークフローファイルを必要とするので、結果としてworkflows
を宣言する必要がありません。 それぞれのワークフローごとに、config.yml で内で設定された新しいワークフローファイルを作成しなければなりません。
CircleCIとGitHub Actionsは、どちらも似た構文を使って設定ファイル中でjobs
を設定します。 CircleCIワークフロー中でrequires
を使ってジョブ間の依存関係を設定しているなら、相当するGitHub Actionsのneeds
構文を利用できます。 詳細については、「GitHub Actionsのワークフロー構文 」を参照してく� さい。
orbsからアクションへの移行
CircleCIとGitHub Actionsは、どちらもワークフロー中のタスクを再利用し、共有するための仕組みを提供しています。 CircleCIはorbsという概念を利用します。これはYAMLで書かれ、ワークフロー中で再利用できるタスクを提供します。 GitHub Actionsはアクションと呼ばれる強力で柔軟な再利用できるコンポーネントを持っており、これはJavaScriptファイルもしくはDockerイメージで構築できます。 GitHub Enterprise Server の API やパブリックに利用可能なサードパーティ API との統合など、リポジトリと相互作用するカスタ� コードを書いてアクションを作成することができます。 たとえば、アクションでnpmモジュールを公開する、緊急のIssueが発生したときにSMSアラートを送信する、本番対応のコードをデプロイすることなどが可能です。 詳細については、「アクションを作成する 」を参照してく� さい。
CircleCIは、YAMLのアンカーとエイリアスでワークフローの部分を再利用できます。 GitHub Actionsはビルドマトリックスを使って、再利用性についての一般的な要求のほとんどをサポートします。 ビルドマトリックスに関する詳細な情� �については「複雑なワークフローを管理する 」を参照してく� さい。
Dockerイメージの利用
CircleCIとGitHub Actionsは、どちらもDockerイメージ内でのステップの実行をサポートします。
CircleCIは、共通の依存関係を持つ一連のビルド済みのイメージを提供します。 これらのイメージではUSER
がcircleci
に設定されており、それがGitHub Actionsとの権限の衝突を引き起こすことになります。
GitHub Actionsへの移行に際しては、CircleCIの構築済みイメージから離脱することをおすすめします。 多くの� �合、必要な追� の依存関係のインストールにアクションを使うことができます。
Dockerのファイルシステ� に関する詳しい情� �については「GitHub Enterprise Serverホストランナーの仮想環境 」を参照してく� さい。
ー
GitHub ホストの仮想環境で使用できるツールとパッケージの詳細については、「GitHub ホストランナーの仕様 」を参照してく� さい。
変数とシークレットの利用
CircleCIとGitHub Actionsは、設定ファイル内での環境変数の設定と、CircleCIもしくはGitHub Enterprise ServerのUIを使ったシークレットの作成をサポートしています。
詳しい情� �については「環境変数の利用 」及び「暗号化されたシークレットの作成と利用 」を参照してく� さい。
キャッシング
CircleCIとGitHub Actionsは、設定ファイル中で手動でファイルをキャッシュする方法を提供しています。
以下は、それぞれのシステ� における構文の例です。
CircleCI
GitHub Actions
- restore_cache:
keys:
- v1-npm-deps-{{ checksum "package-lock.json" }}
- v1-npm-deps-
- name: Cache node modules
uses: actions/cache@v2
with:
path: ~/.npm
key: v1-npm-deps-${{ hashFiles('**/package-lock.json') }}
restore-keys: v1-npm-deps-
GitHub Actions キャッシュは、GitHub.com でホストされているリポジトリにのみ適用できます。 詳しい情� �については、「ワークフローを高速化するための依存関係のキャッシュ 」を参照してく� さい。
GitHub Actionsは、CircleCIのDocker Layer Caching(DLC)に相当する機能を持っていません。
ジョブ間でのデータの永続化
CircleCIとGitHub Actionsは、どちらもジョブ間でデータを永続化するための仕組みを提供しています。
以下は、CircleCIとGitHub Actionsの設定構文の例です。
CircleCI
GitHub Actions
- persist_to_workspace:
root: workspace
paths:
- math-homework.txt
...
- attach_workspace:
at: /tmp/workspace
- name: Upload math result for job 1
uses: actions/upload-artifact@v2
with:
name: homework
path: math-homework.txt
...
- name: Download math result for job 1
uses: actions/download-artifact@v2
with:
name: homework
詳しい情� �については「成果物を利用してワークフローのデータを永続化する 」を参照してく� さい。
データベースとサービスコンテナの利用
どちらのシステ� でも、データベース、キャッシング、あるいはその他の依存関係のための追� コンテナを含めることができます。
CircleCIでは、config.yaml で最初に挙げられているイメージが、コマンドの実行に使われる主要なイメージです。 GitHub Actionsは明示的なセクションを使います。主要なコンテナにはcontainer
を使い、追� のコンテナはservices
にリストしてく� さい。
以下は、CircleCIとGitHub Actionsの設定構文の例です。
CircleCI
GitHub Actions
---
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
- run: bundle install --path vendor/bundle
- run: dockerize -wait tcp://localhost:5432 -timeout 1m
- run: cp .sample.env .env
- run: bundle exec rake db:setup
- run: bundle exec rake
workflows:
version: 2
build:
jobs:
- ruby-26
...
- attach_workspace:
at: /tmp/workspace
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
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
steps:
- name: Setup file system permissions
run: sudo chmod -R 777 $GITHUB_WORKSPACE /github /__w/_temp
- uses: actions/checkout@v2
- 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 リポジトリのための実際のconfig.yml を示しています。 右は、同等のGitHub Actionsを示しています。
CircleCI
GitHub Actions
---
version: 2.1
commands:
shared_steps:
steps:
- checkout
- restore_cache:
name: Restore bundle cache
key: administrate-{{ checksum "Gemfile.lock" }}
- run: bundle install --path vendor/bundle
- save_cache:
name: Store bundle cache
key: administrate-{{ checksum "Gemfile.lock" }}
paths:
- vendor/bundle
- run: dockerize -wait tcp://localhost:5432 -timeout 1m
- run: cp .sample.env .env
- run: bundle exec rake db:setup
- run: bundle exec rake
default_job: &default_job
working_directory: ~/administrate
steps:
- shared_steps
- 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
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
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
steps:
- uses: actions/checkout@v2
- name: Setup Ruby
uses: eregon/use-ruby-action@477b21f02be01bcb8030d50f37cfec92bfa615b6
with:
ruby-version: ${{ matrix.ruby }}
- name: Cache dependencies
uses: actions/cache@v2
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