git ブランチワークその3 - gitlab flow

# 前置き
これまで、git flow, GitHub flow というメジャーな git 運用モデルを見てきました。
どちらも良い運用モデルですが、それぞれに一長一短、良し悪しがあります。

GitLab はこれら2つのモデルに対して以下のような問題点があるとしています。

## Git flow の問題点
- main ブランチはリリースされたコードを保持するためのものになり、開発者は develop ブランチを主ブランチとして利用する。
main ブランチをデフォルトのブランチとするほとんどのツールで切り替え作業が生じる。
- hotfix ブランチと release ブランチによって生じる複雑さ。
これらのブランチは一部の組織では有用かもしれないが、CD を導入した組織ではデフォルトブランチのリリースが行われる。
CD を導入できている場合、これらのブランチが不要な存在であり、儀式化する。



## GitHub flow の問題点
- デプロイメント、環境、リリース、issue との統合 に関して疑問点を残している。
具体的な例は冒頭では上がっていないが、コチラは簡潔すぎることを問題としている。


そこで今回はこれら2つのモデルに対して改善の余地があるとして GitLab が設計した GitLab Flow を見てみることにする。

今回は **GitLab Flow**

- [git flow](https://qiita.com/Takayuki_Nakano/items/19db281646626d9dcd72)
- [github flow](https://qiita.com/Takayuki_Nakano/items/cce7f0118ef0be927759)
- gitlab flow ← ココ


# gitlab flow

章立てでいくつかのケースについて言及している。


## production ブランチ

GitHub flow が持つデプロイタイミングの問題への解決策。

GitHub flow は feature ブランチがマージされるたびにデプロイされることを求めているが、それが現実的ではないプロジェクトも存在する。

例)
- iOS アプリは App store の承認が下りた時点でリリースされる。
- プロジェクト運営上、営業時間中にリリースを行いたい。あるいはユーザー数の多い日中はリリースを避けたいが、それ以外の時間帯にもエンジニアがコードをマージすることがある。

このような場合に、デプロイ済みのコードを反映した production ブランチを作成する。
development ブランチを production ブランチにマージすることでデプロイを行う。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315470/b8ea5699-b411-415f-1bad-cc1462a8663a.png)


### 登場するブランチ

|名称|役割|分岐元|マージ先|備考|
|:-:|:-:|:-:|:-:|:-:|
|development|開発者がメインで使用するブランチ||production|main/master に相当|
|production|デプロイ済みのコードを管理する|||自動デプロイを行う場合、このブランチへのマージをトリガーにする|

いつデプロイが行われたかは production ブランチへのマージ時刻を確認すればよいし、自動デプロイを行っている場合はかなり正確な時刻が確認できる。

あくまで主題は production ブランチの導入であって、development にて開発コードをどのように管理するかは題材としていないのだろう。
デプロイの瞬間までは GitHub Flow に則って運用するが、production ブランチを用意しておき、デプロイタイミングだけ main -> production のマージに変えて運用するなどして利用するのだろう。


## environment ブランチ

動作確認用に staging ブランチに自動的に更新される環境を用意することはよいアイデアであるかもしれない。
ただしこの時、環境とブランチの名前が一致しない可能性があります。

先ほど例に上がったブランチ名と名称が一致する環境があって少しわかりにくいが、staging, pre-production, production の3環境があるとする。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315470/8f565930-e63c-6b45-b440-e718797348b0.png)


環境と同じくstaging, pre-production, production の3ブランチがあります。

1. それぞれのブランチは自身と同名の環境へデプロイを行う
1. 原則として、上流から下流へのマージのみ行える。(staging → pre-production → production)
1. ワークフローでは、コミットは下流にしか流れないので、すべての環境ですべてのテストが行われる。
production にテストが入っているので production でテストを行って pre-production へ、などといった行為は行われない。
1. hotfix を行う際は feature ブランチが作成されてそこで作業を行い merge request で production へマージするのが一般的。
この時 feature ブランチはまだ削除しない。
1. production でのテストを突破すれば、他の環境へ feature をばらまく。
手動テストが必要で、先に staging 等の環境へ反映したい場合は feature を通常通り上流から下流へ流していってもいい。

環境名が説明的なので環境の上下関係がわかりやすいからそりゃそうだろ。というルールに見えるが、もっと自由な環境名になるとブランチは上流から下流へというルールの遵守が肝要になるかな？という感じ。

