トランクベース開発とデプロイ

前回は Git-flow とデプロイについて書いたので

bufferings.hatenablog.com

今回は、トランクベース開発とデプロイについて考える。LinkedIn, Facebook, Google などもトランクベースの開発をしてるんだね

トランクベース開発は Git じゃなくてもいいと思うんだけど、この記事では Git 前提で考える

トランクベース開発?

幹(trunk)となるブランチにみんなが小さな変更を加えていくブランチモデル。寿命の長いブランチを作らないようにすることで、マージでつらい思いをしなくて済むようになって、ビルドも壊れないようにできて、ヤッター!というもの

trunkbaseddevelopment.com

Git-flow みたいに develop ブランチで開発をするんじゃなくて、main ブランチで開発をする。main ブランチを常にビルドが通る状態にしておいて、そこからリリースするスタイル

ただ、main が更新されたら自動でリリースしないといけないというわけではない。自動でリリースしてもいいし、自分の好きなタイミングでリリースしてもいい。単に、main からいつでもリリースできるようにしておけばいい

f:id:bufferings:20220409142646p:plain:w400

https://trunkbaseddevelopment.com より)

幹となる青いブランチにみんなで変更を加えていく。下側にあるグレーの部分は、寿命の短い(長くても2日くらいの)フィーチャーブランチを作ってプルリクエストを出してマージする

一番シンプルな形だと、フィーチャーブランチも作らずに main に直接コミットするみたい。モブプロだと、その形がいちばん合ってそうね

トランクベース開発のバリエーション

GitHub Flow や GitLab Flow や、今回調べてて知ったぐるなびの GitFeatureFlow もトランクベース開発だなって思う。それぞれ、ひとつのブランチを幹にするのは一緒で、デプロイの方法が違う。ので、その辺りを見ていこうかな。最初にざっくりそれぞれの紹介から

GitHub Flow

GitHub Flow – Scott Chacon

「Git-flow は良いけど必要以上に複雑だから GitHub では違うやり方で開発してるよ!」って紹介されたフロー。ほぼトランクベース開発の図のままで、違うのは「main にマージされたらすぐデプロイしよう!」ってところかな。↑の記事では Hubot でデプロイしてる。

そういえば、今だと GitHub でプルリクエストを出して開発を進めるのは普通になってるけど、2011年だとまだそこまで Git もプルリクエストを使った開発もあんまり浸透してはなかった頃なのかなぁ?と思ってツイッター見てみたら、僕は2010年・2011年ぐらいに Git の勉強始めたみたい。ほほー

GitLab Flow

Introduction to GitLab Flow | GitLab

GitHub Flow 良いんだけど、デプロイ周りについては触れられてなくて迷うから、こんな感じが良いと思う!って GitLab がその辺りにガイドラインをつけたフロー

各環境用ブランチを持つことを推奨してる。例えば、development ブランチ(これが trunk)を常にデプロイ可能にしておくんだけど、本番環境へは production ブランチにマージされたときにデプロイされるようにしておく

こうすることで、デプロイのタイミングをコントロールすることができる。これが、前回の記事で触れた「develop と main だけの Git-flow は GitLab Flow と同じ」ってこと

f:id:bufferings:20220409163437p:plain:w400

https://docs.gitlab.com/ee/topics/gitlab_flow.html より)

複数の環境を持つ場合は、こんな感じになる↓

f:id:bufferings:20220409163928p:plain:w600

https://docs.gitlab.com/ee/topics/gitlab_flow.html より)

上から下に流れるようにすることで staging でテストされたものだけが pre-prod に、pre-prod で確認されたものだけが production にデプロイされるようにできる

GitFeatureFlow

ぐるなびの開発チームではこんな風にやってるよ!って紹介されたフロー

GitFlowは使わない!シンプルな「GitFeatureFlow」を紹介します - ぐるなびをちょっと良くするエンジニアブログ

特徴としては「main にマージする前にフィーチャーブランチからデプロイして動作確認ができるようにしてるよ!」ってところ。各環境用のブランチを持つのは GitLab Flow と似てるけど、それを main から反映させるんじゃなくて、フィーチャーブランチの段階で使ってる

