ウェブサイト運用プロジェクトに適したGitのブランチモデル「Webmaster's Git-Flow」

Gitのブランチモデルといえば、 Git-Flow、 Github Flow、 GitLabFlow などが有名です。 いずれもアプリケーションなどのソフトウェア開発に適したフローになっていますが、そのままウェブサイト運用プロジェクトに適用するのは難しいことが多いと思います。

本稿では、既存のブランチモデルをベースに改良を加え、一般的なウェブサイトの運用プロジェクトに適したブランチモデルを考えたいと思います。




## ソフトウェア開発とは異なる、ウェブサイト運用プロジェクトによくある事情

本来の Git-Flow では対応が難しいいくつかの特殊な前提があります。

1. 複数のリリースにかかる編集作業が同時に進行している。
2. 更新内容ごとに、リリース日が決まっており、混ぜてはいけない。
    - リリース日の前後が逆転してはいけない。
    - 別の日の状態を統合してはいけない。
    - コードの機密性が高い。あるコードが、予定された公開解禁日時よりも前に公開されてしまうこと(フライングリリース)は、情報漏えいでありあってはならない。
3. プログラミング的なロジックではなく、HTMLドキュメントを扱う割合が多い。
4. リリース判定の権限を持った担当者が複数いて、それぞれ担当範囲が異なる。
5. リリース日別の状態を、それぞれ予め確認したい。

ソフトウェアのソースコード管理と特に異なる事情は 1 と 2 です。

ソフトウェアの場合、完了した修正タスクをリリースせずに "とっておく” ということが必要なケースは想定しにくいですが、ウェブサイトの掲載情報はリリース日よりも早くても遅くてもいけなく、予定通りのタイミングでリリースしなければいけません。そのため、遠い先の日に更新予定の内容が先に完成したとしても、すぐにマージできず、待機させておける必要があります。

3 の事情も深刻です。 インデントや複数行に渡るテキストの修正、改行、交互に現れる類似するタグの行、画像ファイルなど、有機的な更新差分が多くなりがちです。 長文の自然言語からなるHTML文書の更新差分を人間の目で把握するのは難しく、行数もかなりの量になります。 行単位の手動マージに挑んで気が遠くなった経験のある人も多いことでしょう。

また、ページによって主管の担当者が異なる 4 のケースもよくみかけます。このケースでは、基本的に 5 もセットでついてきます。

社内の組織の体制的に、別のセクションになっていることも多く、入稿やリリース判定チェックのタイミングなどもなかなか足並みが揃いません。


こうした課題を解決できるブランチモデルを検討します。



## ブランチモデル

Git-Flow をベースに、ウェブサイト運用プロジェクトでよくある前提を想定した改良を加えていきたいと思います。

各ブランチそれぞれ、Git-Flow の定義と微妙に異なりますが、 最も大きく違うのは releaseブランチ と stagingブランチの役割です。


### master ブランチ

master ブランチには、リリースが確定した内容だけをマージします。

master ブランチへのマージは、緊急の割り込みリリース(hotfix) 時以外は、staging ブランチからしか行いません。

本番サーバーとmasterブランチの内容は常に一致している状態が理想的です。

場合によっては、Webhookなどの仕組みを使ってmasterブランチの内容を自動的に本番サーバーへデプロイするような環境構築もあると思います。

![master.png](https://qiita-image-store.s3.amazonaws.com/0/28914/6759e9cb-016a-2ffd-dc5e-37f591112e0d.png)





### staging ブランチ

staging ブランチには、 次回リリースの内容だけをマージし、リリース前の最終確認を行います。

ステージングサーバーとstagingブランチの内容は常に一致している状態が理想的です。

![develop.png](https://qiita-image-store.s3.amazonaws.com/0/28914/22957e07-4d9a-a95e-3b69-b788a1d3958a.png)





### release ブランチ

このブランチモデルで最も中心的な役割を持つのが release ブランチです。release ブランチは リリース日 ごとに管理します。複数の release ブランチを並行して進行することができます。

ブランチ名には、 リリース日 がわかる名前をつけます(例: `release-2018-11-13`)。
releaseブランチは、その1つ前のリリース分の release ブランチから分岐します。 release ブランチが1つもない状態のときは、stagingブランチから分岐します。

複数のリリース日の更新作業が同時進行している場合、それぞれの更新日ごとの内容を確認したいことがあります。 ステージングサーバーとは別に、いくつかの確認環境を用意し、次回以降のリリース分のブランチをデプロイできる準備をしておくと、チェックと承認のプロセスがスムーズに進行できる場合があります。

release ブランチは 最終的には staging ブランチへマージし、リリース判定を受けます。
複数の release ブランチがあるとき、 リリース日の最も近いブランチを staging ブランチへマージし、その他の releaseブランチはそのまま待機させます。

長期間 release ブランチの作業が続くときは、release ブランチ同士のマージをしたくなることがあります。この時、手前から未来方向へのマージのみを可とし、過去方向のマージはしてはいけません。情報漏えい(フライングリリース)の原因となるためです。

リリースが完了した releaseブランチは削除します。

![release.png](https://qiita-image-store.s3.amazonaws.com/0/28914/d3a76899-e14d-6c90-68b3-02762d7a9d52.png)






### feature ブランチ

feature ブランチは、各作業者の作業ブランチです。

作業は公開日ごとに分けて進行します。従って、 分岐元は、リリース予定日の releaseブランチです。

更新作業が完了した feature ブランチ のマージ先は、常に 予定されたリリース日の releaseブランチです。つまり、必ず分岐した元へ戻されます。

releaseブランチへマージが済んだ featureブランチは削除します。

![feature.png](https://qiita-image-store.s3.amazonaws.com/0/28914/3c65373e-fd47-9625-90e9-0f72ce59e49c.png)




### hotfix ブランチ

hotfixブランチは緊急の割り込みリリースが必要なときに使います。

必ず master ブランチから分岐し、 内容が確定したら master, staging, 待機しているすべての releaseブランチへマージします。

マージされた hotfixブランチは削除します。

![hotfix.png](https://qiita-image-store.s3.amazonaws.com/0/28914/07f07fea-a0d4-db78-8d1c-97bfe219c1e6.png)



### リリース日が未定の更新タスクをどう扱うか？

リリース日が未定のまま制作をスタートしなければならない変更がある場合は、リリース日未定の releaseブランチ(例: `release-X` など) を作成してひとまず待機しておきます。リリース日未定の変更が複数ある場合は、混ぜてしまわないように注意します。リリース日が決定した時点で、正規の releaseブランチへマージして、このブランチは削除します。




## ウェブサーバーの構成

一般ユーザーに公開されている「本番サーバー」、本番への公開直前に最終確認を行う「ステージングサーバー」を用意します。

本番サーバーは master ブランチに、 ステージング環境は stagingブランチにそれぞれ対応します。Webhookなどの仕組みを使って自動的にデプロイさせる方法もあります。

更新頻度が高く、複数のリリース日の更新作業が同時に進行するようなプロジェクトの場合は、次回以降のリリース分をリリース日ごとに確認できる確認用サーバーをいくつか用意しておくとよいでしょう。このサーバーは、確認要請に応じてreleaseブランチと同期させます。





## まとめ

以上、ウェブマスターのための Git-Flow について考えてきました。

ブランチモデルを全部まとめると次のような図になります。

![full.png](https://qiita-image-store.s3.amazonaws.com/0/28914/76a66d0b-13e6-8656-4140-f4a720dcb4f3.png)




それでは、安全で快適なウェブマスターライフを。