Amazon Web Services ブログ

株式会社レンガにおけるCodeGuruを使ったコードレビューの自動化

このブログは株式会社レンガ 取締役 開発担当 小原 和磨 氏により寄稿され、AWS Japan ソリューションアーキテクト 金杉 有見子 が編集したものです。

株式会社レンガは 、月間100万人以上に利用されている日本最大級のマンションの口コミ・評価サイト『マンションノート』を運営している会社です。マンションノートは日本全国にあるマンション・アパートの「口コミ」と「ランキング」を見ることができるWEBサービスです。マンションの住人をはじめとして、元住人、周辺住人、専門家、不動産会社、物件オーナーなど、あらゆる立場の方々が自分の立場を表明し、マンションに対する生の意見・評価を投稿・共有します。その集合知により、マンション検討者が(住む前に)住んだ後のリアルな生活を想像できるようになり、大切な住まい選びにおいて“こんなはずではなかった”、“別のマンションを選べば良かった”といった後悔を世の中からなくすことを目的としております。

エンジニアは私を含め合計6名在籍しています。レンガはコードクオリティを非常に重要視しているため、コードレビューは私たちの開発において欠かせないプロセスです。しかし、開発量に比例してコードレビューのタスクが増えるため、レビュアーの負担が大きいという課題がありました。また、レビューを重ねたとしても見落としてしまうバグは存在するため、より網羅的にコードレビューを行える仕組みを必要としていました。

そのような時に、2019年のre:InventでAmazon CodeGuruが発表されました。CodeGuruが機械学習をベースとしたコードレビューのサービスであると知った瞬間、私たちが求めていたツールだと思いました。発表当時は、丁度私たちがソースコードに対し大幅な改修を行っていた時期でもあったため、CodeGuru Reviewerが使えるのではないかと思い導入してみたところ、これまでメンバーや他の静的解析ツールが認識していない指摘項目を生成してくれたため、その後もCodeGuruを継続して利用しています。このブログでは、レンガがCodeGuruを導入した背景とそのプロセスについてご紹介します。

コードクオリティの維持

レンガは2012年に設立され、今年で創業8年を迎えます。プロダクトとしては徐々に成熟してきているものの、私たちは今でも素早く機能拡張をすべく、開発に多くのリソースを注いでいます。しかし、開発のサイクルを加速するだけでなく、私たちはコードクオリティの維持に対しても同様のプライオリティを付けて取り組んでいます。機能拡張において、質の低いコードはシステムの複雑さを増し、いつか技術的負債になってしまう可能性があります。一方で、一貫したコードクオリティが担保できていれば、たとえシステムの規模が大きくなっても、シンプルであるが故に拡張の妨げになることはありません。このように俊敏性と品質をバランス良く両立させることは、持続的に新機能をリリースするスタートアップにとって特に重要になってきます。

レンガでは、2段階のコードレビュープロセスを採用しています。開発者がGitHub上のリモートリポジトリに修正点をコミットし、Pull Requestを作成すると、まずは2名のシニアメンバーがレビューを行います。次に、私の方で最終確認をし、問題がなければマスターブランチにマージします。また、ビルドフェーズではCheckstyleによる最低限のコーディングルールのチェックも行っています。

私たちは、コードレビューのコストと品質に課題を感じていました。レンガのコード量が増えるにつれて、レビュアーの負担が増えていました。現状、開発期間の約5%がレビューのやり取りに使われており、また、レビューを行うメンバーは平均して毎日1時間ほどをコードレビューに割いています。私たちは素早くリリースし、新機能による価値をいち早くユーザーに届けたいと思っていますが、コードレビューがボトルネックになることがあります。さらに、レビュー対象となるコード量が増えてしまうと、的確に問題点を見つけ出すことが難しくなってしまい、漏れも発生します。レビュアーを増やすことも解決策の一つではありますが、コードレビューには幅広い業務的/技術的知識が必要とされるだけでなく、上位モジュールに対する理解も必要となってくるため、簡単ではありません。レビュアーの負荷をオフロードできるような自動化されたツールを必要としていました。

CodeGuru Reviewerの導入

CodeGuru Reviewerは自動化されており、開発パイプラインにもシームレスに組み込めるため、導入の敷居がとても低いと感じました。コストに対する課題を解決できる他、機械学習をベースとしているため人間とは異なる観点のインサイトを得られるのではないかと期待が膨らみました。当初は未だPreview段階でしたが、無料利用枠もあったため、早速試してみることにしました。

以下の図はレンガの開発パイプラインを示しています。

CodeGuru Reviewerのセットアップは非常に簡単です。GitHubのリポジトリを選択し、関連付けるだけです。GitHubリポジトリを関連付ける場合、CodeGuru Reviewer用のGitHubユーザーを作成することが推奨されています。関連付けが終われば、CodeGuru Reviewerが有効化されたことになります。

以下はCodeGuruコンソールでリポジトリの関連付けを行う際のスクリーンショットです。

CodeGuru ReviewerはPull Requestによってトリガーされます。通常Pull Requestが発行されてから15分以内にCodeGuru ReviewerがPull Requestコメントを通じてレコメンデーションを提供します。

以下は私たちのコードベースに対し、CodeGuru Reviewerが生成したレコメンデーションです。

It is more efficient to directly use Stream::min or Stream::max than Stream::sorted and Stream::findFirst. The former is O(n) in terms of time while the latter is not. Also the former is O(1) and the latter is O(n) in terms of memory.

指摘のあったコード自体はボトルネックとなるコードではありませんでしたが、該当部分の実行パフォーマンスの改善に役立ちました。また、この方法を知る事でその後の開発にも活かせており、開発者がより自信を持ってコーディングできるようになっています。

以下は私たちのコードベースに対し、CodeGuru Reviewerが生成したもう一つのレコメンデーションです。

Consider closing the resource returned by the following method call: newInputStream. Currently, there are execution paths that do not contain closure statements, e.g., when exception is thrown by SampleData.read. Either a) close the object returned by newInputStream() in a try-finally block or b) close the resource by declaring the object returned by newInputStream() in a try-with-resources block.

実際にリソースリークは発生していませんでしたが、指摘部分をリークが発生しない事が明らかになるように記述をあらためる事で、可読性を向上する事ができました。

実際に導入してみて、CodeGuru Reviewerは既存の静的解析ツールと比べ、生成される指摘事項は少ないが、その分精度が高く、false positiveが少ないプロダクトだと感じました。レコメンデーションの数が膨大だと、逆に選別に無駄な時間をかけてしまうため、的確なレコメンデーションは多忙な開発者にとって非常に嬉しいものです。

サマリ

コードレビュープロセスは重要ですが、レビュアーの負担となり、開発のボトルネックになってしまっては本末転倒です。私たちはCodeGuru Reviewerを導入することで、コードレビューを自動化し、レビュアーの負担軽減に繋げることができました。さらに、自分達が把握していなかったコーディングのベストプラクティスを知ることができ、デベロッパーがより自信を持って開発できるようになってきています。今後、レンガでは循環的複雑度などのメトリクスを指標化し、ユーザーによりクオリティの高いサービスを迅速に提供していきたいと考えています。CodeGuru Reviewerに対しては、更なるRecommendation項目の拡充を期待しています。