砂で次の行を使用します。
- 最終的に異なるデプロイ可能ファイルに入るコードは、傘下のプロジェクトの下の同じリポジトリ内の異なるフォルダーに配置されます。これは、SBT がマルチプロジェクト ビルドと呼ぶものです (私は SBT ではなく maven を使用しますが、概念は非常に似ています)。異なるjarにビルド/デプロイされます。
意味のある分割を行うときは、最終的に展開可能なものを考慮するようにしています。たとえば、私のシステム foosys にfoosys-frontend
とdeployables がありfoosys-backend
、 wherefoosys-frontend
が HTML テンプレートを作成foosys-backend
してデータベースと通信し、2 つが REST API を介して通信する場合、それらを個別のプロジェクトfoosys-core
と共通コードのプロジェクトとして使用します。foosys-core
HTMLテンプレートライブラリに依存することは許可されてfoosys-backend
いません(それを望んでいないため)、またはORMライブラリに依存することも許可されていません(foosys-frontend
それを望んでいないため). しかし、REST ライブラリで動作するコードを「コア ドメイン オブジェクト」から分離することについては心配していません。どちらもREST コードfoosys-frontend
を 使用しているためです。foosys-backend
foosys-reports
ここで、データベースにアクセスしてレポートを作成する新しいデプロイ可能オブジェクトを追加するとします。次に、 と の両方で使用される共有コードを保持するためfoosys-database
に、 に応じておそらくプロジェクトを作成します。また、REST ライブラリを使用していないため、おそらくからも分割する必要があります。したがって、ライブラリ、それに依存するさらに 2 つのライブラリ プロジェクト (および)、および 3 つのデプロイ可能なプロジェクト (に依存する、 に依存する、および両方に依存する ) ができあがります。foosys-core
foosys-backend
foosys-reports
foosys-reports
foosys-rest
foosys-core
foosys-core
foosys-database
foosys-rest
foosys-reports
foosys-database
foosys-frontend
foosys-rest
foosys-backend
これは、そのコードが使用される可能性のある配置可能なもののすべての組み合わせに対して 1 つのコード プロジェクトがあることを意味することに気付くでしょう。3 つのデプロイ可能オブジェクトすべてに含まれるコードは、foosys-core
. 1 つのデプロイ可能なものだけに含まれるコードは、そのデプロイ可能なプロジェクトに含まれます。3 つのデプロイ可能オブジェクトのうちの 2 つに含まれるコードは、foosys-rest
またはに含まれfoosys-database
ます。foosys-frontend
およびfoosys-reports
デプロイ可能なものの一部であるが、の一部ではないコードが必要な場合foosys-backend
そのコード用に別のプロジェクトを作成する必要があります。理論的には、これは、デプロイ可能なものを追加すると、プロジェクト数が指数関数的に増加することを意味します。実際には、それほど問題ではないことがわかりました。理論的に可能な組み合わせのほとんどは実際には意味をなさないため、実際にコードを配置するときにのみ新しいプロジェクトを作成する限り、問題ありません。foosys-core
そして、すべてのデプロイ可能オブジェクトで実際には使用されていないいくつかのクラスになってしまったとしても、それは世界の終わりではありません。
テストは、別の種類の展開可能なものとして、このビューで最もよく理解されています。したがって、foosys-test
3 つのデプロイ可能なプロジェクトすべて ( に依存) のテストに使用される共通コードを含む別のプロジェクトを作成しfoosys-core
、おそらく(およびfoosys-database-test
に依存) テスト ヘルパー コード (データベース統合テスト セットアップ コードなど) に共通のプロジェクトを作成します。と。最終的には、プロジェクトの完全な並列階層になる可能性があります。foosys-test
foosys-database
foosys-backend
foosys-reports
-test
- プロジェクトのリリース ライフサイクルが異なる場合にのみ、プロジェクトを別々の git リポジトリに移動します (同時に、ビルド全体を別々にします) 。
異なるリポジトリのコードは必然的に個別にバージョン管理されるため、ある意味ではこれは空虚な定義です。しかし、必要な場合にのみ、個別の git リポジトリに進むべきだと思います (この投稿との類推): データが大きすぎて使いやすいものを使用できない場合にのみ、Hadoop を使用する必要があります)。コードが複数の git リポジトリにある場合は、それらの間の依存関係を手動で更新する必要があります (開発マシンでは、-SNAPSHOT 依存関係と IDE サポートを使用して、バージョンがまだ同期しているかのように機能しますが、これを手動で更新する必要がありますマスターと再同期するたびに、開発に摩擦が追加されます)。リリースを行って依存関係を非同期的に更新しているため、セマンティック バージョニングのようなものを採用して実施する必要があります。これにより、依存関係をいつ安全に更新できるかを人々が知ることができます。foocorp-utils
そうでないとき。変更ログを公開し、早期警告 CI ビルドと、より徹底したコード レビュー プロセスを実施する必要があります。これはすべて、フィードバック サイクルがはるかに長いためです。下流のプロジェクトで何かを壊した場合、彼らが依存関係を更新するまでfoocorp-utils
、何ヶ月も、あるいは何年も後にそれについて知ることはありません (はい、何年も - 私はこれを目撃しましたが、メガコーポではなく 80 人のスタートアップで) . したがって、それを防ぐためのプロセスが必要であり、それに応じてすべての機敏性が低下します。
これを行う正当な理由は次のとおりです。
- プロジェクトの完全なビルドに時間がかかりすぎて、作業中のコードの統合が遅くなりますが、最初に高速化を試みてください。
- すべてのデプロイ可能なものをデプロイするのに時間がかかりすぎています - 繰り返しますが、これを自動化してスピードアップしてみてください。すべてを同期しておくことには、本当に利点があります。絶対に必要になるまで、それをあきらめたくありません。
- 別のチームがコードに取り組む必要があります。お互いに常に通信していない場合は、とにかくプロセスのオーバーヘッド (セマンティック バージョニングなど) が必要になるため、ビルド時間を短縮することもできます。(明確にするために、すべての git リポジトリには、それを所有して責任を負う単一のチームが必要であり、チームが分割された場合はリポジトリを分割する必要があると思います。リリースプロセスと責任についてさらに考えていますが、この回答はすでにかなり長いです) .
チームの Maven リポジトリ、おそらくNexusを使用します。実際、マルチプロジェクトの段階に入る前であっても、これをお勧めします。実行するのは非常に簡単で (Java アプリのみ)、それを介して外部依存関係をプロキシすることができます。つまり、依存関係 jar の信頼できるソースがあり、上流の依存関係の 1 つが消えてもビルドを再現できます。
チームワークの方法をブログ投稿として書くつもりですが、それまでの間、追加の質問に喜んでお答えします.