这听起来很像我的构建系统。
我使用 gradle 和 2 个单独的 nexus 存储库(“发布”存储库、1 个暂存和 1 个最终存储)来执行此操作。该构建具有目标成熟度的概念,它使用它来计算版本号(使用语义版本控制),因此 RC 构建产生类似 1.0.0-rc1 的版本,最终构建产生类似 1.0.0 的版本。然后,我们以不同的方式(testng 组、黄瓜标签等)标记测试,以便测试的不同部分在不同的时间运行。构建根据目标成熟度决定依赖或发布到哪些存储库,因此可以确保仅使用足够成熟的工件。
这被配置为通过 teamcity 构建链自动运行,因此如果需要,某些核心库中的提交会通过下游构建并继续进行集成测试/部署(通过 rundeck 通过其 java api 通过一组 gradle 任务)。
Gradle 发布和解析存储库是单独配置的,因此可以不同。同样可以在 Maven 中完成。
例如,给定一个依赖图,如
corelib -> mylib -> myapp
每个事物都有一组与它们相关联的测试,这些测试被标记为 beta 或 rc。目的是生成 RC 的构建是通过 beta 测试的构建(即,如果您通过 beta,那么您已经足够成熟,可以成为 RC)并且构建是快速完成的构建(例如,仅进行单元测试)而 rc 测试(生成最终构建)可能会进行一些集成测试或更长时间运行的测试。这个定义是我们自己的,完全是任意的,你可以做任何你喜欢的区分。只有当您对产品有一定的信心水平时,我们才会应用越来越严格和/或持久的测试。
然后我们设置一个构建链,以便 rc 构建依赖于上游 rc 构建,最终构建依赖于上游最终构建和您自己的 rc 构建
IE
--> mylib final --
/ \
mylib rc -- --> myapp final
\ /
--> myapp rc -----
等等。在这个例子中,流程是
- 提交对 mylib 的更改
- mylib rc 构建运行
- mylib final 和 myapp rc 可以并行运行
- mylib 最终构建运行
- myapp rc 构建运行
- 取决于 rc 存储库,因此获取以前 mylib rc 构建的结果
- 运行 beta 测试
- myapp 最终运行
- 取决于最终存储库,因此获取先前 mylib 最终构建的结果
- 运行 rc 测试
每个点的版本号都是通过询问源代码控制来计算的
依赖,在我们自己的人工制品上,是动态的(例如 ivy 术语中的 1.0.+),major.minor 是静态设置的(在源代码控制中)并且构建留给自己产生补丁和候选编号,即 myapp 1.0 将取决于我的库 1.0.+ 。IMO 将 2 个独立的存储库作为过滤机制要简单得多,而不必深入研究 gradle/ivy 中的解析逻辑来过滤掉我们不想要的存储库。