Gaudiy Tech Blog

Gaudiyの技術、開発組織、カルチャーについてお伝えするブログです

トランクベース開発とカンバン改善でリリース速度を早めたDevOpsの取り組み

f:id:gaudiy:20210804120506p:plain

こんにちは、Gaudiyでエンジニアをしている勝又(@winor30)です。

アジャイル的に開発することは、ソフトウェアに関連するサービスをもつ会社であれば、ほぼ全ての企業が採用する意思決定だと思います。不確実性の高い現代社会において、柔軟かつ効率的にアプローチができる手法なためです。

そのプラクティスでよく言われることとして、「小さいバッチで開発して、頻繁にリリースをしよう」というものがあると思います。これを悪だという開発者の方はほとんどいないと思いますが、その実践はかなり難易度が高いと思います。

実際にGaudiyでも、アジャイルが大切であることは理解しながらも、個人の意識、文化、しくみ等が十分ではなく、自然とアジャイルから離れることを行ってしまうことがありました。

そこで最近、QAやユーザー価値を担保しながら「小さいバッチで開発して、頻繁にリリースをしよう」という理想を追求するために、トランクベース開発をはじめとした様々なしくみやプラクティスを導入してみました。

実際に成果も出てきているので、今回はその取り組みをご紹介していきたいと思います。

そもそも「小さいバッチで開発して、頻繁にリリースをしよう」なのはなぜ?

f:id:tkatsumat:20210804083939j:plain

問題点や実際やったことを書く前に、先に理想的な状態とその理由に関して書いておきたいと思います。

そもそも「小さいバッチで開発して、頻繁にリリースをしよう」なのはなぜか、についてです。これは、アジャイル的な開発を進めていき、よりユーザー価値のあるプロダクトをアウトプットすることに繋がるためです。

なぜアジャイルが使われるか?と同じ理由にはなりますが、どんなユーザー価値があるのか?どうやればよいのか?というのは、現代の市場やプロダクトの不確実性が高いことから、すべてを詳細まで予測することはかなり難しいです。

そこでアジャイル的な開発では、今提供できるユーザー価値を頻繁にアウトプットしていくことで不確実性を徐々に潰しつつ、フィードバックループを回して意思決定の変更を頻繁に行うことで、最終的な予測を確実なものにしていく必要があります。この意思決定の変更を頻繁に行い、プロダクトを正しく作るためにも「小さいバッチで開発して、頻繁にリリースをしよう」が必要となります。

この「小さいバッチで開発して、頻繁にリリースをしよう」やアジャイル的な開発がなぜ必要なのか?に関しては、最近の資料ですと、@t-wadaさんが書かれた下記資料が非常によく分かるので、ぜひ一読いただきたいです。(他の話題に関しても書かれていますが、歴史から理解できる内容だと思います)

speakerdeck.com

既存のしくみ・問題点

既存のしくみは、カンバンとGitフローを採用した開発フローになっていました。ざっくり説明すると、カンバンの1チケットが1つのPRに相当し、このチケットが大きな機能を表現していました。それを様々なステークホルダーでレビューした上でマージし、全体の機能ができたらリリースをしていく流れとなっていました。

理想状態を目指す上では、基本的に大きなバッチの開発によるリードタイムの低下が問題となっていました。さらにその原因を細分化すると、下記のような問題がありました。

  1. リソース効率(マルチタスク)に陥りやすい
    • mainブランチとの乖離が大きいfeatureブランチでQAをする
      • 開発以外の視点がこのときに入るのは👍
      • 差分が大きくて、マージまでの速度が上がらない → 待っている間に他のタスクをやる → リソース効率
  2. コンフリクトやデグレリスクが高まる
    • 早くmainブランチに取り込まれないため、差分が大きくなりコンフリクトやデグレの確率が上がっていた
    • 結局mainにマージする前のreleaseブランチでリリースする機能すべてにQAをして、バグを洗い出し、リリースみたいな感じになってしまい、アジャイルらしくなかった
  3. ユーザー価値の測定・判断が不明確
    • featureブランチでの検証や価値を判断する項目が多い
    • もっと前に気づけたのでは?みたいなことがあって出戻る

上記の問題を解決するために、トランクベース開発の導入とカンバンの見直しを行いました。

トランクベース開発とは?

引用:Trunk Based Development

トランクベース開発とは、メインブランチ(トランク)をベースとして、トランクに対して修正を行っていく方法です。詳細に関しては、GCPの記事が分かりやすいかと思います。

DevOps 技術: トランクベース開発 | Google Cloud

トランクベース開発の本質的な価値としては、トランクと修正するブランチの差分が極限まで下がり、コンフリクトやデグレリスクを下げつつ、トランクを常に最新の状態に保つことができる点だと思います。

この性質が特に今回の課題であった「1. リソース効率に陥りやすい」「2. コンフリクトやデグレリスクが高まる」に関して、効果がありそうだと考えました。

