如何使用Maven持续构建和部署特性分支?

38

我的团队使用特性分支来实现新功能,并持续将快照构建部署到远程仓库供用户使用。因此,“部署”实际上只意味着“分发到远程Maven存储库”。目前,我们仅为主分支运行连续集成构建,而不是特性分支,原因如下:我们使用Maven构建项目并在JAR旁边分发JavaDoc和源代码。

我的计划是为每个特性分支的构建添加一个分类器,并期望该分类器在创建和部署构件时被使用,如下所示:

  • 分支:主
  • 分类器:无
  • 构件:foo-${version}.jar、foo-${version}-sources.jarfoo-${version}-javadoc.jar

  • 分支:特性X

  • 分类器:myfeature
  • 构件:foo-${version}-feature.jarfoo-${version}-sources-feature.jarfoo-${version}-javadoc-feature.jar

我并不关心构件的确切命名,我只需要针对特性分支分别生成主要的、源代码和JavaDoc构件。事实证明,JavaDoc插件和源代码插件都没有考虑已配置的分类器,因此实际上覆盖了为主构建创建的构件。

我并不想改变artifactId,尽管这可能会解决问题。您如何处理Maven的特性分支和持续集成?


1
不应该使用分类器来反映分支之间的差异,因为这会对其他插件产生不良影响。 分类器应该是源代码、javadoc等等... 针对您的需求,您应该更改artifactId或版本。 - Farid
1
@eckes - 我们使用Bamboo,它支持根据分支名称上的正则表达式自动触发构建作业并针对不同分支进行构建。一旦检测到与该表达式匹配的分支,它就会克隆一个构建作业(如果通常被指示这样做)。 - Oliver Drotbohm
1
@Farid - 是的,目前似乎这是唯一的解决方案。即使我希望有更好的解决方案,你的评论也可以成为一个很好的答案 :)。 - Oliver Drotbohm
2
这个问题值得更多的浏览和点赞。 - axiopisty
我们在开发生命周期中遇到了类似的问题,正在努力解决。最终你找到了一个可行的解决方案吗?你是否将限定词添加到版本号中?你是否找到了最适合的特定版本号格式? - Eric B.
显示剩余2条评论
4个回答

10

我建议将分支限定符加入版本组件中,因为它与该部分更相关。这还允许您在主分支旁边使用这些版本的快照依赖项。


9
虽然这看起来是一个不错的方法,但在使用版本号范围时会出现问题(例如用于持续集成)。请参阅我的答案。 - Eduard Wirch
不仅版本号范围,将字母放入版本中并且还加上快照,这并不意味着这是一个快照,正如我在我的评论中所指出的那样,feature-SNAPSHOT不再是快照,限定词现在是特性名称和SNAPSHOT。 - Brett Ryan

9
我建议使用适当的版本来代表分支以及版本,例如:
- 主分支使用1.0.0-SNAPSHOT - 特性分支F1使用1.0.0-F1-SNAPSHOT
这样做还可以指示特性分支是从哪个1.0.0版本开始创建的。

