Rubocopを一応入れているのに、滅多に動かしてなくてあんまり意味を成していなかった。issueにずっとあったCIにRubocopを取り入れるというやつに着手しようと思ってようやく取り組み始めた。
reviewdogを知る
CircleCIのワークフローにRubocopのチェックを入れて、自動的にコメントをしてもらいたいなぁと思って調べていたら、reviewdogを知った。
blog.toshimaru.net
自分がやりたかったことはまさにこれだったので、これを参考にすることに。
reviewdogのインストールは本家を参考にした。
github.com
バイナリで配布もされているが、goenv
でgoを入れているので、go getを使って入れた。
$ go get -u github.com/haya14busa/reviewdog/cmd/reviewdog
reviewdogが実行できない場合はパスが通ってないってことなので、パスを通しましょう。
その前にrubocopのルールを決めたい
Rubocopのルールをよく把握してなかったので、チームで以前に作ったルールを実行してみたら、かなりの量で怒られたので、たぶんプロジェクトにルールがまだ合ってないなと思ったので、一から作り直そうと思った。
とはいえ、ルールの数も途方もないだろうし、有名な指針があればいいかなと思って調べ始めたら、onkさんのRubocopの記事を見つけた。
blog.onk.ninja
スモールスタートする
スモールスタートの仕方が書いてあったので、まずはそれを検証することに。
現在の.rubocop.ymlを.rubocop.old.ymlに変更
bundle exec rubocop --auto-gen-config
を実行して.rubocop.ymlと.rubocop_todo.ymlを生成する
bundle exec rubocop --parallel
を実行して指摘がないことを確認する
一旦コミットする
ローカルでreviewdogを実行してみる
CircleCIでreviewdogを実行してみる
という方針を立てた。
reviewdogが動かない(俺の勘違い)
とりあえず、rubocop.old.ymlで怒られていたルールを実行してみると、たくさん指摘された。
それをreviewdogに食わせてみることに。
$ bundle exec rubocop --parallel --only Layout/SpaceAroundEqualsInParameterDefault | reviewdog -f = rubocop -diff =" git diff "
何も表示されない!
しかしこれは当然の話で、reviewdogは変更のあった行でrubocopの指摘がある場合のみ通知してくる。まだコード自体は一切変えていなかったからだ。そこで、敢えてコードをルールに違反するコードに変えたところ、ちゃんと指摘された。
CircleCIでreviewdogを動かす
reviewdogを実行するワークフローを定義する
上のほうで参考にしたサイトの通りにすれば動くので、特に書くことはない…んだけど、一応書く。ちなみにcircle.ymlのフォーマットはCircleCI 2.1なのであしからず。
executorsのruby のdocker imageの環境変数 に、reviewdogのバージョンを指定する。
executors :
default :
docker :
- image : patorash/circle_ci_ruby:2.5.3-node-browsers-pg11
environment :
RAILS_ENV : test
REVIEWDOG_VERSION : 0.9.11
次に、reviewdogを実行するcommandsを定義する。
commands :
run_reviewdog :
steps :
- run :
name : Install reviewdog
command : |
curl -fSL https://github.com/haya14busa/reviewdog/releases/download/$REVIEWDOG_VERSION/reviewdog_linux_amd64 -o reviewdog
chmod +x ./reviewdog
- run : bundle exec rubocop | ./reviewdog -f=rubocop -reporter=github-pr-review
次に、workflowを定義。テストが実行される前にrobocopで検査して、問題があればそこで止めるようにする。まだジョブの定義はしていないが、とりあえずワークフローを先に書く。
workflows :
build :
jobs :
- prepare_test
- reviewdog :
requires :
- prepare_test
- retry_failed_test :
requires :
- reviewdog
- test :
requires :
- retry_failed_test
しかしこれだとreviewdogが通らないとテストすら実行されないので、緊急時とかにうざいかもしれない…。そのときは、retry_failed_testのrequiresをprepare_testに変えてしまうほうがいいかも…とこの記事を書きながら思った。
さて、reviewdogジョブを定義する。もうcommandsを定義しているので、それを呼び出すだけである。一応prepare_testも載せておくが、やってることはcommand名から想像してほしい。
jobs :
prepare_test :
parallelism : 1
executor : default
steps :
- checkout
- restore_node_module_cache
- restore_bootsnap_cache
- ruby-orbs/bundle-install
- yarn_install
- save_node_module_cache
- save_code_cache
reviewdog :
parallelism : 1
executor : default
steps :
- restore_code_cache
- run : bundle --path vendor/bundle
- run_reviewdog
これでcircle.ymlは完成。
あとはgithub でreviewdogでコメントさせるユーザーのトーク ンを環境変数 REVIEWDOG_GITHUB_API_TOKEN
に定義しなくてはならない。
githubのアクセストークンの取得ページ に行く。
この時、もし自分のアカウントで取得すると、reviewdogのコメントをしてくるのが自分のアカウントになる。別に問題ない人はそれでいいが、個人アカウントで機械的 にであっても個人のアイコンがある状態でコメントされると、なんか殺伐としそう…。なので、bot 用の別アカウントを作るなりして、そいつにコメントしてもらうほうがいいと思う。onkさんの記事でも、カーチャンに指摘してもらうみたいに書いてた。
話を元に戻すが、repoにチェックを入れてアクセストーク ンを発行する。
github のアクセストーク ンを発行する。repoにチェックを入れる。
発行したアクセストーク ンは、CircleCIのプロジェクト毎の環境変数 に保存しておく。
CircleCIの設定画面から環境変数 を設定する
これで完了。
あとは、先ほど設定したcircle.ymlを含むbranchをpushして、PRにしてreviewdogがコメントするのを確認すればよし。ちゃんとCIのワークフローがそこで止まることも確認する。
reviewdogによってworkflowが停止していることを確認
そして、指摘された点を修正し直して、ワークフローが全部通ることを確認する。
reviewdogの指摘を修正してワークフローが通ることを確認
オーケー、完成だ。
今後の方針
CircleCIのworkflowにreviewdogを入れられたのは一歩前進。とはいえ、rubocopはスモールスタートの設定をしただけなので、ルールを決めていく必要がある。onkさんが公開しているonkcopが参考になりそうなので、それを読みながら一部を自分のルールで上書きしていこうと思う。
github.com