Best practice: Versioning and releases in multiprojects

724 views Asked by At

What is the best practice for versioning and release management in the following case with multiprojects?

Project structure

  • global parent
    • parent project (Version: 1.0-SNAPSHOT)
      • child project 1 (same like parent)
      • child project 2 (same like parent)
      • child project 3 (same like parent)
      • child project 4 (same like parent)

I want to set only one time the version for the parent and all child projects, because every part of the project must have the same version.

Also what i want is, to release the project with continuum/maven.

Current "bad" solution:

Normaly a easy way should be to set the version in the parent pom and say in every child „last version from parent“ but this dont work with maven <3.1 (See here)[http://jira.codehaus.org/browse/MNG-624] Now i set in every child project the version of the parent project and for every release i must change the version in all childs and the parent.

Example:

Parent

<groupId>com.test</groupId>
<artifactId>com.test.buildDefinition</artifactId>
<version>1.0-SNAPSHOT</version>

Child

<parent>
    <groupId>com.test</groupId>
    <artifactId>com.test.buildDefinition</artifactId>
    <version>1.0-SNAPSHOT</version>
</parent>

<groupId>com.test</groupId>
<artifactId>com.test.project</artifactId>
<version>${parent.version}</version>

If i want to release my projects now with Continuum i use the following order to release it:

  1. Parent Project
  2. Child Project 1
  3. Child Project 2

But this dont work, because after changeing the version of the parent, the childs dont have anymore a SNAPSHOT version in the parent and i think there must be a better way to release a multiproject with continuum.

3

There are 3 answers

0
maba On BEST ANSWER

If you add your child modules in the <dependencyManagement/> tag I am quite sure that you will not have that problem.

Parent

<groupId>com.test</groupId>
<artifactId>com.test.buildDefinition</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>

<modules>
    <module>child1</module>
    <module>child2</module>
</modules>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.test</groupId>
            <artifactId>com.test.child1</artifactId>
            <version>${project.version}</version>
        </dependency>
        <dependency>
            <groupId>com.test</groupId>
            <artifactId>com.test.child2</artifactId>
            <version>${project.version}</version>
        </dependency>
    </dependencies>
</dependencyManagement>

Child1

<parent>
    <groupId>com.test</groupId>
    <artifactId>com.test.buildDefinition</artifactId>
    <version>1.0-SNAPSHOT</version>
</parent>

<!-- groupId and version can be skipped since it will be inherited from parent -->
<artifactId>com.test.child1</artifactId>

Child2 (depends on Child1)

<parent>
    <groupId>com.test</groupId>
    <artifactId>com.test.buildDefinition</artifactId>
    <version>1.0-SNAPSHOT</version>
</parent>

<!-- groupId and version can be skipped since it will be inherited from parent -->
<artifactId>com.test.child2</artifactId>

<dependencies>
    <dependency>
        <groupId>com.test</groupId>
        <artifactId>com.test.child1</artifactId>
    </dependency>
</dependencies>

If you try to when using the dependencyManagement the dependencies between modules will never have to define any versions since they are defined in the parents pom.

I have never had any problems with releasing multi-module projects by this approach.

Edit

To be clear: dependencyManagement does not have anything to do with the inheritence between parent-child. It solves any problems with the version of dependencies between child modules. And it works during releases.

0
Brett Porter On

You should create a multi-module structure, under a single version control hierarchy, for the simultaneously, identically versioned modules. Continuum will allow you to add them to a group either as a single job or multiple jobs per module, and either way the release mechanism will trigger from the parent and automatically resolve the versions for you.

Incidentally, you can drop <version>${parent.version}</version> and the identical groupId, as they will be inherited from the parent.

If the global parent is released separately, you should split that out into a separate module rather than making it part of the same multi-module structure. You can find an example project in this layout here: https://github.com/brettporter/centrepoint

1
Duncan Jones On

If you want all the version numbers to stay in sync, you can make use of the autoVersionSubmodules flag of the Maven release plugin. Setting this value to true will allow you to perform a release at the top project level and have all the sub-modules released with the same version as the parent.

This can be specified on the command line when you run mvn -DautoVersionSubmodules release:prepare or in a POM file as follows:

<plugin>
  <artifactId>maven-release-plugin</artifactId>        
  <version>2.3.2</version>
  <configuration>
    <autoVersionSubmodules>true</autoVersionSubmodules>
  </configuration>
</plugin>

I haven't used Continuum, but I believe it uses the Maven release plugin under the covers? Some Googling suggests this might work (based on a number of "nice to have" bugs regarding how the Continuum interface handles this scenario).