🌊

スタートアップでのウォーターフォール開発におけるGitワークフロー

commits6 min read

最初期のスタートアップとして新しいプロダクトを作る場合、初めはウォーターフォールで開発することが多いと思います。その時、特に複数人で開発する場合は、Git のブランチワークフローをどう規定するのかは悩みどころです。そういった悩みのいち解決案として、こちらの記事をご覧いただけたらと思います。

こちらの記事は、スタートアップで Tech Lead や CTO 等として働くことになった or 現在働いている方に役立つかも、という思いで公開しています。ご自身の働かれている会社様のフェーズによっては、この記事とは相性が悪いかもしれません。予めご了承いただけると幸いです。

Gitブランチワークフローとは

Git ブランチワークフローは、一般には Git ワークフローと呼ばれています。ただし、ワークフローという名称はブランチ以外も指しそうに感じるため、便宜上、Git ブランチワークフローと呼んでいます。こちらの記事では、タイトルでは一般名を使用し、本文では統一してもう一方を使用しています。適宜、ご自身の語彙に合わせて読み替えてください。

Git ブランチワークフローとは、代表的なものでいうと、git-flowGitHub flowといったブランチング規定のことを指します。例えば、git-flow だと複雑で、以下のようになっています。

git-flow
git-flow
Source: A successful Git branching model

逆に、GitHub flow は、一般にそれを単純にしたものと言われています。ここでは詳しい解説はしませんが、git-flow は複雑で、GitHub flow は単純という認識で大丈夫です。

Gitブランチワークフローを定義する

まず、初期のスタートアップだからといっても、main ブランチに直接プッシュして開発を進めるのは流石に問題です。一人で開発している場合はまだしも、複数人で開発している場合は、問題の発生タイミングや発生自体に気づきにくいです。何か問題がある度に、git bisect するとなれば、納期を守れるか非常に不安な開発になってしまいます。

しかし、あまりにしっかりとしたワークフローを採用してしまうと、採用するエンジニアの敷居も上がり、なにより開発速度を鈍化させる可能性が高くなります。そういった問題を考慮した上で、初期スタートアップでのウォーターフォール開発に向いたワークフローを考える必要があります。会社がこのフェーズにある時、最も重要視しなければいけないことは以下の3つです。

  1. 速度感
  2. 確実性
  3. 簡便性

3の簡便性に関しては、1と2を考慮する上で必要なことのため、それらのみで考えても問題ありません。

いかなるフェーズにおいても、それらは重要ですが、特に1の速度感に重きが置かれるフェーズかと思います。速度感を上げるのに必要なこととしては、エンジニア達にとって簡単であり、尚且継続的なデプロイが素早く行えることかと思います。初期スタートアップでのウォーターフォール開発において、継続的なデプロイを行われていない会社様もおられるとは思いますが、ここで言うデプロイとは、社内レビュー用の開発環境やステージング環境へのデプロイを示します。

継続的なデプロイは、初期スタートアップには不要だという意見もあるかもしれません。しかし、継続的なデプロイは、いくらウォーターフォールであっても、2の確実性を担保するためにも必要なことだと思います。開発が全て終わったあとで、デプロイを行い、手動での結合テストを行ったとき、あらゆる部分で不具合があれば大問題です。後戻りコストが計り知れないため、PR 毎の目視レビューまではいかなくても、定期的に継続的デプロイされた開発・ステージング環境で、キチンと動作していることを確認することが好ましいです。そして、その継続的なデプロイを効率良く行うことで、速度感を上げることに繋がります。

エンジニアにとって簡単にすることと、Git ブランチワークフローの堅牢性・利便性はトレードオフなため、それらの方が重要だと考える方もおられるかもしれませんが、あくまでこのフェーズにおいては、特に速度感が重要です。そのため、ある一定それらは捨て置き、速度を考慮したブランチワークフローを定義します。後ほど詳しく説明しますが、Git ブランチワークフローとしては捨て置くだけで、GitHub の設定でカバーできる部分もあるため、そちらと組み合わせて最適なものを考えます。

これらの条件を満たす Git ブランチワークフローを以下のように定義しました。

ウォーターフォール開発のためのGitブランチワークフロー
ウォーターフォール開発のためのGitブランチワークフロー

こちらのブランチワークフローは、GitHub flow をベースにしているため、ブランチング方法は全く同じです。違うのは、デプロイタイミングやプルリクエストを開くタイミング等の、会社としての開発に適した細かい最適化部分のみです。

GitHub flow をベースした理由は、main からのブランチ派生のみのため、git 及び GitHub の基本的な知識があれば対応可能だからです。特に現フェーズにおいて、採用コストや教育コストを上げることを防ぐことができます。また、このブランチワークフローをエンジニアが上手く使用できない場合は、レビュアーである自分が苦労することになり、ひいては速度感が出ないことにも繋がりかねません。開発をマネジメントするためのツールとして、ブランチワークフローを使用します。