カンバンで足りなかったところは?

今までのGaudiyのカンバンでは、「ストーリーを小さく分割し、リードタイムを短くする」という部分に対して、うまく動けなかったところがありました。これを実現することによって、このチケットでなにを行えばよいのか?というゆらぎが減りつつ、最速でユーザーへの価値提供ができるようになり、様々な側面での不確実性を減らすことができるようになります。

これは当たり前ではあるのですが、意外とカンバンやスクラムをやることに集中してしまい、それに慣れてしまって形骸化していたのが事実としてあったので、今回の機会にカンバンとしてどう進めればよいのか?何を意識すべきなのか?というところを再考しました。

実際に導入したトランクベース開発とカンバンのプラクティス

f:id:tkatsumat:20210804092057j:plain

今回行ったトランクベース開発とカンバンのプラクティスは、下記のようなものを導入しました。

  • トランクベース開発に必要なプラクティスの導入
    • Githubフローライクな自動デプロイ設定
    • 同期的なレビューを率先して行う
    • mainブランチがデプロイできない状態を作らないように徹底する
  • カンバンの見直し
    • デイリースタンドアップで青ワークに切り替える
    • ストーリーの価値を明確にし、その検証を小さく多角的に行う
    • WIP制限をうまく使い、リリース頻度を上げる

トランクベース開発に必要なプラクティスの導入

トランクベース開発は原則として、トランクを中心に開発していく開発手法になります。ただし、これを実現するためには、レビューコストと自動テストが課題となります。そのため、トランクベース開発を導入しつつこのあたりの課題も解決するようなプラクティスを導入しました。

Githubフローライクな自動デプロイ設定

Gaudiyでは今までGitフローを採用していました。開発してPRがマージされたものが取り込まれるdevelopブランチが存在し、大きな機能開発があるときはfeatureブランチを作ってそこで開発していました。リリース準備にはリリースブランチを切り、最後にmainブランチにマージすることで、デプロイ・検証・本番反映を通してリリースが完了するような流れでした。

わりと自然にこのような形にたどり着いたのですが、ブランチ間の差分が大きくなることが多々あり、コンフリクトリスクやレビューのコストが増大していました。

ここから、トランクベース開発に変えるために、developブランチを削除し、PRを基本mainブランチからしか切らないようにしました。

f:id:tkatsumat:20210804084649p:plain

また、各環境のデプロイに関しては、mainブランチマージ時にdevelopとstaging環境にデプロイし、mainからリリースタグを切ることによって本番環境にデプロイするようになっています。この理由としては、基本的にmainブランチにマージされたものがユーザー価値の現在の最新状態であるため、それを各環境にできるかぎり反映し、検証やすぐに本番反映できるような状態にしておきたかったためです。

f:id:tkatsumat:20210804085237j:plain

同期的なレビューを率先して行う

トランクベース開発の原則として、mainブランチとPRの差分は極力減らす必要があります。そこで大事なのが、レビューの速度を上げることです。そのため、Gaudiyでは以前から取り組んでいるペアプロを率先して行いつつ、ペアプロを行わなかった場合でも同期レビューを頻繁に行うようにしました。

基本的に非同期のレビューも行ってはいるのですが、デイリースタンドアップ等でPRを投げているがレビュー待ちなものがあるというところから判断し、同期レビューをそこでアサインするようになっています。

f:id:tkatsumat:20210804081956p:plain

mainブランチがデプロイできない状態を作らないように徹底する

トランクベース開発では、mainブランチは基本いつでもデプロイできる状態を作る必要があります。これを実現するために、下記のようなことを行いました

  • featureフラグをうまく使う
  • 自動テストを使って、品質を担保する

featureフラグとは、新しい機能を隠してリリースを行いたいときなどに、その機能を隠す(制御できる)フラグのことです。featureフラグはかなり昔からある考え方になりますが、トランクベース開発ではデプロイ可能状態というものを維持することが重要になるので、featureフラグを使いユーザーにはまだ見せないがデプロイはしたいみたいなことを実現できる必要があります。

自動テストを使って、品質を担保するについては、基本的にはよくあるCI時の自動テストになります。GoでもReactの場合でもunit test、hooksのtest、コンポーネントのインテグレーションテストなどCI環境で実行できるものはすべて実行し、基本的に品質担保を目指します。また、GaudiyではAutifyという自動E2EテストのSaaSを利用しており、これを毎日実行することでmainブランチの品質担保をしています。

詳しくはGaudiyの西岡が下記ブログで説明しているので、興味ある方は読んでいただければと思います。

GaudiyがAutifyを導入して手戻りコストを削減した話 - Gaudiy Tech Blog

また、このあたりのテストや検証で気づいたりした場合は、基本的にその問題の優先度を上げ、なるべくデプロイ可能な状態を作ることにフォーカスすることも重要な点です。

カンバンの見直し

