トランクベース開発について

こんにちは、Red Hatでソリューションアーキテクトをしている石川です。

最近色々なカンファレンスやWebの記事などでトランクベース開発について目にする機会が増えてきました。
トランクベース開発とは、一言で言えばGitを使った開発におけるブランチ戦略の一種です。Gitのブランチ戦略というと有名なものであれば、Git FlowやGitHub Flowなどがありますが、トランクベース開発は、CICDと組み合わせた開発の効率化や高頻度のデプロイという点で昨今注目を集めています。 本記事ではそんなトランクベース開発についてご紹介したいと思います。

そもそもなぜブランチ戦略が必要か?

トランクベース開発の説明をする前に、そもそもブランチ戦略とは何かについて考えてみましょう。
例えば、一人で個人的なプロジェクトに取り組む場合、Gitで複数のブランチを使う動機はほぼ無いでしょう。アプリケーションを開発するのもレビューするのも自分自身であるため、Gitリポジトリ上の一本のブランチに対し直接変更をPushしていっても特に問題はありません。

f:id:jpishikawa:20210824143311p:plain

一方で複数人が一本のブランチで開発する場合はどうなるでしょうか。
別々の開発者が任意のタイミングで変更を次々にPushしていくとなると、メインブランチには複数の変更が常に入り乱れた状態となりコード品質の担保や、コードの全体像の把握が難しくなります。
こうした状況を防ぐにはある開発者が実施した作業箇所に対し別の開発者がレビューするなど、品質担保の仕組みが必要となります。

メインブランチ以外のブランチが必要となるのはまさにこの理由からです。
一本のブランチで開発を進める代わりに、個々人が行う開発はメインブランチから分岐したブランチ(featureブランチなど)で実施し、開発が完了したらメインブランチへのマージリクエストを投げます。このマージリクエストの中でレビューを行い、問題が無ければマージを承認、メインブランチに統合するというプロセスを踏むことで、コード品質を保ちながらメインブランチへ変更を追加することが可能になります。

f:id:jpishikawa:20210824143332p:plain

上の図は非常に単純な例ですが、実際の開発では複数のfeatureブランチが併存したり、またこれ以外にもリリースやバグフィックスなどのタイミングでブランチが作成されるケースがあります。そうしたことから自分たちの開発プロセスに合ったブランチ戦略を採用する必要があります。

代表的なブランチ戦略

よく利用されるブランチ戦略として、Git Flow、GitHub Flowなどがあります。
様々なサイトで詳細な解説がなされているため、ここではそれぞれの概要と特徴を見てみましょう。

Git Flow

f:id:jpishikawa:20210824143125p:plain

  • 基本5種類ブランチが存在(main, develop, feature, release, hotfix)
  • 開発者は各々developからfeatureを作成し作業
  • あるタイミング(スプリントの区切りなど)でdevelopからreleaseを切り出し、ステージング環境で商用リリース前の試験を実施
  • 試験が完了したらreleaseをmainにマージし、商用環境へデプロイ
  • 商用バグが発生した場合hotfixを作成し修正

メリット:ブランチを環境と紐付けて管理しやすい(develop>開発環境、release>ステージング環境、main>本番環境)
デメリット:ブランチのマージのパターンが複雑となり、コンフリクトが起きやすい。またそれらのブランチ運用を開発者が理解する必要がある

GitHub Flow

f:id:jpishikawa:20210824142324p:plain

  • 基本2種類のブランチが存在(main, feature)
  • 開発者はfeatureブランチで作業(実際のブランチ名は開発内容を反映するものにする)
  • 開発者はコードレビューをしてもらうためマージリクエストを作成 作業途中で有識者の意見が欲しい場合、マージリクエストのタイトルに『WIP:』を付けたり、draft pull requestの機能を利用する

(GitHub Flowでのデプロイについては諸説あるため以下は一例)

  • マージリクエストが承認されたらステージング環境にデプロイし、商用リリース前の試験を実施
  • 試験が完了したらmainブランチ上でリリース用のタグを作成し、そこから商用環境へデプロイ

メリット:利用されるブランチの種類が少なく、またそれに伴いマージリクエストのパターンもGit Flowと比べ理解しやすい
デメリット:ブランチと環境を紐付けることが出来ない(上の図だとステージングと商用環境は両方mainからデプロイされる)。商用バグ対応時にタグから別ブランチを作成し、そこからバグフィックス版をリリースする場合がある

