12
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Rails + GitHub Actionsではまったこと

Last updated at Posted at 2019-12-31

やりたいこと

  • gemのキャッシュ
  • yarnライブラリのキャッシュ
  • RSpecの実行
  • システムスペックの実行
  • システムスペック失敗時のスクショをArtifactとしてアップロード
  • DBはmysql5.7

結論

こんなymlを作りました。

example.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
database.ci.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に追加してあげればうまく動きました。

spec_helper.rb
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

12
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?