継続的デプロイの次の課題はなんだろう
Feature Toggle について考えていた流れで、デプロイシステムのことが気になってきた。 ちょっと前にどうやったらデプロイをもっと楽できるだろうかとか考えていたせいもあって、どうも気になると落ち着かない。 軽く思考を整理してブログという形で放流しておく*1。
一言でいうと、たとえ理想的なデプロイシステムが得られたとしても、きっと別のところがボトルネックになるので一緒に解消していかないとだよなあみたいな話。
CI/CDがうまく回り始めたら
たとえば master にマージしたら自動でデプロイしてすぐに反映されるみたいな。いわゆる継続的デプロイ (not デリバリ) が達成できた状態。 なんかもう何も考えなくてもデプロイできちゃう。
こうなった状態で何が発生するかと考えると、僕のような人間としてはやはり master にマージするのが怖くなっちゃう気がする。 レビュアーがマージするとしたら、レビュアーは Approve するのが怖くなる。 レビュイーがマージするとしても、Approve もらったあとにマージするには一定の自信と覚悟がいる。
ほかには、機能のリリーススケジュールが決まっているときなんかは結局マージせずにその日を待つこともあるだろう。
一方で、デプロイとは別問題として feature branch を運用する上での課題にも考えを巡らす。
- master の差分取り込みコスト
- 他のブランチとの衝突
- 予期せぬリグレッション
- コードフリーズ
マージが遅れるとかマージできないってことはこれらの課題を相変わらず抱えたままということ。 デプロイが楽になっても、結局色々考えることあるんじゃないか。
じゃあどうする
トランクベース開発の推進
このあたりの話。
できる限り小さく変更を分けてこまめに master にマージすれば、怖さも最小限で済む。 マージが「機能の開発完了」単位でなく、小さな変更単位になっている状態を目指す。そうした文化づくりをしていく。
とはいえ一度に出したい機能もあるのが実際のところ。 そこでデプロイとリリースの分離が必要になってくる。
デプロイとリリースの分離
- リリースのレバーをビジネス側が持つ
- デプロイのレバーを開発側が持つ
こうできたら理想的だし、リリーススケジュール都合でデプロイを待つ必要もない。 (「XX側」といった構造が適切かどうかは検討の余地がある)
とはいえ、現実的にはデプロイ=リリースを意味することが多いので、分離する方法を探すことになる。
この分離のためには Feature Toggle がよく知られているかと思う*2。 特定の機能を無効にしたままリリースできるトグルを実装してしまう方法。
Feature toggle をちゃんとした仕組みとして、プロダクトや運用の性質にあわせていかに上手に設計するかがキーになるのだろうな。 仕組みがない状態で愚直にやり始めると if/else が散りばめられて、保守性の低下を招くことになりかねないし、そうでなくても普通に面倒。 トランクベース開発を可能にするくらいだとさらにその傾向が強くなりそうだ。
独立して適用できるか?
トランクベース開発や、デプロイとリリースの分離は、開発者個人からチーム全体へとコードの所有権を渡していって早期にフィードバックを得る方法のように思う。 そのフィードバックによって、コードを、ひいてはプロダクトを良くしていくことができるんだろう。
そうすると、冒頭の master マージのハードル解消とは独立したメリットがあるプラクティスとして考えることができる。 なのでそういう課題感がなくてもやってもいいんだけど、CI/CDがうまく回っている状態でなければこれらの実現は難しいように思う。 相互補完的な立ち位置にあるのではないだろうか。
とはいえ、できる範囲で部分的に適用していくのは大賛成。 あとはニーズとコストとの綱引きになるのかな。