そして hotfix の場合のみ全環境に個別に適用することができるといった感じだろうか。


### 登場するブランチ

|名称|役割|分岐元|マージ先|備考|
|:-:|:-:|:-:|:-:|:-:|
|{environment name}|環境名を関したブランチ|1つ下流のブランチ|||

開発時の運用については言及されていない


## release ブランチ

release ブランチは外部にソフトウェアを公開する場合にのみ使用する。

複数バージョンを管理する場合を想定した運用方法だろうか。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315470/75fe6c07-2099-7260-7e64-5d1da8aeded7.png)


1. ブランチ名には 2.3-stable のようにマイナーバージョンまで含まれる。
ブランチ 2.X が切られて、そこから 2.3 や 2.4 が分岐するという風にはならない。
1. main ブランチから release ブランチは作成されて、可能な限り分岐し続ける。
複数のブランチにバグフィックスを適用しなければならない期間を短くすることを期待している。
1. release ブランチ作成後は重大なバグフィックスのみを適用する。
可能であれば main ブランチに修正を加えた後チェリーピックで各 release ブランチへ適用したい。
release への適用のみを急ぐと、後で main へ取り込み忘れて将来再度同じバグに遭遇する可能性があり、それを恐れている。
“upstream first” policy という。
1. セマンティックバージョニングに準拠するため、パッチを当てたらパッチバージョン(X.Y.Z の Z)を上げてタグをつける。
ブランチ名にはマイナーバージョンまで、タグにはパッチバージョンまでつけるということだろう。
1. このフローでは production ブランチや git flow における main ブランチなど、他のモデルでリリース済みコードの保持を担っていたブランチを用意する必要がない。

### 登場するブランチ

|名称|役割|分岐元|マージ先|備考|
|:-:|:-:|:-:|:-:|:-:|
|main|開発者が利用するブランチ||||
|{バージョン番号(X.Y)}|リリース内容を保持する|main||パッチバージョンまで含めたバージョン番号はタグで管理される(X.Y.Z)|

やはり開発時の運用については言及されていない


## まとめ
今までのフローと違って内部でいくつかのモデルに分かれているような説明がなされている。

さらにのちには merge request の扱い方、良いコミットメッセージの書き方など git 運用上のポイントのようなものが用意されていますが、git ブランチそのものの流し方についてはいったんここまで。

一度 GitLab Flow についてまとめてみたい。


### 長所
- どのモデルも git flow 程の煩雑さはない
- CD の導入されていない、導入が適当でないプロジェクトに対する回答が行われている。
  - リリースタイミングを調整したい。(production ブランチ)
  - staging 環境と production 環境など、レベルの異なる複数環境を保持したい。(environment ブランチ)
- 複数環境を保守する必要のある状況への回答が行われている。(release ブランチ)
 
### 短所
- git flow, GitHub flow の問題点を解消しようという目的に主眼を置いたためか、それらの問題点の解消方法以外の部分への言及が少ない。
(開発時はどのようにコードを管理するのか。staging ブランチや develop ブランチから作業ブランチを切るのか？)
- それゆえに、運用時には加えてルールの策定が必要
(プロジェクトに GitLab flow の production ブランチモデルで運用します。と宣言しても、前項のような不明点が残る)
- 同一組織、複数プロジェクトにおいて微妙に細部の異なるルールを布いてしまった場合、説明コストが発生する。

概ね、他のモデルでの運用を行った、あるいは検討したことがあるが不満のあった部分に対する解決策を提供するような資料であると感じた。

実際の利用にはいずれかのモデルをベースに拡張したルール、あるいはいずれかのモデルを使用した他のルールの拡張という行為が必要になるかもしれない。

***


以降の項目は git ブランチワークには直接関係しないもの。

- Merge/pull requests with GitLab flow
- Issue tracking with GitLab flow
- Linking and closing issues from merge requests
- Squashing commits with rebase
- Reducing merge commits in feature branches
- Commit often and push frequently
- How to write a good commit message
- Testing before merging
- Working with feature branches

翻訳くらいしかできることが無いので他の記事や原文をあたってほしい。

***

# 参考
[Introduction to GitLab Flow](https://docs.gitlab.com/ee/topics/gitlab_flow.html)
[GitLab flowから学ぶワークフローの実践](https://postd.cc/gitlab-flow/#gfm-3)