Github actionsでRuby on railsプロジェクトのRspec / System test CIを動くようにしてみた

8月8日にGithub actionsでCI実行できるようになったと発表があってから早くも1ヶ月、先日ようやくbetaの申し込みが通って触れるようになったので、Ruby on railsのプロジェクトでRspecが動くようにしてみました。

作ったプロジェクトはこちらです。よかったらGithub actionsでのCI運用導入の際に参考にしてみてください。

github.com

git clone git@github.com:moritamori/github-actions-sample.git

実際のプロジェクトでは、個々必要なライブラリやサーバ構成が異なるので、主にGithub Actionsのワークフロー構文ページを参考に書いていくことになると思います。

GitHub Actionsのワークフロー構文 - GitHub ヘルプ

Github actionsでCI運用するメリット

現在運用している外部のCIサービスだと

  • Githubトークン共有による漏洩が心配
  • 設定が複雑になる
  • たまに動かなくなる

といったデメリットがありますよね。

Github actionsに移行することで、Githubトークンの発行やコピペ、不意なデータ消失によってトークン再設定など手間を無くすことができるのが嬉しい点です。 動かなくなった時とか、原因がよく分からないし、調べるのに時間かかったりするんですよね。。

設定内容

Railsルートに.github/workflows/rails-ci.ymlのようにyamlファイルを1つ配置するだけです。

name: Ruby

on: [push]

jobs:
  build:

    runs-on: ubuntu-latest

    services:
      postgres:
        image: postgres:11
        ports:
          - 5432:5432
        env:
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: postgres
        options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5

    steps:
    - uses: actions/checkout@v1

    - name: Set up Ruby 2.6
      uses: actions/setup-ruby@v1
      with:
        ruby-version: 2.6.3

    - name: install bundler2
      run: gem install bundler

    - name: Install dependent libralies
      run: sudo apt-get install libpq-dev

    - name: Bundle install
      run: bundle install --jobs 4 --retry 3

    - name: Setup Database
      run: |
        cp config/database.yml.github-actions config/database.yml
        bundle exec rake db:create
        bundle exec rake db:schema:load
      env:
        RAILS_ENV: test
        POSTGRES_USER: postgres
        POSTGRES_PASSWORD: postgres

    - name: Run rspec
      run: COVERAGE=true bundle exec rspec  --require rails_helper
      env:
        RAILS_ENV: test
        POSTGRES_USER: postgres
        POSTGRES_PASSWORD: postgres

設定内容の解説

1つずつ設定内容を解説していきます。

runs-on: ubuntu-latest

最新のubuntu-latestをイメージに使います。 CIの実行に必要なライブラリ等はインストールする必要があります。

services:
 postgres:
   image: postgres:11
   ports:
      - 5432:5432
    env:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
    options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5

postgresqlのイメージを使ってサービスを作ります。 Github Actions CI実行時には以下のように表示されlocalhostにポートをバインドされます。 f:id:moritamorie:20190908003045p:plain

オプションをしないとPostgresqlがシャットダウンしてしまうようなので、ヘルスチェックを行うオプションを付けています。 postgresql - How do I connect to a GitHub Action's job's service? - Stack Overflow

- uses: actions/checkout@v1

Githubからリポジトリのコードをチェックアウトします。

- name: Set up Ruby 2.6
  uses: actions/setup-ruby@v1
  with:
    ruby-version: 2.6.3

外部のアクションを利用して、Ruby 2.6.3をセットアップします。

- name: install bundler2
   run: gem install bundler

bundlerをインストールします。

- name: Bundle install
  run: bundle install --jobs 4 --retry 3

4並列でbundle installします。

- name: Setup Database
  run: |
    cp config/database.yml.github-actions config/database.yml
    bundle exec rake db:create
    bundle exec rake db:schema:load
  env:
    RAILS_ENV: test
    POSTGRES_USER: postgres
    POSTGRES_PASSWORD: postgres

github actionsのCI用のdatabase.ymlをコピーして、DB、テーブル作成しています。 config/database.yml.github-actionsの内容は以下のようになってます。

test:
  adapter: postgresql
  encoding: unicode
  database: github-actions-sample_test
  pool: 20
  username: <%= ENV["POSTGRES_USER"] %>
  password: <%= ENV["POSTGRES_PASSWORD"] %>
  host: localhost

postgres serviceはローカルホストのポートにバインドするので、host: localhostと書けばOKです。 hostを省略すると、CI環境内にあるソケットファイルで接続しようとするのでhostの指定が必要です。

最後に

- name: Run rspec
  run: COVERAGE=true bundle exec rspec  --require rails_helper
  env:
    RAILS_ENV: test
    POSTGRES_USER: postgres
    POSTGRES_PASSWORD: postgres

というようにrspecを実行しています。

envの設定がdb:create, db:schema:loadと被っているので、共通の設定として書く方法がないのかな。。と思ってますが、見つからなかった。 どなたか知っている方いましたらコメントくれると助かります!

感想

まだキャッシュ機能がないので、node_module内のパッケージやbundle installしたGemをキャッシュすることができず、毎回実行していて遅いのが残念です。。

11月が正式リリースなので、それまでにキャッシュが使えるようになっているといいなぁと思っています。 今後の展開が楽しみですね!

参考資料