目次
はじめに
Insight EdgeのLead Engineerの三澤です。
Insight Edgeでは開発プロジェクトに応じてその時々でチームを編成し、プロジェクトの内容に合わせてチーム単位で技術やアーキテクチャや開発ルールの選定・決定をしています。
今回は直近の開発で運用してきた開発ルール(ブランチ戦略)の1つGitHub Flowについて、実際の運用方法や良かった点・悪かった点をご紹介したいと思います。
本記事ではGitとブランチを既知のものとして進めることにご了承ください。
ブランチ戦略
GitHub Flowの話へいきなり入る前に、まずはなぜブランチ戦略を考える必要があるのかを考えてみます。
皆さんもGitを用いて複数人で開発を進めることがあるかと思いますが、その際には各自がブランチを作成し開発を進めるのが一般的です。しかしこの時、もしブランチ戦略を決めずに各開発者が勝手にブランチを作成してしまうとどうなるでしょうか?各ブランチの意味が不明瞭になるだけでなく、ルールを決めずに開発を進めますので各ブランチのコードをマージするのも一苦労になります。さらに、ブランチが乱立することになりますので、どのブランチが正しく動くソースコードなのかが分からなくなるといった問題を引き起こす可能性があります。ブランチ戦略は、そのような問題に対してルールを定めそれに則って開発を進めることによって解決を図るものです。
ここでは3つの代表的なブランチ戦略を簡単にご紹介します。
Git Flow
Git Flow は、Vincent Driessenが2010年に提案したブランチモデルです。masterを安定ブランチとして、そこから分岐したdevelopブランチを開発用のブランチとして開発を進めます。開発者はdevelopブランチから機能毎にfeatureブランチを作成して開発を進め、developブランチへマージを繰り返すというのが基本動作です。その後、developブランチで一定の機能開発やバグフィックスが完了するとreleaseブランチを作成します。このreleaseブランチではリリースの準備としてコードの整理やテストなどが行われます。ここで問題がないことを確認できたらいよいよreleaseブランチの内容をmasterブランチへマージされ本番環境へリリースされます。このようにブランチを用途によって適宜使い分けながらタスクやリリースの管理や安定性の確保しますので、各ブランチの役割が明確になるというメリットがあります。一方で、パッと見てわかる通りブランチの種類が多く管理が複雑になるというデメリットがあります。
GitLab Flow
GitLab Flow は、GitLabが提唱するブランチ戦略です。Productionブランチモデル、Environmentブランチモデル、Releaseブランチモデルといったいくつかのパターンがあるのですが、ここではEnvironmentブランチモデルを紹介します。GitLab Flowでの機能開発はGit Flowと異なりdevelopではなくmasterブランチから分岐したfeatureブランチで行います。featureブランチでの開発が完了すると、その内容をmasterへマージし検証環境でテストするという作業を繰り返します。その後、ある程度開発が進んだタイミングでリリース準備を行います。リリース準備はmasterブランチから分岐したpre-productionブランチで行い、問題がなければ本番環境へリリースされます。このリリースしたコードはproductionブランチにマージされ、終了するという流れです。Git Flowほどの厳密なリリース管理が不要になるというメリットがありますが、それでもやはりまだ複雑というデメリットがあります。
GitHub Flow
GitHub Flowは、GitHubが提唱するGitLab Flowよりもさらにシンプルなブランチ戦略です。開発はmainブランチから派生したfeatureブランチで行います。featureブランチで開発が完了するとmainブランチにマージされ、このマージされた内容が本番環境へリリースされます。このmainブランチには常にデプロイ可能な安定したソースコードが格納されていることを前提としているのが特徴です。ブランチが2本しか存在しないのでとても理解しやすく、mainブランチにマージしたことを基本としてリリースされるので、開発した内容を短いサイクルでリリースにつなげられることがメリットになります。一方でmainブランチの内容が常にリリースとなることから、検証環境へのリリースやリリースバージョン管理が出来ないというデメリットがあります。なお、我々のチームではGitHub Flowをベースに一部改変することでそのデメリットを克服しています。その内容については後ほど紹介します。
開発チームのブランチ戦略
GitHub Flowの採用理由
タイトルにも書いている通り、我々のチームではGitHub Flowを採用しています。一方で、私の開発経験としてはこれまでGit Flowのブランチ戦略を採用することが多かったです。そのためGit Flowで進めるという選択肢もありました。では、なぜ我々のチームがGitHub Flowを採用したかというと、Insight Edgeでは小回りの効く比較的小規模なチームで素早く開発をすることが多かったから、が理由になります。Git Flowのような厳密な管理をするブランチ戦略は、先の説明の通りリリースまでの工程や確認が多くなります。そのため、こまめに機能をリリースしながらシステムをアップデートしていくというアジャイル的な我々の開発スタイルにミートしませんでした。GitHub Flowのようにシンプルでこまめにリリースを重ねていける開発スタイルが小規模チームは適していると考えました。
一方で先にも触れた通り、GitHub Flowはmainブランチの内容が常にリリースとなることから、検証環境へのリリースやリリースバージョン管理が出来ないというデメリットがあります。そのために我々はGitHub Flowに一部改変を加えています。ここでもしかすると、リリース管理を行うGitLab Flowでも良いのではないかという疑問が湧いてくるかもしれません。しかし、こちらについては管理するブランチ数はなるべく減らしたいこと、リリース管理自体はproductionブランチがなくてもタグで代用できることから採用を見送りました。
運用の基本ルール
Insight EdgeではGitHubをプラットフォームとして採用していますので、以降は基本的にGitHubでの用語を用いて我々の開発ルールを説明します。
開発環境
リリースする環境としては、以下の3つを準備しています。
dev
開発者がいつでも任意のタイミングでリリースして良い開発環境。
stg
mainブランチへのマージ後に必ずリリースされる本番適用前の検証環境。
prod
stgでの検証後にリリースされる本番用環境。
ブランチ
作成するブランチは下記の2本になります。
mainブランチ
安定ブランチです。常にリリース可能なソースコードを管理します。
feature/xxxxブランチ
mainブランチから切ります。開発する機能に応じて作成します。xxxxには開発する機能の内容が書かれます。
Pull Request
featureブランチで開発が完了するとmainブランチにマージするためPull Requestを開発者が発行します。レビューはリポジトリ管理者と、開発メンバの2人で実施します。2人のレビューによるレビューで問題がなければマージされますが、このマージはfeatureブランチの作成者が行うのではなくリポジトリの管理者が責任を持って行います。
手順
以下が簡単な開発の流れになります。
- mainブランチからfeatureブランチを作成
- featureブランチで開発完了後、mainブランチへPull Request
- featureブランチの内容をレビュー。問題なければmainブランチにリポジトリ管理者がマージ
- mainブランチにマージ後、stg環境へリリース
- stg環境にてマージされた内容の動作を確認
- stg環境で問題なければリポジトリ管理者がリリースバージョンを示すtagを付与
- (前回の本番環境へのリリース内容と今回のリリース内容の差分を示すリリースノートを作成)
- tagの付与されたコミットをprd環境へリリース
通常のGitHub Flowは、手順1-4の流れを繰り返しますが、我々は6以降の手順を追加して運用しています。tagを活用することによって追加のブランチを作成する必要が無くなりますし、prd環境へのリリースバージョンが明確になるという嬉しさがあります。
手順7についてはプロジェクトによっては作成しないこともあるためカッコ付きとしています。我々の開発では、GitHub Actionsで前回のtagと差分を取得しリリースノートを自動作成するようにしています。tagと一緒にリリースノートも作成することで前回との差分が一目瞭然となるため非常に便利です。
また、stg環境へのリリースもGitHub Actionsでmainブランチへのマージをトリガーとしてリリースされるようにしています。prd環境へのリリースについてもGitHub Actionsでリリース出来るようにしていますが、こちらについては最後に人手の承認を挟んでからリリースするようにしています。
上記の手順でそれぞれどの環境にどの内容がリリースされているのかを示したのが下記の図になります。mainにマージされたものは全てstgにリリースされますが、prdへはtagのついたものだけがリリースされます。
その他、開発時のポイント
GitHub Flowだからというわけではありませんが、次のような点にも気をつけて開発を進めています。
レビュアーのレビュー負荷を下げるために
- Pull Requestのサイズはなるべく小さくしています。目安は1-2時間でレビュー出来る分量です。
- lintに加えてSonarCloudによるソースコードの静的解析をPull Request時に適用しています。静的解析が通らないとマージできないようにしており、一定の品質が保たれるようにしています。
実際にGitHub Flowを運用してみて
GitHub Flowの採用により現在のところ大きな課題はなく運用ができていると感じています。もちろん今後開発の規模が大きくなった時等には新たな課題が出てくることが予想されますが、小規模チームで高速にプロダクトをリリースしていくのに良くフィットした開発ルールと言えます。
最後に運用してみて良かったこと、悪かったことを紹介して終わろうと思います。
良かったこと
- シンプルな運用フローであるため学習コストが低い
- 小さい単位でのPull Requestとコードレビューにより、品質管理とフィードバックのサイクルがスムーズになった
悪かったこと
- こまめにPull Requestを発行するのでレビュー頻度が高くなりがち。特にレビューはリポジトリ管理者に集中し負荷が高い状態が続いてしまった
- 対策:Pull Requestの発行時に、変更内容の詳細やレビューしてほしい観点を細かく記載することで認知負荷を下げる。チーム編成時のコーディングルールの事前すり合わせを徹底する
- ブランチが2本しかないのでmainブランチへのマージ時にコンフリクトが発生することがあった
- 対策:こまめにPull Requestとは言うものの、その単位が大きいことがしばしばあったため、変更を小さな単位で頻繁にレビュー・マージすることを徹底することで、マージ時の競合の範囲を減らしていく
まとめ
小規模開発チームが取るべきブランチ戦略としてGitHub Flowに着目し、我々のチームがどのように運用してきたかをご紹介しました。GitHub Flowは素早くプロダクトがリリースできることからPoCなど、価値検証を高速に回していくことが求められる開発現場に特にフィットすることが確認できました。
Insight Edgeでは一緒に変革しながら価値検証ループを高速に回していけるメンバを募集中です!技術選定はもちろん、このような開発ルールについても柔軟に変革できる環境となっていますので、興味がある方はカジュアルにお話させて頂ければと思います。お気軽に 公式サイト の採用ページからお申し込みください!