在单个Git仓库中托管的多模块Maven项目的发布

10

我正在尝试发布单个模块的多模块项目,这些模块都包含在一个git仓库中。

文件夹结构大致如下:

  |- api/pom.xml
  |- database/pom.xml
  |- core/pom.xml
  pom.xml

父POM只是通过使用<modules>标记以一种合理的方式构建所有子组件的方法。本质上,先构建api,然后构建database,最后构建core。
该项目最初托管在SVN中,通过在maven scm标记中简单地指向存储库中的不同路径,很容易使maven release命令正常工作。但Git似乎不是这种情况。
运行mvn release:prepare时,它按预期对api pom进行更改,但在执行mvn release:perform时,它尝试构建父pom,并由于无法解析database/pom.xml中列出的api-snapshot依赖项而无法构建database包。
我应该如何配置我的scm标记才能发布Git存储库中的特定模块?这可能吗?
编辑:添加pom示例
以下是pom文件的示例设置: parent pom.xml
<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/xsd/maven-4.0.0.xsd">

  <modelVersion>4.0.0</modelVersion>
  <groupId>com.findwise.hydra</groupId>
  <artifactId>hydra-parent</artifactId>
  <version>0.2.0</version>
  <packaging>pom</packaging>

  <modules>
    <module>api</module>
    <module>database</module>
    <module>core</module>
  </modules>
</project>

api/pom.xml

<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/xsd/maven-4.0.0.xsd">

  <modelVersion>4.0.0</modelVersion>
  <groupId>com.findwise.hydra</groupId>
  <artifactId>hydra-api</artifactId>
  <packaging>jar</packaging>
  <version>0.2.0</version>
  <name>${project.artifactId}</name>
  <description>Hydra API</description>

  <licenses>
    ...
  </licenses>

  <scm>
    ...
  </scm>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    ...
  </dependencies>

  <build>
    <finalName>${project.name}</finalName>
    <plugins>
      ...
    </plugins>
  </build>
</project>

数据库(database)的pom文件看起来与API很相似,但是它依赖于API。同样的,核心(core)也依赖于数据库(database)(以及依赖于API)。
然而,API和数据库本身对于集成应用程序非常重要,因为API定义了客户端API,而数据库定义了后端API。这就是最初将它们分开发布的想法 - 父级POM只是为了更简单地构建整个堆栈而做出的。

你是否在API、数据库或核心模块中使用父标签来引用来自父POM的东西? - khmarbaise
1个回答

10
通常发布多模块构建的方法是从根位置进行,这意味着也要一起发布其所有子模块。不单独发布单个模块。如果你试图这样做,将会失去它们之间版本关系。
如果您真的想分别发布模块,请将它们分别制作成Maven项目,并为每个项目提供一个Git存储库。
您提到的树看起来确实像一个多模块构建,应该从根部一步完成发布。
基于您更新的内容,我可以建议您采用以下结构的真正的多模块构建:
root
 +-- pom.xml (1.0-SNAPSHOT)
 !
 +-- api 
 !     +-- pom.xml (1.0-SNAPSHOT)
 +-- database
 !     +-- pom.xml (1.0-SNAPSHOT)
 +-- core
       +-- pom.xml (1.0-SNAPSHOT)

最好在Maven中使用继承,这意味着在每个模块(api、core、database)中使用像这样的父级:
<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/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <parent>
    <groupId>com.findwise.hydra</groupId>
    <artifactId>hydra-parent</artifactId>
    <version>0.2.0-SNAPSHOT</version>
  </parent>

  <artifactId>hydra-api</artifactId>

  <description>Hydra API</description>

这使您可以将api、核心和数据库中的所有共同内容放入父级中。例如,您应该只将许可证信息放入父级中,像这样的属性:
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

此外,您还可以将有关所使用插件的信息放入父级中,例如:

about plugins


  <build>
    <pluginManagement>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>2.3.2</version>
          <configuration>
            <source>1.6</source>
            <target>1.6</target>
          </configuration>
        </plugin>
        ...

当然,你需要在父级中定义scm区域,并且还有许多其他事情需要定义。同时,建议将dependencyManagement定义在父级中,这样可以在一个点上定义依赖项及其适当的版本,而无需在模块中定义版本,从而大大减少模块中pom文件的大小。结果是通过单个mvn release:prepare等从父级发布,但会产生不同的构件,如hydra-apihydra-corehydra-database,它们具有相同的版本号,这将确保apicore等彼此相符。

我在模块pom.xml中没有使用父标签。根目录中的“parent” pom或多或少只存在于允许正确顺序建立核心和所有其它组件之目的。我需要在“子模块”POM中使用父标签吗?并且单步发布父级是否会发布所有模块工件,还是仅发布某种超级工件? - Joel Westberg
1
如果您按正确顺序构建它,例如从核心到API等,那么您将具有依赖项。在这种情况下,我建议从单一点进行真正的多模块构建和发布,就像我所描述的那样。您能否发布您的父POM以及可能的一个模块?这会使讨论更简单。 - khmarbaise
关于pom文件,我添加了更多的信息。感谢您提供的任何建议! :) - Joel Westberg
非常好的建议。谢谢!这次我最终选择手动发布,但是我会按照您的建议重新排列pom文件——看起来这是正确和最好的方法。 - Joel Westberg

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