Railsのコードをリーズナブルに自動コードレビューをしてもらうためのGithub Actions

## はじめに

[GitHub Actions](https://github.co.jp/features/actions)には[Market Place](https://github.com/marketplace?type=actions)でいろいろなActionが公開されていて、導入するだけでRailsプロジェクトで即使えます。ただ…そのままだと仮想マシンを何台も使うので、プライベートなリポジトリではあっという間にクレジットを消費してしまいます…。そこで、自分達のプロジェクト用に作ることにしました。

対象プロジェクト全体を解析し、常にクリーンに保つようにできればよいのですが、途中から入れたせいもあり、なかなかできず…。それなので最低限各々が出したプルリクエストに対してキレイにしようという方針です。

試したときのコードは[こちら](https://github.com/ken1flan/test_with_reviewdog)です。
https://github.com/ken1flan/test_with_reviewdog

## 今回使っているツール（ありがとうございます！）
- [reviewdog](https://github.com/reviewdog/reviewdog)
  - ↓の各静的解析ツールの出力からプルリクエストの分だけ抽出して、報告してくれます。
- [rubocop](https://github.com/rubocop-hq/rubocop)
  - コミュニティ内でよいとされているRubyの書き方に沿っているかチェックしてくれます。
- [reek](https://github.com/troessner/reek)
  - Rubyで書かれたコードの可読性/保守性/拡張性がよくないかチェックしてくれます。
- [brakeman](https://github.com/presidentbeef/brakeman)
  - Railsアプリケーションのセキュリティスキャナです。
- [haml-lint](https://github.com/sds/haml-lint)
  - HAMLがメンテナンスしやすくなっているかチェックしてくれます。
- [eslint](https://github.com/eslint/eslint)
  - Javascriptがメンテナンスしやすいかなどをチェックしてくれます。
- [stylelint](https://github.com/stylelint/stylelint)
  - CSSやSCSSがメンテナンスしやすいかなどをチェックしてくれます。

## コード
やっていることは大雑把に書くとこんな感じです。
reviewdogが内部で実行する静的解析ツールについては`.reviewdog.yml`に書いてあります。

1. 静的解析ツールを動かすために必要なRubyとNode.jsのインストール
2. プロジェクトで必要なライブラリ群のインストール
3. reviewdogのインストール
4. reviewdogの実行

```yml:.github/workflows/code_analysis.yml
name: code_analysis
on: [pull_request]
jobs:
  code_analysis:
    name: runner
    runs-on: ubuntu-latest
    env:
      REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    steps:
      - uses: actions/checkout@v2
      - uses: ruby/setup-ruby@v1
        with:
          ruby-version: 2.7.1
      - uses: actions/setup-node@v1
        with:
          node-version: 12.x
      - name: cache vendor/bundle
        uses: actions/cache@v1
        with:
          path: vendor/bundle
          key: bundle-${{ hashFiles('**/Gemfile.lock') }}
      - name: cache node_modules
        uses: actions/cache@v1
        with:
          path: node_modules
          key: yarn-${{ hashFiles('**/yarn.lock') }}
      - name: bundle install
        run: bundle check || bundle install --jobs=4 --retry=3 --path vendor/bundle
      - name: yarn install
        run: yarn install
      - name: install reviewdog
        uses: reviewdog/action-setup@v1
      - name: reviewdog
        run: reviewdog -reporter=github-pr-check
```

```yml:.reviewdog.yml
runner:
  rubocop:
    cmd: bundle exec rubocop
  brakeman:
    cmd: bundle exec brakeman --quiet --format tabs
  reek:
    cmd: bundle exec reek --single-line
  haml-lint:
    cmd: bundle exec haml-lint
  eslint:
    cmd: yarn run eslint app/**/*.js
  stylelint:
    cmd: yarn run stylelint app/**/*.{css,scss}
```

### 出力

[こんなふう](https://github.com/ken1flan/test_with_reviewdog/pull/2/checks
)に出力されます。
プルリクエスト内で見つかったものは見やすく表示されます。
`Filtered Findings`にプロジェクト内で見つかったものがすべて書かれているので…どれくらい課題が溜まっているかも見れるので、気にしているとよいかもしれません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14380/955af99e-cea0-e306-f386-7d7c879406ff.png)


### ハマったところ
#### Rubyのセットアップはruby/setup-rubyを！

GitHub謹製の[actions/ruby](https://github.com/actions/setup-ruby)はパッチバージョンを指定できず、最新が少し遅れて使われています。
GemfileでRubyのバージョンを指定したりすると思うのですが、これと相性が悪く、バージョンがズレてしまうことがたびたびあり、bundle installに失敗してしまいます。

Rubyコミュニティがメンテナンスしている[ruby/setup-ruby](https://github.com/ruby/setup-ruby)はパッチバージョンの指定もできるので、こちらを使うようにしました。


## 恥ずかしいからプルリクエストに出す前に直したい！

自PCに`reviewdog`をインストールして、↓のようにすれば事前に確認できます。

```console
$ reviewdog --diff='git diff main'
```

## 最後に

こういうのは人間にお願いすると自分もレビュワーもツライので、機械にお願いするのが一番です。指摘されると、たしかに…ということが多いので、自分だけでは拾いきれない、よい書き方を学べて助かっています。