Github Flowをベースに、メンバーのパワーにグラデーションのあるチームに優しい仕組みにするケースを考える

Github Flow の機能開発branch部分は好きに運用しろというスタンスだと思っている

機能開発branchは、あくまで機能開発branchであって、これらはdeploy可能であるかどうかはわからない。 一方でmainはavailableであることを保証する必要がある。

という前提に立って考えると、PRでいきなりmain branchにはmergeさせたくなくなる。

そもそもgithub flow is 何

  • 機能開発branchとmain branchの体制で運用する。
  • PRでのレビュー必須(Approvedは可能であれば複数が望ましい)
  • テストコード必須 or 推奨
  • 機能開発branchがMerge Ready になる とは [ devでの検証が取れている ] ではなく、[ 機能開発branchの内容をprodにdeployしてから、検証OKのフィードバックを受け取るところまで完了している ]である。

が、主だった特徴に思える。

release branchが欲しくなる

mainと機能開発branchの構成の場合、機能開発branchの検証タイミングとrebaseタイミングが煩雑になりがちになる。
そして、チームメンバーのスキルにグラデーションがある場合

手の速いプレイヤーがガンガンリリースを切っていくことでmainのコミットとtagはどんどん積みあがる。
すると、手の遅いプレイヤーは再rebase作業が重なり、しんどい状況になる。

という課題が発生した。
そのため、

  • mainのheadからrelease branchを必ず作成し、以降のReleaseのための準備やFixについてはrelease branchにコミットを積む。
  • 存在出来るrelease branchは最大1つだけ。(= releaseの追い抜きが不許可になるため、再rebaseを行うストレスが軽減される。)

とした方がprodにdeployする資産を作る際のrebase漏れや検証途中での再rebaseの負担増が起きにくく、(少なくとも我々にとっては)筋が良いようだ。
逆に開発チームがハイパワーな場合は、rebase業を忘れることはなく、複数回のrebase業が苦にならなかったり、そもそも開発スピードが速いため、rebase業をそれほど行わずにガンガンreleaseを切っていけるんだと思う。

PRレビューを小口化するためのルールについても形式化したくなる

機能開発branchからSub branchを切るかどうかの判断は、PRを分割するかどうか(=PRのサイズが大きくなるかどうか)という観点で行われることが望ましい。
形式化すると無駄なbranch操作が必要になるので、生産性には悪影響がある。
一方で、チームのパワーにグラデーションのあるケースだと、所作を決めたほうが混乱が少ないようだ。

所作をある程度固定化しつつ、生産性のために一部の所作は省略しても良いよう、branch modelを書いてみることにした。

customed branch model figure

customed-git-flow

about customed branch model

前提条件

  • 機能開発branch、release branch、main branchの体制で運用する。(左記のbranchは必ずbranchのフロー上登場する。)
  • PRでのレビュー必須(Approvedは2以上必要)
  • テストコード必須 or 推奨
  • release branch を作成する = Staging へのdeploy&検証 Ready = 機能開発の実装自体はこのタイミングで閉める。
  • release branch は1度に最大1つだけ作成出来る。但し、複数機能開発branchをMergeすることは可能。
  • release branchに機能開発branchをMergeするタイミングで、必要に応じてrebaseが必要。
  • prodへのdeployが完了し、prodでの検証OKのフィードバックを以て、main branchへのmerge、releaseのpublish、Tagの追加がReadyとなる。

feature integration branch は 形式化したい人向けのoptionalなルート

  • 機能開発を統合するようなbranchを作成し、PRを小口で作成し都度mergeしていく(prerelease0.1 => 0.2 のフロー)
  • 機能開発branchで開発していて、先にレビューしてもらいたいケースが出てきた場合に、sub branchを作成し、PR作成⇒レビューを行い、merge readyになったタイミングで機能開発branchにmergeを行う(prerelease0.3 => release 1のフロー)

両者はやっていることは同じなので、本質的には後者のみで構わないはずだが、形式化を好む人は前者での作業のほうが心が安らぐようなので記述した。
一方で、合理性を好むタイプの人は後者での作業を従来通り行ってくれれば良い。

尚、機能開発branchのサイズが小さければsub branchを切らなくて良い(prerelease0.2 => 0.3 のフロー)

開発中の機能をmainに合流させたいケースを考える

前提としてエッジケースなので、図には記載しない。
開発が割合長期に渡る等の理由で、prodの稼働等が未達だが、mainにコードを合流させたいというケースがリアルワールドでは起こりうる。
実際問題、開発を統合するためのbranchを育てる方法も度が過ぎれば、PRのレビューやテストのカロリーが許容範囲を超えてくることはままある。

開発中の機能からmainへの直接PR作成&mergeについては

  • 現在稼働中の資産への影響がないこと
  • 現在release branchが生存中ではないこと

を満たしている場合のみ許容するのが筋が良いように思える。

release branchの存在意義について

ケースによってはrelease branchが冗長になりがちではあるものの、機能開発branchのrebaseを忘れた状態で検証を行ってしまって時間をロスするといったケースを防ぐことが出来るというメリットが存在する。 一方で手数は増えるため、開発チームのパワーと相談して決めるのが筋が良いように感じた。(少なくとも、2021年現在の自分のチームでは、必要なように思う。)

また、release branchは複数の機能開発branchをMergeする役割も担うことになる。(図で表現されていないけれど……。)

まとめ

こんなもの考えなくても完全にWayに則って進行できるのが一番ローコストで良い。

と思う一方で、チームのパワーに合わせてまずはミスが出にくい仕組みにして一歩ずつ進めていくしかないという気持ち。