
こんにちは!ぐるなびFineOrderというモバイルオーダーサービスでバックエンドの開発をしてます谷です。 担当しているプロジェクトでGitLabからGitHubへ移行することになり、せっかくなら一緒にsubmodule運用もやめてmonorepo化したいと思いまして、今回、両方一緒に対応しました。 そのときの話を紹介していけたらと思います。
GitHub移行とmonorepoは関係ない
まず最初にお伝えしたいのですが、GitHub移行とmonorepo化は技術的に関係ありません。 当然、GitLabでもmonorepoはできますし、GitHubでsubmoduleを使い続けることもできます。
ただ、GitHub移行もmonorepo化の対応も、通常はCIの書き換えが必要になるかと思います。 別々で対応すれば2度手間になります。 つまり、まとめて対応した方がお得です!
また、当たり前ですがまとめて実施するとチームメンバーに対して一度の周知で済みます。
いまGitHub移行することを考えていて、submodule運用などリポジトリ管理で課題を抱えているチームがあればmonorepo化も一緒に検討してみてはいかがでしょうか。
実は今日お伝えしたかったことはここだけです!
なぜGitHub移行したのか
元々は私たちのチームではGitLabでソースコードを管理していました。 GitLabからGitHubへ移行した理由としては、GitHubの方がチーム全体の開発生産性を向上できると考えたからです。 開発支援系SaaSでGitHub連携を前提にしていることがあり、GitHubの方が外部サービスとの連携がスムーズであるということと、GitHub Actionsのエコシステムが充実していて生産性向上の施策・管理がしやすいと考えたからです。
なぜmonorepoにしたのか
移行前は、共通コードを管理するリポジトリを20を超えるリポジトリにsubmoduleとして取り込んでいました。 この運用が結構辛くて、共通コードを管理するリポジトリで更新が走るたびに 必要に応じて各リポジトリでsubmoduleの更新のPR(Pull Request)を作成する必要がありました。 20リポジトリ分のPRを作るのに0.5~1時間はかかっていたと思います。
submoduleの管理だけでなく、例えば言語のバージョンアップする際はすべてのリポジトリでコード変更してコミットしてPRを作ってという作業もかなり手間です。 リリースも複数のリポジトリでPR作ってマージしてという作業が発生して、心理的にも億劫に感じる作業になっていました。
リポジトリ数がまだ少なかった頃は特にストレスを感じていなかったのですが、
20を超えて、すべてのリポジトリに対して同じような修正をひたすらする作業は辛いです。
なんとか、この同じような修正のPRをたくさん作る作業を辞めたい。
その思いが強かったことが、monorepoにしようと決めた1番の理由です。
ちなみにmonorepoにするデメリットも検討しました。
- ビルド時間が長くなりCI/CDが重くなる
- リポジトリが肥大化して開発者体験が悪くなる
などです。ただ、現状の20程度のリポジトリの数では問題ないだろうと判断しました。そして実際に現状デメリットを特に感じてません。
もう少し大規模な組織になりリポジトリ数が増えていけば、今とは別の課題が起きてくるかもしれません。
monorepo化前後のリポジトリ・ディレクトリ構成
実際とは差異はありますが、イメージとしては左図から右図のような変更をいたしました。元々は、左図のようにリポジトリが乱立していて、各リポジトリでcommonリポジトリをsubmodule設定していたところを、右図のように、1つのリポジトリの中に以前リポジトリだったディレクトリをすべて配置するようにして、commonリポジトリをそれぞれのディレクトリから参照するようにしました。
この構成に変更したことによって、commonリポジトリの変更時にsubmodule更新は不要であり、commonの修正とPRだけで良くなり、言語のバージョンアップも1つのPRで済みます。
これで何の生産性もないPRをひたすら無心で作るだけの作業を無くすことができます!

移行作業について
今回の移行設定作業のコーディングの大部分はAIを活用して効率化しました。 Issueラベル管理、Pull Request作成時のビルド対象判定・ビルド実行、GitHub ActionsでCI/CDパイプライン構築などについては、AIを用いて実装すれば効率的に行える認識です。
個人的に一番時間がかかったのは、
既存のGitLabの各リポジトリのコミットをGitHubの1つのmonorepo化したリポジトリに移行する作業
です。大量のコンフリクトが発生し、解消作業が難航しました。 コンフリクト解消はまだ人間が判断して対応した方が早いと個人的には思ってます。
コミットの過去履歴について
コミットを過去履歴すべて移行するかどうかについては、 個人的には、そもそも過去のコミット履歴をそこまで見ることもない、必要ないと感じていれば、
- Initial Commitにすべてまとめる
- 特定日以降のコミットの履歴のみを残す
など割り切って決めた方がいいと私は考えてます。
ただしこの場合にはいくつか個人的に感じた注意点があります。
- 過去のリポジトリは削除せずにアーカイブ化しておいて、過去コミットをいつでも確認できる状況にしておいた方がいい
- PR履歴なども後でたまに見に行くことが発生する可能性もあるので削除しない方がいい
- 後から入ってくるメンバーなど別リポジトリで運用されていた過去など知らない人もいるため、READMEなど過去リポジトリのリンクをどこかに記録しておいた方がいい
まとめ
- GitHub移行を今後控えている方、
- submodule運用などリポジトリ管理で課題を抱えているチーム
であれば、monorepo化も検討してみてはいかがでしょうか。
以上です。
