Maven 与 Jenkins - 更新依赖项的父 pom 版本

Posted

技术标签:

【中文标题】Maven 与 Jenkins - 更新依赖项的父 pom 版本【英文标题】:Maven with Jenkins - Update parent pom version of dependency 【发布时间】:2012-03-12 15:42:36 【问题描述】:

我有一个与此类似的 pom 文件

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>myApp</groupId>
  <artifactId>myAppId</artifactId>
  <packaging>war</packaging>
  <version>1.2-SNAPSHOT</version>
  <name>Maven Test Webapp</name>
  <url>http://maven.apache.org</url>

  <dependency>
      <groupId>com.manydesigns</groupId>
      <artifactId>portofino-war</artifactId>
      <version>3.1.10</version>
      <type>war</type>
      <scope>compile</scope>
  </dependency>

  </dependencies>
  <build>
    <finalName>TestName</finalName>
  </build>
</project>

如果我在上述 pom 文件上运行“mvn release:prepare”,则工件的版本会发生变化。即它变成了

<version>1.2</version>

现在假设我已经更新了 portofino-war 应用程序,它是这个 pom 文件的依赖项。 portofino-war 现在是 3.1.11 版本,但父 pom 文件指向 3.1.10 版本,如上所示。

如果构建了新版本的 portofino-war,我有什么方法可以更新父 pom(通过 Maven 或 Jenkins)文件?

谢谢

编辑

应用程序使用 Maven 覆盖 - http://maven.apache.org/plugins/maven-war-plugin/overlays.html 从其他战争文件构建一个战争文件。这意味着如果构建了任何依赖模块,则必须构建父模块才能生成最终的 war 文件。

问题是,目前如果我构建任何模块,我必须手动更新父 pom 文件中的版本以使用正确的模块版本进行构建。

编辑 2

感谢您的帮助拉尔夫。基本上这就是我想要实现的目标:

我想要做的是创建一个 maven 项目,它将基于几个模块构建一个 war 文件。假设模块具有以下结构:

模块 1

customerModule
    |-webapp
        |-jsp
            |-customer
                |-findCustomer.jsp
                |-addNewCustomer.jsp
                |-deleteCustomer.jsp
    |-src
        |-com
            |-mycompany
                |-customer
                    |-FindCustomerAction.java
                    |-AddCustomerAction.java
                    |-DeleteCustomer.java

模块2

productModule
    |-webapp
        |-jsp
            |-product
                |-productCustomer.jsp
                |-addNewProduct.jsp
                |-deleteProduct.jsp
    |-src
        |-com
            |-mycompany
                |-product               
                    |-FindProductAction.java
                    |-AddProductAction.java
                    |-DeleteProduct.java 

模块3

commonModule
    |-webapp
        |-css
            |-style.css
        |-jsp
            |-templates
                |-coreTemplate.jsp
    |-src
        com
            |-mycomany
                |-common
                    |-Logger.java
                    |-Access.java
    |-META-INF
        |-MANIFEST.MF
        |-context.xml
    |-WEB-INF
        |-lib
            |-oraclejdbc.lib
            |-log4j.lib
            |-common.lib
        |-struts-config.xml
        |-tiles-def.xml
        |-web.xml

显示的每个模块都将由不同的团队开发。每个团队都会生成一个 war 文件并将其安装在本地 maven 存储库中。例如,存储库可能如下所示

com
 |-customerModule
    |-customerModule.v2.1.war
    |-customerModule.v3.0.war
 |-productModule
    |-productModule.v3.0.war
    |-productModule.v3.1.war    
 |-commonModule
    |-commonModule.v0.5.war 
    |-commonModule.v3.0.war 

现在构建管理器使用上述战争文件来构建最终可部署的战争文件。本来打算用maven overlays来合并三个war文件。我确实测试了war文件与覆盖的合并,发现以下配置有效。即使用依赖项:

注意:这些依赖在 commonModule pom 文件中

