SENSYN Roboticsのブランチ戦略

# はじめに

SENSYN Roboticsではお客様との共同開発という形でプロダクトを構築しており、プロダクトやプロダクトを構成するリポジトリの数がかなり多くなっています。
ブランチ戦略は基本的にgit-flowを使っていたのですが、リポジトリ毎に微妙に差があって開発・運用が煩雑になっていました。

# ブランチ戦略の統一

そこで、ブランチ戦略を統一して開発・運用を簡単にしようとしています。
また、git-flowはWeb開発にはあまり合わない(煩雑な割にメリットが少ない)と感じていたので、GitHub flow+タグ打ちリリースという戦略を採用しました。

# git-flowの問題点

ここまでgit-flowで数年間続けてきたのですが、デスクトップアプリ向けのワークフローという印象でWebでのサービス開発にはマッチしないように感じています。
Webでのサービス開発で管理しているのは本番環境にリリースしている一つだけのバージョンですが、git-flowは複数のバージョンを管理する想定になっています。
その結果としてリリースまでの手順が多くなり、開発者の負担になっていました。

# GitHub flow+タグ打ちリリース

GitHub flowはmainブランチと各機能の開発を進めるfeatureブランチの二種類のブランチだけを使うワークフローです。
featureブランチのレビューが終わったらmainブランチにマージして即座にリリースされるのが本来のフローですが、SENSYN Roboticsの場合はドローンでの飛行試験を行わないとリリースできないケースも少なくないため、マージ即リリースというのは難しいです。
そのため、mainブランチとfeatureブランチのみを基本とするところはそのままに、タグを打ったらリリースフローが走るようにするカスタマイズを加えています。

タグにはバージョン名を指定し、リリース候補を意味するRCタグ(`v1.2.3-rc4`形式)と、リリースを意味するバージョンタグ(`v1.2.3`形式)の二種類を利用します。
RCタグが指定された場合はステージング環境にデプロイされ、バージョンタグが指定された場合は本番環境にデプロイされます。
また、mainにマージされたら開発環境にデプロイするようにしています。

```mermaid
%%{init:{
    'themeVariables':{
        'tagLabelFontSize': '10px'
}}}%%
gitGraph
  commit
  commit
  commit
  branch feature/upload
  branch feature/layout-bug
  checkout feature/upload
  commit
  commit
  checkout feature/layout-bug
  commit
  commit
  checkout main
  merge feature/layout-bug
  branch feature/background-jobs
  checkout main
  merge feature/upload
  checkout feature/background-jobs
  commit
  commit
  checkout main
  merge feature/background-jobs tag: "v1.3.0-rc1"
  branch feature/trivial-bug
  checkout feature/trivial-bug
  commit
  checkout main
  merge feature/trivial-bug tag: "v1.3.0-rc2 v1.3.0"
  branch feature/embed-ai
  checkout feature/embed-ai
  commit
  commit
  checkout main
  merge feature/embed-ai
```

# Hotfix

GitHub flow+タグ打ちリリースには本来のGitHub flowにはない問題が一つあります。
デプロイされたバージョンに緊急性の高い問題が見つかったときのリリースです。

本来のGitHub flowであればmainブランチに修正を入れてマージ&リリースを行うだけですが、タグ打ちリリースではそうもいきません。
SENSYN Roboticsではこの問題に対処するため、hotfixブランチを導入しています。複雑性は増しますが、hotfixを行う機会はそれほど多くないため、割り切ることにしました。

運用としては

1. 本番環境にリリースされているバージョンのタグから、hotfixブランチを生やす
2. hotfixブランチで修正〜テストを行う
3. レビューを受けて通ったらmainブランチにマージする (このときhotfixブランチを削除しない)
4. mainブランチにマージされると開発環境にデプロイされるので、そこで確認を行う
5. hotfixブランチにRCタグを打ってステージング環境にデプロイする
6. hotfixブランチにバージョンタグを打って本番環境にデプロイする

となります。
hotfixブランチにタグを打ってリリースすること、mainにマージする点は他のfeatureブランチと同じ扱いになることがポイントです。
リリース後に別の問題が見つかったら、hotfixブランチから新たなhotfixブランチを生やします (= `本番環境にリリースされているバージョンのタグから、hotfixブランチを生やす`)。

```mermaid
gitGraph
  commit
  commit tag: "v1.2.0"
  branch hotfix/crash-bug
  checkout hotfix/crash-bug
  commit tag: "v1.2.1-rc1"
  checkout main
  merge hotfix/crash-bug
  checkout hotfix/crash-bug
  commit
  commit tag: "v1.2.1-rc2 v1.2.1"
  branch hotfix/security-fix
  checkout hotfix/security-fix
  commit
  commit tag: "v1.2.2-rc1 v1.2.2"
  checkout main
  commit
  merge hotfix/crash-bug
  commit
  merge hotfix/security-fix
  commit
```

# 課題

現在はすべてのリポジトリにこのブランチ戦略を適用できているわけではなく、徐々に適用を進めているところです。
そのために[KAIZEN Day](https://qiita.com/adachin0817/items/c6c78a4564401a772cf0)が役立っています。
ただ、リポジトリ数がとにかく多いので、全てのリポジトリに適用するのはかなり時間がかかりそうです。

また、リポジトリ数の多さは複数のリポジトリで一つのプロダクトを構成していることに起因しています。
これはマイクロサービスアーキテクチャを採用しているためですが、リリース漏れの原因になったりもするので、プロダクト単位で一つのリポジトリに集約することを検討中です。

# まとめ

* Webサービスの開発にはgit-flowよりGitHub flow+タグ打ちリリースが向いている
* 本来のGitHub flowより複雑になるが、リリースタイミングの柔軟性を確保できる