株式会社サイバーエージェントでバックエンドエンジニアをしている江頭です。
今回、私たちのチームにトランクベース開発という手法を取り入れることによって、デリバリーの速度と開発効率が上がり1日に多いときで15回以上本番デプロイができました。
この記事では、トランクベース開発とはどのような手法なのかご説明したあとに、実際に導入してわかったことをご紹介したいと思います。
トランクベース開発とは
トランクベース開発とは、ソースコードのバージョン管理手法です。現在一般的な手法であるGitflowでは、機能毎にブランチを作成し 1つの機能実装が完了するまでそのブランチで作業し、コードレビュー完了後に各役割ごとに存在するブランチへマージします。
Gitflowでは1つのブランチへ長時間にわたり変更を加えるため、次のような課題があります。
- メインブランチへのマージの際に差分が多くコンフリクトが発生する可能性が高い
- 変更点が多くなることにより レビューワーのコストが上がる
一方、トランクベース開発では、機能実装や改修といった作業を小さい単位に分割し、小さい単位でどんどんマージしていく手法です(少なくとも1日に1回)。作業を小さい単位に分割して行うことで、1つあたりの差分は限定され、マージとコードレビューにかかるコストを少なくすることができます。
トランクベース開発では、作業を小さい単位に分割しプルリクエストをたくさん出していくため、同期的にコードレビューを行うことが重要になります。非同期でコードレビューを行うと、マージまでに時間がかかってしまい、コンフリクトが発生する可能性が高くなります。
導入してわかったこと
私たちのチームの場合、ソースコードはドメインごとに分離されているため、マージの際にコンフリクトすることは稀でした。一方、コードレビューにかかる時間は短いとは言えず、それにより長時間のレビュー待ちが発生することが多くありました。また、コードレビューを待っている間に、別の作業に取り組む必要があり、マルチタスクになってしまうことでミスが発生していました。
この問題を解決するためにトランクベース開発の導入検討をはじめました。しかし、別のチームにトランクベース開発を導入しようとしたときに、うまくワークせず失敗した経験がありました。一方、現在のチームでは開発の初期段階からトランクベース開発を導入し、1年以上たった現在も定着しています。
うまくワークさせるために、わかった3つのことをご紹介します。
作業を小さい単位に分割すること
トランクベース開発では、1つのブランチでの変更点を少なくして1日に複数回メインブランチへマージします。そこで、レビューワーのコストを下げるために作業をうまく小さい単位に分けて取り組むことが重要になります。これまでの機能毎にブランチを作成して実装していくGitflowに慣れていると、最初はどの単位で分割したら良いのだろうと考えてしまうことが多いと思います。
私たちのチームでは、ある機能を実装するときに1~2パッケージ単位に変更を加え、プルリクエストを出している人が多いように思います。
同期的なコードレビュー
トランクベース開発では、1日に複数回プルリクエストが出るため同期的なコードレビューが重要になります。レビューワーは、レビュー依頼がきたら今の作業を一時的止めてコードレビューを行うというルールを定着させる必要があります。この同期的なコードレビューを実現するためにも、1つのプルリクエストでの変更点を限定し、レビューしやすくすることが大切になります。
フィーチャーフラグ
トランクベース開発では、変更を次々にメインブランチにマージしリリースしていくため、未完成の機能や非公開の変更もリリースされてしまいます。これを管理するために、フィーチャーフラグを導入しています。フィーチャーフラグとは機能のオンオフを管理する仕組みで、社内ツールであるBucketeerを利用しています。フィーチャーフラグをソースコードに中に埋め込むことで、機能を有効したいときは、Bucketeerの管理画面からオンにすることで、ソフトウェアのデプロイ作業なしで機能を有効にすることができます。また万が一、リリース時に不具合が発生しても管理画面からオフにするだけで機能を無効化できるため、ユーザーへの影響を抑えることも可能にしています。
フィーチャーフラグについては弊社エンジニアが寄稿する高速な開発サイクルを実現するフィーチャーフラグ入門もぜひご覧ください。
まとめ
トランクベース開発を実践したことで。1日のメインブランチへの変更回数は平均15回、最初の変更をコミットしてから本番稼働するまで平均5時間になりました。これらの数字はチーム内で可視化し、朝会で毎日共有することで日々の数字の変化を知ることができ継続的に意識・改善できるようにしています。
また、フィーチャーフラグを活用することで管理画面から機能のリリースが実現できるため、デプロイによるリリースフローも不要になりました。
トランクベース開発を検討している方々の参考になると幸いです。
参考
https://cloud.google.com/architecture/devops/devops-tech-trunk-based-development?hl=ja