Fully automate release procedure with release+versions plugins
Asked Answered
C

1

12

Would be great if Maven guru community can help me with the following task.

I would like to automate the release process of Maven module in Hudson in a way that release process runs in batch mode (does not need anything to be asked from console). Currently I use common steps release:prepare (with <preparationGoals>versions:update-parent clean verify</preparationGoals> to update parent to latest version before commit) + release:perform. However I would like Maven to do the following:

Somewhen during preparation step:

  • For all dependencies which match the groupId of the current module and parent, replace -SNAPSHOT with released version (e.g. versions:use-releases -Dincludes=???).

Somewhen after release:

  • For all dependencies which match the groupId of the current module and parent, replace release version with -SNAPSHOT version (e.g. versions:use-latest-snapshots ...).

Example:

<parent>
    <groupId>org.mycompany.myproject</groupId>
    <artifactId>myproject-parent</artifactId>
    <version>1.0-SNAPSHOT</version>
</parent>

<dependency>
    <groupId>${project.groupId}</groupId>
    <artifactId>myproject-api</artifactId>
    <version>1.1-SNAPSHOT</version>         
</dependency>

before module is tagged is transformed into:

<parent>
    <groupId>org.mycompany.myproject</groupId>
    <artifactId>myproject-parent</artifactId>
    <version>1.0</version>
</parent>

<dependency>
    <groupId>${project.groupId}</groupId>
    <artifactId>myproject-api</artifactId>
    <version>1.1</version>          
</dependency>

and after release is succeeded is transformed into:

<parent>
    <groupId>org.mycompany.myproject</groupId>
    <artifactId>myproject-parent</artifactId>
    <version>1.1-SNAPSHOT</version>
</parent>

<dependency>
    <groupId>${project.groupId}</groupId>
    <artifactId>myproject-api</artifactId>
    <version>1.2-SNAPSHOT</version>         
</dependency>

I feel like it needs a mixture of

versions:use-releases scm:commit release:prepare release:perform versions:use-latest-snapshots scm:commit

but I am not sure what is the best way of doing this. Especially it would be nice to have as less commits as possible: the difficulty is that reparationGoals are run after -SNAPSHOT version check.

The described project is not a multi-module project in a sense that parent POM is not referring it's children via <modules>. SCM structure is the following:

 .
 |
 +-- myproject-parent
 |   +-- pom.xml
 +-- myproject-api
 |   +-- pom.xml
 +-- myproject-impl
     +-- pom.xml

Dependencies are:

myproject-api → myproject-parent
myproject-impl → myproject-parent
myproject-impl → myproject-api

The project's parent POM (myproject-parent) will be released rarely and thus will be released first. Then myproject-api (if necessary) and then myproject-impl.

Consume answered 10/5, 2012 at 19:35 Comment(0)
R
5

The simple problem you have is that your parent has a different version number than your childs which is the wrong way for a mulit-module build. A multi-module build is intended to have a number of modules related which have the same release process from which follows to have the same version number. If you follow that guideline you don't need the versions plugin you only do the release via release:prepare and release:perform That's it.

Update: After the further discussion I would suggest to setup a new set of Hudson jobs which contain the dependencies between the modules (downstream/upstream deps.) and do a release on each hudson job which triggers the next in the string of the jobs and so on. This prerequisites to have separate modules and separate areas in the version control as well. Otherwise this fight will be lost with Maven and complicate the life.

Reagent answered 11/5, 2012 at 12:36 Comment(7)
I can't agree with you. We have flat module structure: this is the only way to make them split and independent in Hudson (otherwise test fail in submodule fails the whole project build). Some of the modules (e.g. parent POM) are rarely changed: there is no need to release them. Others (like "model") will be released few times. And your advise does not work if I have dependencies between two multi-module projects. Also even for multi-module build I have no evidence that release:prepare will replace -SNAPSHOT dependencies with "future release" versions.Consume
For the first i can say it's good if the tests fail the whole build will fail cause something is wrong. The question is why do you like to have them separated in Hudson? Either this is a multi-module build or it is not. Furthermore if you parent pom is changed rarely so it sounds it could be a separate module which has it's own release cycle and you need to release it cause it's used as a dependency/parent by others. If you have dependencies between the modules what will work perfect in a multi-module build. I can recommend to take a look here: github.com/khmarbaise/javaee as example.Reagent
For the first i can say it's good if the tests fail the whole build will fail cause something is wrong. It's not always handy. In our project small groups of developers work on their own module. Each module has it's own email notification list to send emails when build fails / recover from failure. Thus persons X and Y are responsible for modules A and B.Consume
The question is why do you like to have them separated in Hudson? Each Hudson job has it's own history of builds, history of code coverage matrices and backup of artefacts. Have you ever used CI in enterprise environment? If so you should know the rule: if CI fails, no commits are allowed, and team should fix CI first. Slicing of big module into smaller parts gives the opportunity for the team to continue development on independent module non-failed module.Consume
Either this is a multi-module build or it is not. The project I describe is not a multi-module project in a sense that parent pom is not referring it's children via <modules> section. I have updated the question. Furthermore if you parent pom is changed rarely so it sounds it could be a separate module which has it's own release cycle and you need to release it cause it's used as a dependency/parent by others. Yes, this is exactly the situation: parent POM is released separately.Consume
If you have dependencies between the modules what will work perfect in a multi-module build. I can recommend to take a look here You project has a clean structure, as Spring or Hibernate projects, which are released as one project. However my situation is the same as javax.xml.bind:jaxb-api+com.sun.xml.bind:jaxb-impl+net.java:jvnet-parent: each of them are released separately. Your situation is simpler, because you refer version via ${project.version} which is inherited from your POM.Consume
In your case maven-release-plugin will replace the POM version <version>1.0.3-SNAPSHOT</version> to <version>1.0.3</version>before actual release, because you're doing the multi-module build. Do you type the versions from console, or you use autoVersionSubmodules=true? Also your update in the answer does not help match: it's clear how to setup jobs and triggers, it's not clear how to do the release. Will maven-release-plugin update the versions to latest released artifacts? (P.S. sorry for slicing the answer, I hit the comment limitation)Consume

© 2022 - 2024 — McMap. All rights reserved.