Question:如何处理 Maven 多项目构建的功能分支?
Jenkins 构建和部署这些分支,以将开发人员的构建开销降至最低,但开发和功能分支无法构建相同的 Maven 版本,否则我们将面临工件和源代码之间不匹配的风险。
我们有一个脚本来更改子 pom 中的父版本和根 pom 中的版本。虽然这在 Maven 空间中隔离了分支,但在合并时会导致额外的工作。
我认为 Nexus Pro 登台功能可能会帮助我们避免这种要求,并使每个功能分支使用一个特定的存储库,我们在分支删除/合并后可以轻松删除该存储库。
Again: 如何处理多分支和maven的问题?
下面的方法怎么样:
- Use the buildnumber-maven-plugin http://www.mojohaus.org/buildnumber-maven-plugin/从 git 获取信息并填充特定的 Maven 属性(我们特别感兴趣的是
scmBranch
属性(即当前的git分支)
- Use the build-helper-maven-plugin http://www.mojohaus.org/build-helper-maven-plugin/检查我们是否处于功能分支中(通过regex http://www.mojohaus.org/build-helper-maven-plugin/regex-property-mojo.html,不包括知名分支,如
master
, develop
等)并填充(或不填充)新的 Maven 属性,例如branch.classifier
- Use the maven-jar-plugin https://maven.apache.org/plugins/maven-jar-plugin/根据上一步设置的内容,在生成的工件上设置分类器,即使用新的
branch.classifier
属性:如果为空,则不会应用任何分类器(默认行为,应用于develop
例如,分支);否则将动态应用以当前分支命名的分类器。
这是一个最小的例子:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>create</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.10</version>
<executions>
<execution>
<id>regex-property</id>
<goals>
<goal>regex-property</goal>
</goals>
<configuration>
<name>branch.classifier</name>
<value>${scmBranch}</value>
<regex>(^develop)|(^master)|(^release.*)</regex>
<replacement></replacement>
<failIfNoMatch>false</failIfNoMatch>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<classifier>${branch.classifier}</classifier>
</configuration>
</plugin>
</plugins>
</build>
下面的代码片段基本上填充了scmBranch
动态属性,然后设置branch.classifier
仅当不同于其值时develop
, master
or release*
,然后将其设置为分类器。
这种方法的主要优点:
- 不会应用 pom 更改,因此根本不存在合并问题
- Nexus 在同一版本的项目上工作但在不同的分支上不会发生冲突:分类工件将有不同的Maven坐标 https://maven.apache.org/pom.html#Maven_Coordinates,即GAV(groupId,artifactId,version)变成唯一的GAVC(+classifier)
- That's actually a meaningful usage of the classifier https://maven.apache.org/pom.html#Dependencies attribute of an artifact:
分类器允许区分从相同 POM 构建但内容不同的工件。
- 生成的工件将根据其源分支在 Nexus 中动态不同,因此具有隐式可追溯性:无需开发人员干预(不易出错,隐式约定),无需 CI 作业干预(更容易维护),完全透明
- 使用分类器,将更容易使用分支生成的工件作为 Maven 依赖项(例如,在库项目的情况下):我想使用当前正在分支 xxx 上开发的依赖项
Examples
因此,您将生成以下工件:
- 工作时
develop
: e.g. project-1.0.0-SNAPSHOT.jar
(空分类器,因此不应用,由正则表达式处理)
- 工作时
featureA
: e.g. project-1.0.0-SNAPSHOT-featureA.jar
- 工作时
hotfix-JIRA123
: e.g. project-1.0.0-hotfix-JIRA123.jar
- 工作时
release-sprint42
:这取决于你,我添加这种情况是为了不应用分支名称,只是因为在这些情况下我更喜欢明确设置一个特殊的分类器,RC<number>
,对于候选版本,但这是惯例/品味/习惯的问题,您也可以在此分支上应用相同的方法,只要不会在 Nexus 上产生冲突。另请注意:当使用 JIRA/Stash/Git 集成时,发布分支名称通常类似于release/v0.1.0
,其中/
字符可能会在某些操作系统中引起问题(如果确实需要,仍然可以通过进一步的正则表达式替换来修复)。
- 工作时
master
: 嘿,没有人应该继续工作master
:) 这个案例只是作为双重检查,但这实际上不是必需的
关于此方法的警告:
- 正如下面通过注释讨论所解释的,如果相关的 Maven 项目已经使用了分类器,甚至更多地通过模块间依赖关系(例如,对来自另一个模块的测试范围类的依赖),那么应该仔细测试这种方法,因为它可能会一些缺点
- 该书的出版
<artifactId>.pom
包含分支分类器的文件可能会与主线构建发生冲突(即覆盖它)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)