さらに、「小さいバッチで開発して、頻繁にリリースをしよう」を達成するため、カンバンでもいくつかの点を見直しました。これらの改善点も基本的にはアジャイル的な原則に従った、ということが結論になります。

デイリースタンドアップで変更できるようにする

f:id:tkatsumat:20210804090621j:plain

デイリースタンドアップが形骸化されていたときは、タスクの進捗や困ってることの報告がメインになっていました。この方法でも、どこまでチームが達成しているのか?が分かるので良いとは思うのですが、アジャイルの原則で言えば、そういったことを踏まえてどう柔軟に意思決定を変えていけるか?ということが大事になります。

これを実現するために、デイリースタンドアップでは上記のような報告に加え、どうしたらよりリードタイムを縮めることができるかをベースに、どう変更することができるのか?を問いかけるようにしています。具体例としては、ストーリーの分割を行ったり、ビジネスの状況から考えて次優先すべきところを話したりなどがあります。

また、この変更するような作業を「青ワーク」と呼び、プログラミングやデザイン作るなどの作業を「赤ワーク」とGaudiyでは呼んでおり、言葉としても使うことで「今は青ワークだから変更に柔軟になろう」と意識付けられるようにしています。

ストーリーの価値を明確にし、検証を小さく多角的に行う

https://i.gyazo.com/967f7893e1df900a0c5f65794ac8a1e2.png

f:id:tkatsumat:20210804082055p:plain

もうひとつ、ここも形骸化されやすいポイントですが、チケットのストーリーの価値を明確にすることに注力しました。基本的にテンプレートを作成し、作業に入る前には必ず書くようにしました。このチケットを達成したとき、ユーザーにどんな価値を提供できるのか?というところを明らかにしてから作業に入るように徹底しています。

また、ユーザー価値の検証のためにストーリーが一通りできたら、エンジニア、デザイナー、Biz、コミュニティマネージャーなど様々な視点からそのストーリーの検証を同期的に行い、どこが良いか、どこが改善必要 or 足りないかなどを実際にアプリを触りながら話すようにしています。

ストーリー分割とこのプロセスが合わさることで、かなり認識のブレはなくなりつつ、開発としてもYAGNIな精神を維持することで、バーティカルスライスを意識した開発を実現することができます。

WIP制限をうまく使い、リードタイムを減らす

f:id:tkatsumat:20210804090834p:plain

引用:Recruit Tech Blog

カンバンの原則として「WIP制限」というものがあり、これを徹底することでリードタイムを下げるようにしています。

詳しくは下記記事が分かりやすく書かれているので、こちらを見ていただければと思います。

SUUMOアプリチームがスプリントを廃止してカンバン方式に移行した話

WIP制限とはフロー効率的に動くためにカンバンボードに導入される仕組みとなります。フロー効率とは、たくさんの仕事に労力をかける(リソース効率)よりも、何かの1つの仕事にフォーカスし、それを終わらせたあとに次の仕事に集中する方式(フロー効率)のほうが最終的にかかる時間は同じ、かつリードタイムは短くなるという考え方です。これを実現するために、カンバンではWIP制限というものが存在し、カンバンボード内で取り掛かることができるチケットの枚数を制限しています。

Gaudiyでは、作業中やレビュー中などのレーン単位でWIP制限を導入し、基本的にそれを超えないように作業しています。WIP制限により、多くの種類の仕事ができないため、ペアプロなどの同期的作業が強制され、属人化の防止やレビューコスト削減などの恩恵もあります。

結果

今回のトランクベース導入とカンバンの見直しを行いよりアジャイルな開発文化に変えた結果、リードタイムがかなり短くすることができました。また、下記例は1週間だけですが、基本的にこのぐらいのリードタイムを安定して出しているので、定常的にアウトプット出せているものだと思います。

f:id:tkatsumat:20210804082123p:plain リードタイム10日

f:id:tkatsumat:20210804082137p:plain リードタイム4日

また、定性的なものを例に上げると、チームのメンバーからも「開発フローがガラリと変わったけれど、よりアジャイルな開発になって前よりもストレスなく開発できる」という声も上がっていました。

まとめ

今回の記事で紹介したとおり、トランクベース開発とカンバンの改善を行ったことにより、アジャイルな「小さいバッチで開発して、頻繁にリリースをしよう」という理想的な状態に少しだけ近づくことができたと思います。

特に、チームのメンバーからも「アジャイルな開発に明らかに変わった感じがして良かった」という声が上がったのはかなり良かった点かなと思います。

ただ、まだまだ改善できる点はあり、Gaudiyはかなり不確実性が高い事業領域を扱っていることもあるので、よりアジャイルな組織を目指していければと思っています。Gaudiyの開発組織に興味を持っていただいた方は、ぜひ気軽にお話ししましょう!

▶︎カジュアル面談はこちら

▶︎オープンオフィス・オープン勉強会はこちら