1
/
5

【Quipperブログ】Quipper の Monorepo な Web アプリ開発における Git 戦略

こんにちは。Quipper採用担当の鈴木です。今回の記事は、Web Developerの@mtsmfmによる「Quipper の Monorepo な Web アプリ開発における Git 戦略」です!是非、ご覧ください!

Rails Developers Meetup 2019 の自社スポンサーセッションはいっそ休憩室にすればいいのでは? と言い出した Web dev の @mtsmfm です。お弁当や神授業、そして Quipper からは 3 名が登壇しましたが、発表は楽しんでいただけましたでしょうか。

僕は自分の発表@jeremy さんが聞いてくださったり、キーノートでは Rails 6 で入ったパッチを紹介してもらったりして感無量です。
この場を借りて Rails DM の開催に尽力された @yhirano55 さん他みなさまには感謝を述べたいと思います。本当にありがとうございました。

今日は、Quipper における Git ブランチ と Kubernetes を組み合わせた、開発から本番デプロイまでの流れを紹介したいと思います。

流れ

ざっくりとした概要としては Git flow をアレンジしたものを使っています。

まず、開発のベースとなるものは develop ブランチです。ここから機能追加ブランチを切り、PR を develop に向けて出すのが基本です。PR 毎に Heroku で言うところの Review app のように、PR 毎に Kubernetes の namespace が作られます。

Quipper では先日、monorepo への移行をしました。これにより、一つの機能を実装するために API とフロントの両方に PR を出さないといけなかったり、場合によってはそれに加え社内 gem にも別途修正が必要だったものが、1 つの PR を出すだけで済むようになりました。また、PR 毎のステージング環境も Kubernetes でまるごと起動するようにしたため、動作確認のために個別のステージング環境を環境変数を切り替えて繋がるようにする必要がなくなりました。便利ですね。

次に、release ブランチです。release ブランチは毎回リリーステスト環境にデプロイされます。Quipper では現在概ね週に1回、QA の会社に手動テストをお願いし、テスト通過後に本番デプロイをしています。リリーステスト中に発覚した問題は release ブランチへ PR を出します。Git flow では release ブランチは新しい release-xxx ブランチを作ることになっていますが、Quipper では簡便化のために release ブランチは毎回リリース後に削除し、 develop ブランチを release ブランチとする流れです。

本番へのデプロイは master ブランチへのマージによって行います。早めに出したほうがいい修正は hotfix 用に master ブランチから派生させて PR を出しますが、週次本番デプロイでは release ブランチから master ブランチへのマージをします。Git flow ではこのとき Tag を打つことになっていますが、Web アプリケーション開発において Tag を打つメリットがなさそうなので打っていません。

最後に、修正の backport です。このままでは、図の bugfix-xxx や hotfix-xxx が develop に反映されていないため、本番やリリーステスト環境で直されている問題が、開発用環境だと発生するようになってしまいます。そのため、master から develop への PR を出し、backport を行っています。

Quipper ではこのように、Git flow を多少簡便化したような Git 戦略によって開発を行っています。

思わぬ落とし穴

概ねこのフローで問題なく回せていたのですが、先日、リリーステスト環境のコードがリリース予定のものになっていないことがありました。これについて説明します。
Quipper では monorepo に移行したのですが、非常に多くのサービスがあり、毎回すべてのサービスをビルド、デプロイするのは時間がかかります。そこで、k8s の deployment に前回リリースした Git のコミットハッシュ値をもたせ、その値と今回の内容の差分に当該サービスに関係ある変更が含まれているかを検出し、必要がないときにはデプロイをスキップしています。この差分検出の仕組みにバグがあり、前回のリビジョンが参照不能な際には差分がないものとして扱われてしまい、そのサービスのデプロイが行われない状態になっていました。

通常のフローでは参照不能にはならないのですが、リリーステスト環境でしか試せない操作があり、本番デプロイはしないが試したいというケースがありました。これは、一部 Quipper 外部の環境については PR 単位で用意することが困難だったためです。また、さらに偶然、リリーステスト環境に入れた後に手直しした内容が必要だったため、その変更を cherry pick して release ブランチに適用していました。これにより、その翌週リリーステスト環境の作成時に release ブランチを作り直した際、cherry pick した内容と同等の内容は develop ブランチに存在するもののコミットリビジョンが異なるものが最終デプロイリビジョンとして記録されていたため、差分の検出に失敗してデプロイがされない状態になってしまいました。

幸いにしてリリーステスト中に修正したはずの内容が入っていないことなどからこの問題が発覚し、取り急ぎデプロイスクリプトの修正を行いました。

本番には出さないがリリーステスト環境で試したいというケースは稀ではあるものの、現状の流れを踏まえると、release ブランチは develop ブランチをマージする、という流れでもいいかもしれません。

終わりに

ある程度時間をかけて全体に対して手動テストを挟むようなリリースの流れを取る場合には、コードフリーズが必要になるためこのような Git 戦略との相性がいいです。

ただ、週1デプロイしかできないのは都合が悪い点も多く*、可能なら頻度は上げたいものです。
分断されたモノリスを monorepo に寄せたことによって普通のモノリスとしてテストしやすくなっているので、アプリケーションを跨いだテストを足していって周期をもっと早めるのが今後の課題です。

*デプロイせずとも任意のタイミングでリリースする Darklaunch について Rails DM 2019 で @ujihisa が発表しています https://speakerdeck.com/ujihisa/almost-microservices

スタディサプリ's job postings
6 Likes
6 Likes

Weekly ranking

Show other rankings