性質はそれぞれ異なるものの、関連のある複数のプロジェクトをどう統合するか(あるいは統合しないか)、皆さんはどうするのを好みますか?
例えば、同じサービスについて front-end、back-end(api)、serverless、batch、pipeline、…… などがあるとすると、
-
Mono-repo
サービスが同じならリポジトリは1つ! 各プロジェクトはパッケージ/フォルダ構成で管理
-> コミット管理はどうする…? CI/CD や pre-commit のような hook も複雑になりそうで…… -
Git Submodules
性質が違うなら少なくとも git の履歴は分けて管理すべき! それでもできるだけ1つにまとめて……
-> submodule sync などの学習コスト…… マージも複雑になるし…… 他の開発者はついてこられるだろうか? -
独立repo
シンプルに! 別プロジェクトならリポジトリも別に!
-> Aサービスを見るにはどのリポジトリを見ればいいですか? えーとこれと、あれと…… ほかに何があったっけ……
正解はない気もしますが、どれを/なぜ好むのか気になります!
16件のコメント
私はそれぞれ独立した repo 派です…
この機能に関連する API の履歴を見たいと思ったときに、何を見ればいいんだろう? という疑問が浮かぶので、repo 1つを1つの機能に対応させておくほうが楽なんですよね。
私はたいていの状況ではモノレポを使いますが、サブモジュールを使うケースが2つあります。
外部のパブリッシャーを雇ったとき。
パブリッシングに必要な情報以外を外部のパブリッシャーに公開したくない場合、サブモジュールを使います。
外部ソリューションをカスタマイズしなければならないとき。
特にプラグイン機能を提供するソリューションである場合、サブモジュールを使います。
その外部ソリューションをサブモジュールとして登録しておき、自分のプラグインをシンボリックリンクなどでプラグインのパス内に入れる形で作業します。自分のプラグインは自分なりに別途バージョン管理しつつ、外部ソリューションは彼らのバージョン管理をそのまま維持できるという利点があります。
submodule の使用経験は、みなさんあまり良くないようですね……改善できるツールがあるといいですね
マージコミットだけでやっていく自信があるならモノレポ、
頻繁にリベースするならマルチリポ、
サブモジュール? それならOSが提供するディレクトリリンクを使えばいいです……
以前はそれぞれ独立したrepoを使っていましたが、最近はサブモジュールを使う方法に完全に切り替えました。
以前はgitへの理解が浅く、サブモジュールをうまく活用できていませんでしたが、今はサブモジュールを使うほうがよいと考えているためです。
ただし、サブモジュールを使うとそのサブモジュール側でコミットしたうえで親repo側にも再度コミットする必要があり、その結果2つの時点にずれが生じてrepoの一貫性が下がる問題が出てくるように思います。
https://monorepo.tools/
このサイトをまだご覧になっていなければ、一度見てみるとよいと思います。
サブモジュールは個人的な経験上、おすすめしません。
サブモジュールで別のリポジトリのコードを共有したいなら、むしろパッケージとして配布するほうがよいと思います。
私たちの会社では、プロジェクトごとのチーム人数が少なく、フロントエンドとバックエンドの言語や技術スタックも分かれているため、職種間でのクロス貢献はほとんどありませんでした。結局のところ、ほかのあらゆるITシステムと同じように、最終的には組織構成に従うものだと思いますね
おお……インターフェースを人が合わせるのか、ツールがやってくれるのかによって、相手のコードの可視性を調整するアプローチなんですね
Mono-repo の経験がないので、ひとつ気になっていることがあります。Mono-repo にする場合、複数のプロジェクトやサービスに共通するモジュール(例: デザインシステム)は、それぞれの Mono-repo に含める形になるのでしょうか? それとも、これはどうしても別の Repo として切り出して参照する形にするのでしょうか?
共通モジュールへのアクセスは、
yarn workspaceのような支援を使って、symlink 形式でアクセスしていた気がします!私は会社でも個人プロジェクトでも、フロントエンド・バックエンド・バッチなどを分けずに、1つの git で管理しています。
後方互換性を守るよりも、両方を一緒に修正したほうが楽な場合もありますしね。どちらもチーム規模が小さいので、わざわざ分けて良いことはないというか……。GitHub Actions は変更された部分だけ動くように設定しており、その程度の手間なら十分受け入れられました。何よりも、バックエンドとフロントエンドを分けることより、お互いが相互に貢献できるのが良いと思っています。(フロントの作業をしていてバックエンドに必要なものがあれば自分で追加したり、エラーも自分で直したり、など……)
うーん、やはり規模が小さいか、あるいは役割分担が厳密でないなら、モノレポを好まれるようですね! Git の履歴が混ざる? こともあまり気にされませんか?(どうせみんなが見るコードだから?)
興味深いのは、私のサイドプロジェクトでもそうだということです。今は12人ほどと一緒に作業してきましたが、各メンバーがフロントからバックエンドまでを一気通貫で担当しています。バーティカルスライスに近い感じでもありますね。
それを混在しているとはあまり考えていません。1つのPRでフロントエンドとバックエンドの両方を修正することも多いので。うちは全員がフルスタックの4人という方針なので、バックエンド/フロントエンドを問わずお互いにレビューもしますし、変更点も把握しておく必要があります。
モジュールがそれほど大きくないならモノレポ
モジュールが大きいならサブモジュール
あるいは、オープンソースとして公開するときにサブモジュール側だけにコントリビュートできるようにして、メインリポジトリは独自に管理したいなら、
サブモジュールに分けることになると思います。
ただ、サブモジュールを挟むとオープンソース化する際に、ほかのユーザーがコントリビュートのためにテストやビルド関連のドキュメントを書くのが少し複雑になる気はします。
なので個人的には、両者へのコントリビューションの性質が違うのでなければモノレポにするか、
別々の GitHub にして、それぞれをパッケージとして配布したり Docker イメージにしたりする形で管理するのがよいと思います。
オープンソース関連については考えていませんでしたが、ご意見ありがとうございます!