SODA Engineering Blog
😎

トランクベース開発に移行して開発生産性も向上した話

2023/12/19に公開

スニダンを開発しているSODA inc.の Advent Calendar 19日目の記事です!!!/

はじめに

SODAでは開発組織の中で開発の生産性を評価するために Four Keys 、指標をモニタリングするためにFindy Teams+ を利用しています。私が組織に入った時にはデプロイ頻度・変更のリードタイムといった指標が低い状態となっていたため、それに対して改善した取り組みを紹介していきます。

課題の整理

私がチームに入った1月ごろのFour Keysの指標がこちらです。
リードタイムが極端に長いこと、変更障害率が高いことがわかると思います。

ただ、このリードタイムについては正しい計測ができていないというのが実際の問題点でした。
フィーチャーブランチ開発を採用しており、巨大なフィーチャーブランチがマージされたことによってリードタイムが悪化してしまっていました。

また、このプロジェクト期間中にアプリの細かいアップデートや不具合の対応など様々な小さい変更が差し込まれては審査に出すといったリリース作業が頻繁に発生していました。これによりリリース作業はもちろんのこと、フィーチャーブランチへ差分を取り込んだりとフィーチャーブランチのメンテナンスも必要になり手のかかる運用になっていました。

問題点としては下記のようなものが挙げられます。

  • 開発の実際のリードタイムがモニタリングできない
  • 変更障害率が高い
  • 巨大なPRのコンフリクト解消作業がリリース直前に発生する
  • 運用・保守とのコンフリクト

トランクベース開発へ

モバイルアプリチームはスプリント開発において振り返りの時間があるのでこれらの問題について全員で認識を揃えること自体は特に難しい作業ではありませんでした。これら全ての問題を解決するためにはパフォーマンスのモニタリングの設定を変えるだけでは不十分だったので開発フローを見直す必要がありました。
結果としてトランクベース開発に切り替えようというところまではスムーズに進めることができたと思います。

新しくブランチ運用を変えるにあたって下記の2つはチーム全員で運用イメージを固めました。

  1. Feature Toggleの運用ルール
  2. Feature Toggleを使った実装をする際のサンプル

Feature Toggleの運用ルール

トランクベース開発では小さいバッチに分割してトランク(デフォルトブランチ)にマージしていきます。特に大きい機能ではコードのマージがユーザーに公開して良いということとイコールではないので、コードのマージと機能のデプロイを分離する必要があります。そこで活用するのがFeature Toggle(Feature Flagの方が一般的?)です。

Feature Toggleと呼ばれているものが機能とコードのデプロイを分離する Release Toggles 以外にもいくつか種類があること、また一般的に Feature Toggle を採用することでコードが複雑になってしまうことなどチームで勉強会を行いました。

Feature Toggles (aka Feature Flags) より

Feature Toggleを採用しても複雑度を増さないようにする対策としてチームでは運用ルールを作って、そのルールに沿って新しいToggleを追加する運用としています。

大きく3つのルールがあります。

  1. Toggleのオーナーを決める
  2. 命名ルール
  3. 管理表

それぞれについて簡単に説明すると

Toggleのオーナーを決める

Toggleのライフサイクル(登録から設定の削除まで)に責任を負う人です。
オーナーはToggleを追加し、機能の公開を終え役割を終えたと判断した時にToggleの設定および関連実装を削除する必要があります。

命名ルール

スニダンではToggleのsuffixだけ決めていて、機能公開を制御するものに関しては release_toggle
がつくようにしています。また、過去に使ったことのある名前については再利用しないこともルールにしています。

管理表

管理表はNotionのテーブルで管理しています。
記載する必要がある項目としては以下のようにしています。

  1. Toggle名
  2. 用途(Toggleの設定値を切り替えた際の挙動の変化)
  3. App version(Toggleの実装を追加したバージョン)
  4. オーナー
  5. 削除可能なタイミング

App Versionは影響範囲を特定するときやToggle自体を削除するときに必要な情報で、削除可能なタイミングもあらかじめ記載しておくことで開発終了時の状態と比較して問題がなければ消すという判断材料として利用できています。

Feature Toggleを使った実装をする際のサンプル

運用が始まってから今日までの開発は想定していた通り、丸々作り替えるような開発が続いているというのもあり概ね以下のような実装で対応できています。

改修対象となる画面の実装の build メソッドの中で Toggle が有効かどうかによって新しい実装、元の実装を返すようにしています。呼ばれた画面によって必要な Provider が呼び出されるためToggleの分岐を差し込むポイントはUIのみに限定できています。

今後の開発内容によってはもっと細かい分岐が必要になる可能性もありますし、場合によっては複数のToggleが依存し合うケースも出てくるかもしれません。ベストな対策はまだ見つけていませんが、Feature Toggleのライフサイクルを短くする(リリースが終わって消せるタイミングで消す)ことで、できるだけコードをシンプルに保つようにしています。

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final someReleaseToggle = ref.watch(someReleaseToggleProvider);
    if (someReleaseToggle) {
      return const NewScreen();
    }
    return const OldScreen();
  }

おわりに

モバイルアプリチームのブランチ運用を改善した事例を紹介しました。
導入からは10ヶ月程度経過していますが、結果は指標にも表れていると思います。

指標を実態にあった形で計測できるようになったことで振り返りの改善サイクルを回せるようになったこと、巨大なブランチ運用がなくなったことで変更障害率も下がり、変更のリードタイムも爆速になったことが今回の取り組みから得られた結果です。

個人の体感としても指標が実態と近くなったことで振り返り自体がやりやすくなったこと、変更のリードタイムを意識できるようになったことで小さいPRに分割してトランクにどんどんマージしていける点は開発体験自体が良くなったと感じます。バグ対応や問い合わせの対応なども修正し、すぐにトランクにマージできるのはとてもストレスフリーです。

これからも変更のリードタイムがElite基準(24h以内)、変更障害率0%を目指して改善を続けていき隊と思います。

SODA Engineering Blog
SODA Engineering Blog

Discussion