GitHub ActionsでRubyプロジェクトのCIをしてみた

エントリ要約

はじめに

しばらく前からGitHub Actionsがパブリックベータとして公開されていた。 申請をしてから結構待つ必要があった(1〜2週間かかったと思う)が利用できるようになったので、自前のRubyプロジェクトのリポジトリに適用してみた。 なお今は申請するとすぐ利用できるとのこと。

基本設定

いずれ何もしなくても使えるようになるのかもしれないが、現時点では申請が必要。
こちらからできる。

申請が通るとGitHubリポジトリ上部に"Actions"というタブが表示される。

GitHub Actionsの設定ページ
GitHub Actionsの設定ページ

ここからワークフローの雛形を選べるので、"Ruby"を選択。 ワークフローの設定ファイルの編集画面になるので、適宜編集してコミット。 あとはこのファイルをカスタムしていく。

テスト

jobs.build.stepsを以下のようにする。

jobs:
  build:
    # 省略
    steps:
    - uses: actions/checkout@v1

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

    - name: Build and test
      run: |
        # 依存するgemのインストールに必要なOSパッケージのインストールなどはこのあたりに記載する
        # sudo apt-get update
        # sudo apt-get install -y libsqlite3-dev
        gem install bundler
        bundle install --jobs 4 --retry 3
        # rspec を実行する
        bundle exec rspec

マトリックステスト

複数のバージョンのrubyでテストする場合はjobs.build.strategy.matrixを追加し、jobs.build.stepsSet Up Ruby 2.6アクションのruby-versionを書き換える。

jobs:
  build:
    runs-on: ubuntu-latest

    # ここを追加。なお現時点で利用できる Ruby は 2.3.7, 2.4.6, 2.5.5, 2.6.3 の模様
    strategy:
      matrix:
        ruby:
          - 2.5.x
          - 2.6.x

    # 略

    steps:
    - uses: actions/checkout@v1

    - name: Set up Ruby 
      uses: actions/setup-ruby@v1
      with:
        # matrix.ruby に置き換える
        ruby-version: ${{ matrix.ruby }}

依存するgemをマトリックスにする場合は、bundlerの環境変数BUNDLE_GEMFILEGemfileを指定して実行する機能を利用する。 自力で頑張ることもできるだろうが、thoughtbot/appraisalを使えばローカルでの複数バージョンテスト一括実行も楽に行えるのでおすすめ。

    strategy:
      matrix:
        ruby:
          - 2.5.x
          - 2.6.x

        gemfile:
          - rails_5.2.gemfile
          - rails_6.0.gemfile

    # 略

    steps:
      # 略

      - name: Build and test
        # env を追加
        env:
          BUNDLE_GEMFILE: gemfiles/${{ matrix.gemfile }}
        run: |
          gem install bundler
          bundle install --jobs 4 --retry 3
          bundle exec rspec

Code Climateでテストカバレッジを確認する

"Build and test"アクションの前後にcc-test-reporterを実行するアクションを追加する。

事前にCode Climate側でリポジトリを追加し、Test Reporter IDを取得しておく必要がある。
リポジトリSettingSecretsに登録しておくとYAML内で参照できるようになるため、CC_TEST_REPORTER_IDとして登録する。

    steps:
    - uses: actions/checkout@v1
    - name: Set up Ruby
      uses: actions/setup-ruby@v1
      with:
        ruby-version: ${{ matrix.ruby }}

    # 
    - name: Setup Code Climate test-reporter
      env:
        CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
      run: |
        curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
        chmod +x ./cc-test-reporter
        ./cc-test-reporter before-build

    - name: Build and test
      env:
        BUNDLE_GEMFILE: gemfiles/${{ matrix.gemfile }}
      run: |
        gem install bundler
        bundle install --jobs 4 --retry 3
        bundle exec rspec

    - name: Upload coverage
      env:
        CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
        # GIT_COMMIT_SHA は設定しなくても参照できているが、ドキュメントに GIT_BRANCH と共に指定するよう記載されているので一応セットしておく
        GIT_COMMIT_SHA: ${{ github.sha }}
      run: |
        # ブランチ名のみを保持する環境変数や context は見つからなかったので、$GIT_BRANCH から抽出する
        GIT_BRANCH=$(echo $GITHUB_REF | sed -e 's|.*/||') ./cc-test-reporter after-build

なお、テストカバレッジを取得するにはテスト実行時にSimpleCovも実行しておかなければならない。

# spec/spec_helper.rb

require 'simplecov'
SimpleCov.start

テストカバレッジの取得をCI時のみに限る場合は以下のようにする。

if ENV["COVERAGE"]
  require 'simplecov'
  SimpleCov.start
end
    - name: Build and test
      env:
        BUNDLE_GEMFILE: gemfiles/${{ matrix.gemfile }}
        # COVERAGE をセット
        COVERAGE: true
      run: |
        gem install bundler
        bundle install --jobs 4 --retry 3
        bundle exec rspec

これでCode Climateで結果を確認できるようになる。 同時にRepo SettingsBadgesでバッヂも取得できるので、READMEに追加する。