はじめに
こんにちは、リブセンスの不動産ユニットでIESHIL(イエシル)の開発をしている須貝です。主にアプリケーションレイヤでがんばっています。
イエシルは主にマンションにまつわる大量のデータを扱うサービスなので私もTreasureData上でクエリを書いたりするんですが、イケてないクエリを書いてメモリを400GBくらい消費してしまいjobをTDの中の人にkillしていただいたのが今年の印象的なやらかしです。本当にすみませんでした
さて、イエシルの開発チームは日々ユーザーに価値を提供すべく機能開発をゴリゴリとやっています。その一方でさらに高速でユーザーに価値を提供するために自分たちの生産性を上げたいとも思っています。いわゆる「カイゼン」というやつです。そのために、新しいツールを入れてみたり、外部のサービスを導入したりして自分たちの働く環境を良くしようとしています。というわけで2018年を振り返ってチームの開発効率を高めるために行ったカイゼンをピックアップしてみなさまにご紹介しようと思います。
と、すこし大げさな感じで言っておいてなんですが、つまるところCIで各種Lintを走らせまくったよという話なんであまり期待しないでください
前提
- イエシルはHeroku Private Spaces上で動いている。
- イエシルはRuby on Rails(5.2.2)を使っている。
- ソースコードの管理、レビューにはGitHubを使っている。
- CIはCircleCIを利用している。
- アプリケーション側の開発者は3〜4名。
2018年にやってきたこと
以下、今年の最初のほうから順に振り返っていきたいと思います。
CircleCIを1.0から2.0にバージョンアップした
- CircleCI1.0は今年の夏で終了してしまったので、CircleCIを使われているチームの方は必ず今年通る道だったかと思います。
- ただ、私たちは「CircleCI1.0が終わるよ〜」とアナウンスがある前に対応していたので先にやっておいて良かったなと。「終わるよ〜」って言われて対応すると義務感あってなんか嫌ですからね。親に「宿題やれー」って言われたらやりたくないみたいな。
- 何にせよこの2.0以降が後に続く各種LintをCircleCIで走らせていく礎となりました。これが2018年の1月にやったこと。
- Orbや2.1はまだ試していないので2019にやっていきたいす。
slim-lintをCircleCIで走らせるようにした
- 当時、うちのチームではすでにrubocopをCircleCIで実行するようになっていました。
- で、slim-lintはその名の通り、slimのlintです。4月でチームを卒業した方が置き土産的にslim-lintを導入していったので、どうせならCI上で実行しようと思ってやりました。
- ただ、導入当初はそのままCI上で実行すると警告が大量に出てしまうので、結果は無視するようにしていました。以下のような感じです。
- run:
name: Run Slim-Lint
command: bundle exec slim-lint app/views/**/*.slim || echo 'Too many warnings...'
- ここは私の持論なんですが、いきなりCI上でLintを有効にして警告が出まくるとチーム内で拒否反応が出る可能性が高いので、いったん結果は無視しつつもとりあえずCI上で実行するようにしておく、というのが新規にLintを導入するときには良いのかなと思います。
- その後、既存のファイルはとりあえず
.slim-lint.yml
でignoreするようにしておき、新規ファイルのみチェックするようにしました。 - で、既存のLintが通らないやつらは後から時間があるときに対応していく、と。
- 地道に既存のファイルを修正していくのは心が折れるんですが、この辺**いい感じに進捗を可視化してモチベーションを維持する仕組みづくりができないか?**というのが今考えていることです。2019年にがんばります。
FactoryBot.lintをCircleCI上で走らせるようにした
- FactoryBot自体の説明は省略しますが、雑に説明するとテストデータをいい感じに用意するためのgemです。
- 実はこのFactoryBotにもlintがあります。説明を省略するために当時のPRのスクリーンショットを貼っときます。
- 改めて自分のPRとか見てると、書きっぷりがほんと偉そうでイラッとしますね。これもカイゼン対象だと思った。
- 例によって既存のやつは後から直していくスタイルです。やっぱりいきなり全部直すの無理なんで、まずは新規に変なのが入ってこないようにしておくというのが常套手段なんじゃないかなと私は思います。
huskyを導入してremoteにpushする前にローカルで軽くLintを走らせるようにした
- さて今年の前半までにいろんなLintがCircleCI上で動くようになったんですが、そうすると今度はチームに何が起きたか? せっかく10分ちょいかけてテストがパスしたのにLintでコケてCIの結果が になることが増えてきたんですね。10分くらいならまだいいんですけど、一時期は20分くらいかかっていたのでLintでコケたときのダメージがでかかったです。
- 「なんか開発者の時間がもったいないなあ」と思うようになってきたので、**ローカルで主要なlintを走らせてからpushするようにすればいいんじゃないか?**と思ってそういうツールを探しました。
- で、一番良さそうだったのがhuskyというやつだったので入れました。
- commitやらpushするときのgit hookをチーム内で共有できるというのが素晴らしいです。
- まずprepushでrubocopやらES-Lintなどを走らせるようにしていたのですが、その後precommitでも差分があったファイルだけrubocopを走らせるようにしていきました。ここでも段階的に導入するスタイルを取りました。
- 結果、CI上でlintがコケて…というのはほぼなくなったので、時間を節約できるようになったと思います。
まとめ
- LintはとりあえずCI上で実行するようにしておくのが良いと思う。チームのみんながLintの結果を見れる状況を作っておくのが重要。
- チームのメンバーが「うっ…」と拒否反応を起こさないように段階的に導入できないかを考える。
- 一気にまとめてLintの対応をしようとか思わない。
- カイゼンに終わりはない。
おわりに
今回はCIでLintを走らせる系の話に絞ってご紹介しましたが、上記以外にもHerokuのreview app周りで変な設定だった箇所を直したりとか、SendGridのX-SMTPAPIを使ってメールの分析をしやすくするための情報を付加したり、redashbotを使ってグラフをSlack上で共有しやすくしたりとか数えきれないほどのカイゼンをやってきました。
開発者の生産性を向上させる取り組みに終わりはないと思います。来年もスキを見てカイゼンやっていきたい所存です。
最後にイエシルの運営・開発に関わっているみなさま、まだ終わってないけど2018年もおつかれさまでした。来年もがんばっていきましょう