STORES でソフトウェアエンジニアをやっている @morihirok です。
先日 【増枠】10年超えRails開発の振り返りと未来 - 持続可能な開発の具体策 というイベントで STORES の Rails 開発について話してきました。
この発表後の懇親会でスライド第2章で触れた r7kamura/rubocop-todo-corrector についてのご質問をよくいただいたので、プロダクトブログで解説できればと思います。
rubocop-todo-corrector とは
Rails リポジトリにおいて、Linter であるところの RuboCop が入っていることが多いかと思います。 一方で、長期的に開発が続けられているリポジトリにおいては運用の途中で RuboCop が導入されることも多いのではないでしょうか。RuboCop 導入時点ですでに多くの違反箇所があり、なかなか運用を回しにくい状況になるというのは自分の経験上も珍しくない話かなと感じております。
そういう時に便利なのは --auto-gen-config
にて生成される .rubocop_todo.yml
です。違反している Cop とそのファイルをリスト化し、RuboCop の検知時に一旦このリストを無視してくれるというものです。これによって新規の違反を防ぎつつ、リスト化された既存コードの違反を徐々に改修できるというものです。
しかし、経験上多くの場合で .rubocop_todo.yml
はなかなか改善されずそのままになります。さらには .rubocop_todo.yml
が増えるという未解決事件が発生することもあります。.rubocop_todo.yml
の運用には多くの課題が発生しがち、というのは Rails リポジトリを開発した方であればうなずいていただけるのではないでしょうか。
そこで便利なのが r7kamura/rubocop-todo-corrector です。
これは GitHub Actions の Custom action です。rubocop_todo.yml
にリストアップされている違反のうち autocorrects offenses を自動で修正し、かつ rubocop_todo.yml
の内容を最新化してくれるというものです。
詳しくは README を読んでいただくとして、これのメリットについて自分が感じたことは以下です。
.rubocop_todo.yml
を修正する手間が省ける
Cop 指定で rubocop -A
しようとしたときに、オプションを覚えておらずググる、無事直したあと --auto-gen-config
というオプション自体を思い出せず再度ググる、ということを私はやりがちです。さらに無事全てのオプションを思い出しても --auto-gen-config
は一旦全ファイルに RuboCop を回す必要があるため、時間がかかります。時間がかかるので別の仕事をしているようなそうでもないような時間が流れ、その後Pull Reqestを作成する必要があります。怠惰で短気で傲慢である私にはここまでのステップを全てやり切ることができません。
rubocop-todo-corrector を使えばこれらの作業を全て GitHub Actions 上で自動で実施してくれるため、かなり楽ができます。
GitHub Actions に乗っかって様々なワークフローを組める
workflow dispatch によって GitHub Actions のページからボタンを押して起動することができたり、workflow dispatch の引数に特定の Cop を指定して修正してくれることができるので便利です。
さらに、スケジュール起動することもできますし、特定のアカウントやチームにレビューアサインすることもできます。つまり .rubocop_todo.yml
の修正を行うワークフローを組織に合った形で自由に組むことができるということです。
次の章で実際に STORES のとある巨大リポジトリで設定されている GitHub Actions の設定内容を紹介します。
STORES での導入例
最初にほぼそのまま GitHub Actions のワークフローの YAML ファイルを紹介します。
name: rubocop-todo-corrector on: schedule: - cron: '0 0 * * 1-4' # 09:00 JST 月曜〜木曜 workflow_dispatch: inputs: cop_name: description: Pass cop name if you want to pick a specific cop. required: false type: string ignore: description: Check this with cop_name if you want to ignore a specific cop. required: false type: boolean jobs: run: runs-on: ubuntu-latest steps: - uses: actions/create-github-app-token@v1 id: app-token with: app-id: ${{ vars.OUR_GITHUB_APP_ID }} private-key: ${{ secrets.OUR_GITHUB_PRIVATE_KEY }} owner: ${{ github.repository_owner }} - uses: r7kamura/rubocop-todo-corrector@v0 with: cop_name: ${{ inputs.cop_name }} gh_pr_create_options: "--reviewer our-org/rubocop-reviewers" github_token: ${{ steps.app-token.outputs.token }} ignore: ${{ inputs.ignore }}
と言ってもほぼそのまま README にある Example の内容を持ってくれば動きます。実際に我々の設定もそのようになっていることがご理解いただけるのではないでしょうか。
実際に私たちのワークフローとしては、毎日 1 Pull Request ずつ rubocop-todo-corrector が作ってくれて、それをランダムアサインが有効になっている GitHub Team にレビュー依頼するようになっています。その上でランダムアサインが当たったメンバーはその Pull Request をマージするかルール自体を disabled にするかのオーナーシップを持ってもらう、というルールにしました。
これによって徐々に .rubocop_todo.yml
の行数を減らすことができ、結果として私たちの .rubocop_todo.yml
からは autocorrects offenses を 0 件 にすることができました。
簡単に導入でき、かつワークしやすい仕組みだと思いますので、お困りの方がいらっしゃればぜひ試してみてください。
ところで autocorrects offenses じゃない .rubocop_todo.yml
がまだまだたくさんありまして、そういったものをしっかりと倒し切るようなエンジニアリングだったり GitLab のように CustomCop を活用して リポジトリの平和を守るようなエンジニアリングをやりたい方がいらっしゃいましたらぜひご連絡ください。
そうでない方でも STORES に興味ある方はご連絡ください!