GitHub Flowについてより詳しく知りたい方はこちらの公式ページを参照してみて下さい。

トランクベース開発の概要

ここまでで代表的なブランチ戦略についてご紹介しました。 それではそれらと比較しトランクベース開発がどういったものか見ていきましょう。
f:id:jpishikawa:20210824140141p:plain

トランクベース開発では、開発者は一つのメインブランチ(trunk)上で作業を行い変更を直接Pushするか、1〜2日以内にマージすることを前提とした作業用ブランチ(short-lived branch)を作成しそこで作業を行います。Git FlowやGitHub Flowでは開発用のブランチが長期間存在することがあり得ましたが、それを許容しないのがトランクベース開発の一つの特徴です。これによりマージに伴うコンフリクトの発生を抑止することが可能となります。 また変更が加えられたtrunkブランチは常に商用提供可能とし、速やかに商用環境にデプロイされます。

トランクベース開発では開発単位を小さく保ち頻繁にturnkに対しPushすること、またそれに伴いCICDを実行し、自動テストや脆弱性診断などのフィードバックを素早く得ることで、開発スピードの向上とデプロイまでの時間短縮を実現しています。

DORA(DevOps Research and Assessment)が公開している過去のレポート(2016年2017年)でも、ハイパフォーマーの共通点としてブランチの短命化が挙げられています。

トランクベース開発の実現

トランクベース開発は開発者に対しメリットをもたらす一方で、それを実現するには単にブランチ戦略を変更するだけでなく、開発の体制やリリースの考え方についても見直していく必要があります。

例えば、trunkブランチに対し直接開発者がPushを行うとなると、マージリクエスト以外の品質担保の仕組みが必要となります。
マージリクエストでは、開発者が一定期間作業をした後に高スキル者がレビューをするという方法でコードの品質を担保していましたが、この場合特定のレビュアーに負担が集中し、せっかく開発した機能が中々マージされず、ビジネス価値を発揮出来ないというケースが考えられます。

トランクベース開発ではそうした空白期間を発生させないために、マージリクエストの代わりにペアプログラミングやモブプログラミングの仕組みがよく採用されています。これらにおいては、開発期間中、継続的に他者の目でコードの内容が客観的に評価されるため、作業完了時に既に一定の品質が確保されるものと考えられます。 f:id:jpishikawa:20210824140204p:plain

また商用提供しているアプリケーションにバグが見つかった場合はどうなるでしょうか。
アプリケーションのリリースをバージョニングして管理している場合、次期バージョンのcommitを含まないよう、バグが見つかったバージョンのリリースタグから新たにブランチを作成し、修正の変更を加えるなどのアプローチが必要となります。
一方でトランクベース開発においてはtrunkブランチを常にリリース可能なものであると位置付けるため、次バージョンという考え方を気にすることなく、バグ修正についてもその他の機能開発と同じように扱うことが可能となります。 f:id:jpishikawa:20210824140222p:plain

銀の弾丸ではない

ここまでトランクベース開発の考え方や実現方法について取り上げて来ましたが、注意したいのはトランクベース開発が全ての開発チームに有効な手法ではないということです。
例えば、ペアプログラミングを採用することで生産性が向上するチームもあれば、それらが上手く馴染まないチームも存在します。ペアで開発をしていても、開発の当事者となることで見えづらくなる問題もあるため、あえて個別にレビューのプロセスを導入したいという要望もあるかもしれません。
リリースのバージョニングについても同じで、プロジェクトにより常に最新のcommitをデプロイするという方法が、プロジェクトを取り巻く環境によっては適切でないケースも存在します。

トランクベース開発は、開発スピードを早め、デプロイまでのサイクルを短くするための一つの手段です。
そのためトランクベース開発を実現する、ということを大上段に掲げるのではなく、自身の開発チームの効率化を達成するためにそこに適用可能なアイディアをトランクベース開発から取り入れていくことが重要だと考えられます。

まとめ

今回はトランクベース開発やその他のブランチ戦略についてご紹介しました。
Gitのブランチ戦略はCICDの設計を考える上でも非常に重要となってきます。
自分や自分のチームが置かれた状況を踏まえた上で、開発を効率化していくため適切な方法を選択していきましょう。

* 各記事は著者の見解によるものでありその所属組織を代表する公式なものではありません。その内容については非公式見解を含みます。