1
1.0.0等同于<主版本号[>.<次版本号[>.<增量版本号]]*,而-F1等同于*[>-<构建编号|限定符]>*。-SNAPSHOT是Maven的一部分。此外,这有什么问题吗?根本没有。 - khmarbaise
5
你想知道如何指示Mercurial或Maven在合并回主分支时不包含POM版本号。我的意思是,你不想每次合并时都手动解决这个问题,对吗? - Asgard
1
我一直在使用这种方法,使用Maven版本插件。mvn versions:set -DallowSnapshots=true -DnewVersion=0.1-$branch-SNAPSHOT -Pall - digao_mb
@OliverGierke,我在想你是否可以与公众分享那个脚本?我们也遇到了同样的问题。合并包含不同组件版本号的pom文件的分支变得非常具有挑战性。例如,我的主分支可能有1.4,而我的发布分支可能有1.1,但当我们尝试将发布分支与主分支合并时,这成为了一个难题。 - endless
@endless — 脚本可以在此处找到(https://github.com/spring-projects/spring-data-build/blob/1c23418cf38970b86cd1fbb8d806a0defa24f4d6/etc/scripts/new-issue-branch)。它为设置创建了一个专用提交,我们在合并分支时将其删除。这样,版本定制永远不会进入主分支。 - Oliver Drotbohm
显示剩余5条评论

8

像其他人建议的那样,使用版本号来存储分支名称很快就能解决问题,但如果您使用版本范围,则会导致问题。版本号并不是为了这样使用的。我们在持续集成过程中使用它们,使集成测试依赖于被测试的工件:

[1.8-SNAPSHOT,1.9-SNAPSHOT)

版本号中的限定符部分表示相同代码基础的不同增量阶段:
1.8-alpha1-SNAPSHOT
1.8-alpha1-SNAPSHOT
1.8-beta1-SNAPSHOT

这就是为什么上述版本范围会捕获上述情况,Maven将按照此顺序排序。
1.8-SNAPSHOT
1.8-alpha1-SNAPSHOT
1.8-alpha1-SNAPSHOT
1.8-beta1-SNAPSHOT

任何版本号带有功能分支名称的构件(例如1.8-featureA-SNAPSHOT)将优先于没有限定符的快照版本。但是,功能分支是一个“不同”的代码库,而不是相同代码库的新版本。对于我们的集成测试场景,这导致了无用的测试失败。功能分支尚未准备好通过集成测试进行测试。

现在我们遵循这个规则:如果您必须进行更改,为什么不更改构件ID呢?对于功能分支,我们更改构件ID即可解决此问题。


虽然特性分支是一个“不同”的代码库,但它仍然是主构建的同一项目。看起来应该有一种解决方案,而不是修改工件ID。但我没有一个=(也许Maven版本要么太功能丰富(支持范围),要么太不灵活(只支持3个点版本a.b.c作为数字,并默认为a.b.c.d的字符串)。 - Stan Kurdziel
顺便说一句:我在功能分支上使用完全不同的版本。主分支上是 1234……而在功能分支上是 featureA-001featureA-002……也考虑过使用 featureA-SNAPSHOT,但似乎更为复杂。 - Stan Kurdziel
1
这是正确的 - 然而,在Maven中使用版本范围本身就存在各种问题(例如需要遵循Maven的版本号格式),因此我认为它们在实践中并没有被广泛使用。如果您从未使用过版本范围,则不会遇到此问题。 - sleske
我会避免使用版本范围。如果您使用可变版本快照,请仅在需要不同依赖项时更改它们。 - eckes
这绝对是正确的答案。正如我在上面的评论中所指出的,Maven提供的版本控制方案根本不允许在版本中包含功能。 - Brett Ryan
显示剩余2条评论

5

如果不想改变构建工具 Maven 中的坐标,您可以使用maven-branch-extension,为每个特性分支有效地创建一个单独的 SNAPSHOT 命名空间。该项目页面上引用了以下内容:

与其在特性分支上更改版本号,我们更改仓库。每个特性都被部署到一个子目录中,基于它们的分支名称,在一个专门为特性分支设计的远程仓库中。不存在覆盖构件的风险。版本号不会改变。Git 的分支和合并保持简单(就像它应该的那样!)。

该扩展程序获取当前 Git 分支,并在仓库的 URL 中解析一个属性,以便正确存储和检索构件。它还管理缓存和从本地仓库获取构件,以便在从特性分支工作时,如果存在,则取自特性分支仓库中的构件。

这样做的好处是,SNAPSHOT 依赖的外部用户完全与主题分支上的内部工作隔离开来。


我认为这是最好的方法,比起玩弄构件的GAV更加简洁。此外,“特性”仓库可以针对特性分支生命周期进行优化(例如在特性分支被删除时自动清理等)。 - sola

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接