デプロイは GitHub Actions 等を使用していることを前提にしています。デプロイタイミングとしての最も理想は、以下のようにします。

  1. main ブランチに push した時、開発/ステージング環境にデプロイ
  2. main ブランチに tag をプッシュした時、本番環境にデプロイ
  3. (任意) PR にプッシュした時、開発/ステージング環境のプレビューにデプロイ

それぞれの詳細は、この記事内の「GitHub Actions を使用して継続的なデプロイを行う」節で説明します。

また、それぞれの細分化したチケット等に着手してもらうタイミングで、連絡してもらうようにしています。そのチケットにおける最初のコミット時に、そのブランチをプッシュ&プルリクエストを開いてもらうようにします。GitHub flow では、コミットを溜め込んだ後に、プルリクエストを開くようにされていますが、それではエンジニアが実際に開発してくれているのか分かりません。そうなると、それこそ納期を守ることが難しくなるため、初めから連絡してもらい、適宜時間がかかっている場合は、コミュニケーションを取ることができます。

GitHub Actions を使用して継続的なデプロイを行う

Lint 等の基本的な CI もセットアップしていると尚良いですが、一旦自動デプロイだけでも構成しておくと、今後の作業が非常に楽になります。

1. main ブランチに push した時、開発/ステージング環境にデプロイ

こちらは、シンプルで、以下のような workflow ファイルを書くと実現できます。

name: Product X (Dev)

on:
  push:
    branches: [ main ]

jobs:
  deploy:
    ...

2. main ブランチに tag をプッシュした時、本番環境にデプロイ

こちらも、とてもシンプルに済ませることが可能です。ただ、GitHub Environments と組み合わせることで、特定の GitHub ユーザーの承認を通してからしか本番環境にデプロイできないような、安全なワークフローを組むことができます。こちらに関しては、別の記事で紹介します。

name: Product X (Prd)

on:
  push:
    tags:
      - 'v*'

jobs:
  deploy:
    ...

3. (任意) PR にプッシュした時、開発/ステージング環境のプレビューにデプロイ

こちらは、pull_request イベント時に、CI を回すように設定する必要があります。また、任意としていますが、実現すればコードレビューに加えて、目視でのレビューも可能なため、非常に安全な開発フローになります。

フロントエンドの場合でかつ、SPA の場合は、Firebase Hosting を使用することで簡単に実現できます。Firebase Hosting には、Preview Channel というものが用意されていて、プルリクエスト毎に URL を発行し、そこにアクセスすることでレビューできます。設定に関しては、Firebase CLI を使用することで、簡単にセットアップできます。

上記のセットアップを行うことで、以下のように Preview Channel 用のリンクが生成され、PR 上にコメントを生成してくれます。

Firebase Hostingのプレビューリンクコメント
Firebase Hosting のプレビューリンクコメント
Source: Deploy to live & preview channels via GitHub pull requests

詳細は以下のリンクを参照してください。

https://firebase.google.com/docs/hosting/github-integration

SPA ではない場合や、そもそもフロントエンドでない場合は、Firebase Hosting を使用できません。しかし、Cloud Run を使用すれば、そういった場合でもプレビューデプロイを実現できます。そちらに関する詳細は、プレビューデプロイをCloud Runで行うにて紹介しています。

GitHub で Branch protection rule を設定する

折角ブランチワークフローと CI/CD を用意しても、それに適した Branch protection rule を設定しなければ、誤ってマージしてしまう危険性が高まります。基本的にレポジトリに対する権限を適切に設定していれば、リードである自分は、Administrator で、エンジニアが Write 権限として設定されていると思います。その時、Branch protection rule を設定していれば、エンジニアが強制的にマージできなくなるため、非常に安全です。マージを行えるのは、リードである自分で、レビューした後にマージボタンを押せるようにすると良いかと思います。

Branch protection rule の設定方法は、レポジトリページの、Settings -> Branches -> Branch protection rules から設定できます。お好きな設定を入力し、Create ボタンをクリックして作成してください。こちらの記事のイメージで設定されている場合は、レビュアーがいて、CI/CD が設定されていると思います。その場合は、Require pull request reviews before merging や Require status checks to pass before merging 等を有効にすると、誤ってマージすることを防ぐことができます。

今後の流れ

上記の設定で、だいぶ複数人での開発がスムーズに行え、素早く、確実にプロダクトを完成に導けるかと思います。

会社のフェーズに合わせて適切な手法を選択することが、特にスタートアップには大切です。最初から高可用な構成にした k8s を使用して、莫大なインフラ費用がかかっていてはバーンレートがすごいことになってしまいます。特に大した数のユーザーもついていないフェーズでは、Cloud Run を使用するなどの対応策が考えられます。

長い間ウォーターフォール開発で進めてしまうと、エンジニア達やリードをとっている自分自身が疲弊していってしまいます。そのため、closed alpha 版等のリリースタイミングで区切りを付け、アジャイル開発へと転換していくのが良いと思います。

そういった、初期スタートアップのフェーズでかつ、アジャイル開発に適した Git ブランチワークフローに関しては別記事で紹介します。もし良ければご覧ください。

GitHubで編集を提案

Discussion

ログインするとコメントできます