やりたいこと
- gemのキャッシュ
- yarnライブラリのキャッシュ
- RSpecの実行
- システムスペックの実行
- システムスペック失敗時のスクショをArtifactとしてアップロード
- DBはmysql5.7
結論
こんなymlを作りました。
name: RUN Rspec
on:
pull_request:
branches:
- master
jobs:
build:
runs-on: ubuntu-latest
services:
mysql:
image: mysql:5.7
env:
MYSQL_USER: root
MYSQL_ALLOW_EMPTY_PASSWORD: yes
container:
image: ruby:2.6.4
env:
RAILS_ENV: test
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: bundle install
run: |
gem install bundler
bundle install --path vendor/bundle --quiet --jobs 4 --retry 3
- name: yarn install
run: yarn install
- name: set database.yml
run: cp -v config/database.ci.yml config/database.yml
- name: db create
run: bundle exec rails db:create db:schema:load --trace
- name: run rspec
run: bundle exec rspec
- name: Archive rspec result screenshots
if: failure()
uses: actions/upload-artifact@v1
with:
name: rspec result screenshots
path: tmp/screenshots/
以下はまったことや学んだこと
ruby2.6.4がないと言われる
rubyのセットアップはactions/setup-ruby@v1
を使うといくつかの記事で紹介されていましたが、2019/12/30現在、2.6系だと2.6.3しか使えないらしいです。
- name: Set up Ruby 2.6
uses: actions/setup-ruby@v1
with:
ruby-version: 2.6.4
なので普通にcontainerイメージをつかうことにしました。
container:
image: ruby:2.6.4
gemをキャッシュしたい
gemをキャッシュしたい場合はこう書けば良さそうです。
- uses: actions/checkout@v1
- uses: actions/cache@v1
with:
path: vendor/bundle
key: bundle-${{ hashFiles('**/Gemfile.lock') }}
yarnライブラリをキャッシュしたい
そもそもyarnを入れる必要があります。
- 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
bundleと同じようにyarnもキャッシュさせます。
- uses: actions/cache@v1
with:
path: node_modules
key: yarn-${{ hashFiles('**/yarn.lock') }}
mysql5.7を使いたい
services:
mysql:
image: mysql:5.7
env:
MYSQL_USER: root
MYSQL_ALLOW_EMPTY_PASSWORD: yes
datbase.ci.ymlを作ってそれをCI上でdatabase.ymlにリネームして使ってます。
- name: set database.yml
run: cp -v config/database.ci.yml config/database.yml
default: &default
adapter: mysql2
encoding: utf8mb4
charset: utf8mb4
collation: utf8mb4_general_ci
pool: 5
host: mysql
port: 3306
username: root
password:
test:
<<: *default
database: circle_test
host名をmysql
にしないとうまくmysqlに接続できませんでした。
usernameはMYSQL_USER
部分と合わせる必要があるでしょう。
passwordは不要なのでMYSQL_ALLOW_EMPTY_PASSWORD: yes
としてます。
test環境としてrailsコマンドを打ちたい
container:
image: ruby:2.6.4
env:
RAILS_ENV: test
当然ちゃ当然ですが、bundle exec rails db:create
コマンドなんかもtest環境で行いたいので環境変数としてRAILS_ENV: test
を設定しました。
システムスペックを動かしたい
プロジェクトではheadless_chrome
を使ってるのですが、特に何も考えずCIを動かすとこのエラーが出ました。
Webdrivers::BrowserNotFound:
Failed to find Chrome binary.
これはChromeをインストールすれば解消されました。
- 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
が、次のエラーが出ました。
Selenium::WebDriver::Error::UnknownError:
unknown error: Chrome failed to start: exited abnormally
(unknown error: DevToolsActivePort file doesn't exist)
(The process started from chrome location /usr/bin/google-chrome is no longer running, so ChromeDriver is assuming that Chrome has crashed.)
このオプションをdriven_byに追加してあげればうまく動きました。
driven_by :selenium, using: :headless_chrome do |driver_options|
driver_options.add_argument('--disable-dev-sim-usage')
driver_options.add_argument('--no-sandbox')
end
システムスペックの結果をArtifactとしてアップロードしたい
- name: Archive rspec result screenshots
if: failure()
uses: actions/upload-artifact@v1
with:
name: rspec result screenshots
path: tmp/screenshots/
システムスペックが成功すると tmp/screenshots/
が作られないので no such file or directoryのエラーがでます。なので if: failure()
を書いて『直前のジョブが失敗したら=RSpecが失敗したら』という条件を課しています。ただ、システムスペックは通ったけどモデルスペックは通らなかった、という場合でも動いてしまうはずなので何か他の方法をとる必要があると思われます。
CircleCIに比べてちょっと遅い気がしますが今後改善されていくことを期待します。
GitHub上で全て完結するのはとても良いですね。
今回作ったものはこちらです
https://github.com/DaichiSaito/github-action-example