我在沙子中使用以下几行:
- 最终进入不同可部署项目的代码进入同一个存储库的不同文件夹中,在一个伞式项目下——SBT 称之为多项目构建(我使用 maven 而不是 SBT,但概念非常相似)。它将被构建/部署到不同的 jars。
在进行有意义的划分时,我会尝试考虑最终的可部署项。例如,如果我的系统 foosys 有foosys-frontend
和foosys-backend
可部署的,foosys-frontend
HTML 模板和foosys-backend
与数据库的对话在哪里,并且两者通过 REST API 进行通信,那么我将把它们作为单独的项目,以及一个foosys-core
用于公共代码的项目。foosys-core
不允许依赖 html 模板库(因为foosys-backend
不想要那个),也不允许依赖 ORM 库(因为foosys-frontend
不想要那个)。但我不担心将与 REST 库一起使用的代码与“核心域对象”分开,因为两者都foosys-frontend
使用 foosys-backend
REST 代码。
现在假设我添加了一个新的foosys-reports
可部署对象,它访问数据库来做一些报告。然后我可能会foosys-database
根据 来创建一个项目来保存和foosys-core
使用的共享代码。而且由于不使用 REST 库,我可能也应该从. 所以我最终得到了一个库,另外两个依赖于它的库项目(和),以及三个可部署的项目(依赖于、依赖于和依赖于两者)。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
您会注意到,这意味着对于可能使用该代码的每个可部署组件组合都有一个代码项目。进入所有三个可部署的代码进入foosys-core
. 仅包含在一个可部署项目中的代码将进入该可部署项目的项目。进入三个可部署项目中的两个的代码进入foosys-rest
or foosys-database
。如果我们想要一些代码是foosys-frontend
和foosys-reports
可部署的一部分,但不是foosys-backend
可部署,我们必须为该代码创建另一个项目。从理论上讲,这意味着随着我们添加更多可部署项目,项目数量会呈指数级增长。在实践中,我发现这并没有太大问题 - 大多数理论上可能的组合实际上没有意义,所以只要我们只在实际有代码可以放入新项目时创建新项目就可以了。如果我们最终得到几个类foosys-core
,它们实际上并没有在每个部署中使用,这不是世界末日。
在这种观点中,最好将测试理解为另一种可部署的。所以我会有一个单独的foosys-test
项目,其中包含用于测试所有三个可部署项目(取决于foosys-core
)的通用代码,也许还有一个foosys-database-test
项目(取决于foosys-test
和foosys-database
)用于测试助手代码(例如数据库集成测试设置代码)foosys-backend
和foosys-reports
。最终,我们可能会得到一个完全平行的-test
项目层次结构。
- 仅当项目具有不同的发布生命周期时,才将项目移动到单独的 git 存储库(同时,单独的整体构建)。
不同存储库中的代码必须独立进行版本控制,因此在某种意义上这是一个空洞的定义。但我认为只有在必要时才应该继续使用单独的 git 存储库(类似于这篇文章:只有当您的数据太大而无法使用更友好的东西时,您才应该使用 Hadoop)。一旦您的代码位于多个 git 存储库中,您必须手动更新它们之间的依赖关系(在开发机器上,您可以使用 -SNAPSHOT 依赖关系和 IDE 支持来工作,就好像版本仍然同步一样,但您必须手动更新它每次与 master 重新同步时,都会增加开发摩擦)。由于您正在异步发布和更新依赖项,因此您必须采用并实施语义版本控制之类的东西,以便人们知道何时更新依赖项是安全的foocorp-utils
而当它不是。您必须发布变更日志,并进行早期预警 CI 构建,以及更彻底的代码审查流程。这一切都是因为反馈周期要长得多;如果你在下游项目中破坏了某些东西,你不会知道这一点,直到他们在foocorp-utils
几个月甚至几年后更新他们对 . . 因此,您需要流程来防止这种情况发生,而一切都会相应地变得不那么敏捷。
这样做的正当理由包括:
- 您的项目的完整构建花费的时间太长,这会减慢您正在处理的代码的集成速度 - 尽管先尝试加快速度。
- 部署所有可部署项目花费的时间太长——不过,再次尝试自动化并加快速度。保持一切同步有一个真正的优势,你不想放弃它,直到你绝对必须这样做。
- 不同的团队需要处理代码。如果您彼此之间没有持续的沟通,那么无论如何您都需要进程开销(语义版本控制等),因此您最好获得更快的构建时间。(要明确一点,我认为每个 git 存储库都应该有一个单独的团队来拥有并负责它,并且当团队拆分时,他们应该拆分存储库。我对发布过程和职责有进一步的想法,但是这个答案已经很长了) .
我会使用一个团队 Maven 存储库,可能是Nexus。实际上,即使在您进入多项目阶段之前,我也会推荐这个。它非常容易运行(只是一个 Java 应用程序),您可以通过它代理您的外部依赖项,这意味着您有一个可靠的依赖项 jar 源,即使您的上游依赖项之一消失,您的构建也将是可重现的。
我打算将我的团队工作方式写成一篇博文,但与此同时,我很乐意回答任何进一步的问题。