Question

I'm trying to release individual modules of a multi-module project, contained within a single git repository.

The folder structure looks something like this:

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

The parent pom is simply used as a way of building all subcomponents in a way that makes sense by the use of the <modules> tag. In essence, building api, then database, then core.

The project started out hosted in SVN and by simply pointing to different paths in the repository in the maven scm tag it was easy to get the maven release commands to play nice. This doesn't seem to be the case with Git.

When running mvn release:prepare it performs changes on the api pom as desired, but when performing mvn release:perform it attempts to build the parent pom, and fails to build the database package due to it's inability to resolve the api-snapshot dependency that is listed in database/pom.xml.

How should I configure my scm tags to be able to release a specific module within the Git repository? Is this even possible?

Edit: adding pom samples

Here's an example setup of how the pom files look:

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>

The database pom looks very much like api, but has a dependency to api. The same goes for core, which depends on database (and through it, on api).

The api and database artifacts themselves are important on their own though, as api defines the client API and database the backend API, both of which are used for integrating with the application. From this stems the original thought of releasing them separately -- the parent pom is merely an afterthought to allow simpler building of the entire stack.

Was it helpful?

Solution

The usual way to release a multi-module build is to do it from the root position which means also to release all it's sub modules with it. Not releasing a single module separately. If you try to do so you will loose the relationship of the versions to each other.

If you really want to release the modules separately just make separate maven projects out of it and give them each a git repository.

The tree you mentioned looks really like a multi module build which should be released in a single step from the root.

Based on what you have updated i can recommend that you should go with a real multi-module build with a structure like the following:

root
 +-- pom.xml (1.0-SNAPSHOT)
 !
 +-- api 
 !     +-- pom.xml (1.0-SNAPSHOT)
 +-- database
 !     +-- pom.xml (1.0-SNAPSHOT)
 +-- core
       +-- pom.xml (1.0-SNAPSHOT)

The best is to use inheritance in Maven which means to use in every module api, core, database a parent like this:

<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>

This give you the option to put everything which is common in api, core and database into the parent. For example you should put the license information only into the parent, the properties like them:

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

and furthermore you can put information about plugins you are using into the parent as well like:

  <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>
        ...

and of course you have to define the scm area only a single time in the parent and many other things as well.

Also it's possible and recommended to define dependencyManagement into the parent which gives you the chance to define the dependencies only at one point with their appropriate versions and no need to define the version in the modules.

This will result in dramatically reducing the size of the pom's in the modules.

The result will be to release from the parent via a single mvn release:prepare etc. but will produce different artifacts like hydra-api, hydra-core and hydra-database having the same version number which will make sure to have the api, core etc. in accordance with each other.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top