f:id:bufferings:20220409164249p:plain

https://developers.gnavi.co.jp/entry/GitFeatureFlow/koyama より)

自分がやってたやつ

と、ここまで書いて、自分もなんか過去に書いたなぁって思って、みてみたらあった

bufferings.hatenablog.com

Git-flow だとちょっと複雑で、GitHub Flow だとシンプルすぎるからって言って、フィーチャーブランチだけの開発をしてたみたい。ブランチ名を指定してワンクリックデプロイできるようにしてたから、そのフィーチャーブランチをステージング環境にデプロイして問題なければ main にマージって流れか。GitFeatureFlow とやりたいことは同じだね

f:id:bufferings:20160205004713p:plain

デプロイ

ということで、トランクベース開発の場合のデプロイは

GitHub Flow のように

  • main にマージされたら自動で本番環境にデプロイされる

GitLab Flow のように

  • 各環境用のブランチがあって、main から順にそれぞれのブランチが更新されたら自動でデプロイされる

GitFeatureFlow のように

  • フィーチャーブランチから各環境用のブランチが更新されたら自動でデプロイされる

名前がないけど僕がやってたみたいに

  • ブランチ名とデプロイ先を指定してワンクリックデプロイをする

かな。GitFeatureFlow と僕のやってたフローは、トランクベース開発というよりは、軽量の Git-flow かもなぁ。フィーチャーを安定させてから main にマージするから、フィーチャーブランチの寿命が長そう

CircleCI では?

前々回の記事 で紹介した CircleCI の僕がいるチームのやり方は GitHub Flow に近くて

  • 小さな部品単位で main にマージして、main が更新されたら本番環境にデプロイされる

のだけど main にマージする前に確認したい場合は

  • canary ブランチにマージすることでカナリア環境にデプロイされる

というのをやってる

デプロイ周りのそれぞれの特徴は?

デプロイとしてシンプルなのは GitHub Flow の「main が更新されたら本番環境にデプロイされる」

必要になるのは CI を充実させること、フィーチャーフラグなどを使用してリリース前の機能を隠しておくこと、かな。細かな部品を常時統合しながらデプロイするので、開発のスピードはすごく速いし、未統合の機能も少なくて良い。一方で、デプロイ前にQAを実施するようなプロセスは挟まないので、そういったプロセスが必要な場合は別の方法で取り組む必要がある

GitLab Flow だと各環境にデプロイして確認してから本番環境にデプロイすることができる

なので、ステージング環境などでじっくり確認することができる。注意が必要なのは、本番環境などに HotFix が必要な場合に、すでに development ブランチが先に進んでいる場合は production ブランチにどう反映させるかを考える必要があるところかな。それと、デプロイのための流れはひとつだけなので、複数の機能の開発を並行して進めてそれぞれを動作確認したい、というのは難しい

GitFeatureFlow だと、複数の機能をそれぞれ別のフィーチャーブランチとして開発して、それぞれ別の環境にデプロイするということも可能

だけど、フィーチャーが大きくなると結局 Git-flow で発生していたようなマージの難しさがでてくるから、小さめのフィーチャーとして寿命の短いブランチにしておく方が良さそう。また、複数の機能を並行して開発しているときの環境ブランチは、機能Aをデプロイして動作確認したあとに機能Bをデプロイして確認すると、結局それは本番環境のコードとは異なるものになるので注意が必要そう。なので、ブログでも紹介されてるみたいにたまに main から作りなおしたら良さそう。それか、force push で更新してもいいのかも

こう見てみると

GitHub Flow がいちばん合うのは、GitHub や GitLab や CircleCI みたいに開発系のウェブサービスだと思う。ある程度固まった単位でのリリースが必要な場合は GitLab Flow は使えそう。だけど、複数の機能を並行して開発していく場合は GitFeatureFlow みたいな軽量の Git-flow が良さそうで、もっとリリースをかっちり管理したい場合は、Git-flow が良さそう

今回はこんなところかなー。次回は GitOps とデプロイ、を書いてこのシリーズは終わりかなー

追記

書いた

bufferings.hatenablog.com