<dependency>
  <groupId>com</groupId>
  <artifactId>customerModule</artifactId>
  <version>3.0</version>
  <type>war</type>
  <scope>compile</scope>
</dependency>
<dependency>
  <groupId>com</groupId>
  <artifactId>productModule</artifactId>
  <version>3.1</version>
  <type>war</type>
  <scope>compile</scope>
</dependency>

如果我随后构建 commonModule 模块,我最终会得到一个包含 Module1、Module2 和 Module3 的所有内容的 war 文件。最后是这样的:

MyApp.war
    |-webapp
        |-css
            |-style.css
        |-jsp
            |-customer
                |-findCustomer.jsp
                |-addNewCustomer.jsp
                |-deleteCustomer.jsp
            |-product
                |-productCustomer.jsp
                |-addNewProduct.jsp
                |-deleteProduct.jsp     
            |-templates
                |-coreTemplate.jsp
    |-META-INF
        |-MANIFEST.MF
        |-context.xml
    |-WEB-INF
        |-lib
            |-oraclejdbc.lib
            |-log4j.lib
            |-common.lib
            |-customerModule.jar
            |-productModule.jar
        |-classes
            |-com
                |-mycomany
                    |-common
                        |-Logger.class
                        |-Access.class
        |-struts-config.xml
        |-tiles-def.xml
        |-web.xml   

上述方法有效,但需要一些手动干预才能完全发布。这是一个修改模块会发生什么的示例

Team 1 更新模块 1

- Team 1 makes changes to module 1 and check in changes into CVS    
- Team 1 installs module 1 onto the maven repository by issuing mvn:prepare and mvn:perform on module 1. This adds a new version of customerModule.war on to the local repository
- Team 1 updates the dependency version for module 1 in the pom file used to merge the war files (i.e. commonModule)
- Team 1 builds the deployable war file by building the commonModule. 

上面没有像你建议的那样使用多模块项目,所以我试图了解版本控制如何与多模块项目一起工作。例如,假设多模块项目看起来像这样

MyApp
 |- productModule
    |-pom.xml
 |- customerModule
    |-pom.xml
 |- commonModule
    |-pom.xml
 |-pom.xml
在每个子模块中添加版本号与在父模块中添加版本号有什么区别? 您说子模块将使用父版本。假设父版本当前是 3.4 版,它怎么知道它应该使用 productModule.war 的 3.1 版? 最后,如果团队 1 对其中一个子模块进行了更改,在构建多模块项目之前,他们是否仍需要先构建它并将其作为单独的产品部署到 maven 存储库中,或者可以这样吗?一步完成? 如果我想发布一个不一定意味着使用特定模块的最新版本的补丁版本,这将如何工作?

谢谢

【问题讨论】:

不明白释放myApp和修改依赖有什么关系。 【参考方案1】:

对于问题“编辑”部分中描述的场景,我建议将所有战争文件放在一个:多模块项目中。

【讨论】:

单个多模块项目可以用来合并war文件吗?我认为这只能通过使用 Maven Overlays 来实现。 单个模块项目的不同模块,可以像一个普通的maven项目。 不同的模块方法如何帮助版本控制?你能提供一个例子吗?谢谢 这将使版本控制方法完全过时。 那么如果子pom中没有指定版本,父pom会使用哪个版本呢?它总是使用最新版本吗?【参考方案2】:

您可能想要使用依赖范围而不是更新 pom:http://docs.codehaus.org/display/MAVEN/Dependency+Mediation+and+Conflict+Resolution#DependencyMediationandConflictResolution-DependencyVersionRanges

【讨论】:

以上是关于Maven 与 Jenkins - 更新依赖项的父 pom 版本的主要内容,如果未能解决你的问题,请参考以下文章

Maven 依赖项 - 版本与更新

在 POM 中更新依赖版本

mvn 命令用于更新依赖项中的版本和一个使用该依赖项的项目

在依赖升级的情况下自动构建 Maven 项目

Maven 子项目 - 不可解析的父 POM

maven更新版本具体依赖