Github Actions 使ってますか?
まだβ版ですし本稼働させている人は多くないと思いますが、 2019年11月中旬頃にようやくキャッシュ機構が実装されるそうなので、 CircleCI 非課金勢としては非常に楽しみにしています。
宣言通り実装されたので追記しました!
Rails の CI を Github Actions で動かすにあたって、システムテスト周りで少しハマったので、導入方法をまとめてみました。
Rails プロジェクトの初期化
いつも通り rails new していきます。
今回は Rails 標準の minitest を使っていますが RSpec の場合でもほぼ変わりません。
$ mkdir rails_on_github_actions
$ bundle init
# frozen_string_literal: true
source "https://rubygems.org"
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
gem "rails"
$ bundle
$ bundle exec rails new .
$ bin/rails db:migrate
テストをするために user リソースを追加しておきます。
$ bin/rails g scaffold users
$ bin/rails db:migrate
$ bin/rails test
Workflow の作成
Github Actions でテストを走らせるために、 workflow を作っていきます。
scaffold によってシステムテストも作られていますが、一旦ここではブラウザを使わないテストだけ扱います。
name: Test
on: [push]
jobs:
build:
runs-on: ubuntu-latest
container:
image: ruby:2.6.4
steps:
- uses: actions/checkout@v1
- name: Set up node and yarn
run: |
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
curl -sL https://deb.nodesource.com/setup_12.x | bash -
apt install -y nodejs yarn
- name: Build and setup
run: |
bundle -j 4
bin/rails yarn:install db:setup assets:precompile
bin/rails test
これを push すると workflow が自動的に走ります。
System Test
Github Actions で system test を実行するため、 Chrome をインストールするスクリプトを workflow に追加しています。
name: Test
on: [push]
jobs:
build:
runs-on: ubuntu-latest
container:
image: ruby:2.6.4
steps:
- uses: actions/checkout@v1
- name: Set up YARN and NodeJS
run: |
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
curl -sL https://deb.nodesource.com/setup_12.x | bash -
apt install -y yarn nodejs
- name: Install chrome
run: |
wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | apt-key add -
echo 'deb http://dl.google.com/linux/chrome/deb/ stable main' | tee /etc/apt/sources.list.d/google-chrome.list
apt update -y
apt install -y google-chrome-stable
- name: Build
run: |
bundle -j 4
bin/rails yarn:install db:setup assets:precompile
- name: Run test
run: |
bin/rails test
- name: Run system test
run: |
bin/rails test:system
ローカル環境なら driven_by :selenium_chrome_headless
だけで Headless Chrome を使ってテストできますが、 Github Actions のような Docker 環境だと /dev/shm
のサイズ割り当てが小さいため、それを使わないようにするため disable-dev-shm-usage
という起動オプションを追加しています。また、 no-sandbox
は Docker 環境のように root 権限で Chrome を立ち上げるのに必要なオプションです。
require "test_helper"
class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
driven_by :selenium, using: :headless_chrome, screen_size: [1400, 1400] do |driver_options|
driver_options.add_argument('--disable-dev-shm-usage')
driver_options.add_argument('--no-sandbox')
end
end
これを push すると Github Actions で system test も無事に成功します。
MySQL
実際のアプリケーションでは SQLite を使うことはほぼ無いと思うので、 Github Actions でも MySQL を使ってみます。
Gemfile に mysql2 を追加
gem 'mysql2'
database.yml を MySQL 用に更新します。ほぼデフォルトですが、ホスト名とパスワードを環境変数で設定できるようにしています。
default: &default
adapter: mysql2
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: root
charset: utf8mb4
collation: utf8mb4_bin
encoding: utf8mb4
password: <%= ENV.fetch('MYSQL_ROOT_PASSWORD', '') %>
host: <%= ENV.fetch('MYSQL_HOST', 'localhost') %>
development:
<<: *default
database: rails_on_github_actions_development
test:
<<: *default
database: rails_on_github_actions_test
production:
<<: *default
database: rails_on_github_actions_production
テストが正常に動くかローカルで確認しておきます。
$ bin/rails db:create
$ bin/rails test
$ bin/rails test:system
workflow の services に MySQL を追加します。root のパスワードは環境変数で設定します。
services で追加したコンテナのホスト名はサービス名と同じになるようです。
name: Test
on: [push]
jobs:
build:
runs-on: ubuntu-latest
services:
mysql:
image: mysql:5.7
env:
MYSQL_ROOT_PASSWORD: password
container:
image: ruby:2.6.4
env:
MYSQL_HOST: mysql
MYSQL_ROOT_PASSWORD: password
steps:
- uses: actions/checkout@v1
- name: Set up yarn and node
run: |
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
curl -sL https://deb.nodesource.com/setup_12.x | bash -
apt install -y yarn nodejs
- name: Install chrome
run: |
wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | apt-key add -
echo 'deb http://dl.google.com/linux/chrome/deb/ stable main' | tee /etc/apt/sources.list.d/google-chrome.list
apt update -y
apt install -y google-chrome-stable
- name: Build
run: |
bundle -j 4
bin/rails yarn:install db:setup assets:precompile
- name: Run test
run: |
bin/rails test
- name: Run system test
run: |
bin/rails test:system
これを push すると Github Actions で MySQL を使ったテストが無事に成功します。
services と環境変数を書き換えれば postgres などの他のデータベースも使用できるかと思います。
キャッシュ
Actions リリース当時はキャッシュ機構が実装されておらず、自前でキャッシュ機構を用意しない限りビルド毎に gem や Node モジュールのインストールが必要でしたが、actions/cache が2019年11月に提供され、一般的な CI サービスと同等レベルに使えるサービスになりました。
ここでは前回の MySQL のサンプルをベースにして、Gemflie.lock と yarn.lock のハッシュ値をキャッシュのキーとして使用し、ライブラリに変更がなければ余計なダウンロードが行われないようにしてみます。
name: Test
on: [push]
jobs:
build:
runs-on: ubuntu-latest
services:
mysql:
image: mysql:5.7
env:
MYSQL_ROOT_PASSWORD: password
container:
image: ruby:2.6.4
env:
MYSQL_HOST: mysql
MYSQL_ROOT_PASSWORD: password
steps:
- uses: actions/checkout@v1
- uses: actions/cache@v1
with:
path: vendor/bundle
key: bundle-${{ hashFiles('**/Gemfile.lock') }}
- uses: actions/cache@v1
with:
path: node_modules
key: yarn-${{ hashFiles('**/yarn.lock') }}
- name: Set up yarn and node
run: |
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
curl -sL https://deb.nodesource.com/setup_12.x | bash -
apt install -y yarn nodejs
- name: Install chrome
run: |
wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | apt-key add -
echo 'deb http://dl.google.com/linux/chrome/deb/ stable main' | tee /etc/apt/sources.list.d/google-chrome.list
apt update -y
apt install -y google-chrome-stable
- name: Build
run: |
bundle -j 4 --path vendor/bundle
bin/rails yarn:install db:setup assets:precompile
- name: Run test
run: |
bin/rails test
- name: Run system test
run: |
bin/rails test:system
詳細なドキュメントはこちらになります。上限2GBってなかなか太っ腹ですね。
https://help.github.com/en/actions/automating-your-workflow-with-github-actions/caching-dependencies-to-speed-up-workflows
今回作ったサンプルプロジェクトは Github に置いてますので良かった参考にしてみてください。
https://github.com/d-mato/rails_on_github_actions