2
votes

What is the numbering/versioning strategy for dependencies when doing snapshots/releases?

A team of 15 developers,20 Maven parent projects = total 70+ POMs including child module POMs. Currently there are a lot of dependencies where most of these 70 depend on one or the other.

Past:

All POMS have 1.0.0-SNAPSHOT as their version and also under dependencies tags.It gets uploaded to Nexus repo with mvn deploy.

Present:

We started doing mvn release recently. So all 20 parent POMs are now 1.0.1-SNAPSHOT and release ver 1.0.0 for all of them lies in Nexus.All <dependencies> tags now point to 1.0.0

Problem:

Developers don't want to point to release versions. They need bleeding edge development version 1.0.X-SNAPSHOT from their peers whether its unstable or not.

SCM wants to point to RELEASE versions only as he has to do a mvn release once a week which will fail as it points to snapshot versions.

Question:

Now I know the version plugin , but the question is, what do I put in the POM so that both parties are satisfied by running their own version of mvn versions: command. Preferably, the POMs should point to SNAPSHOTS so 15 people are happy, and when SCM does the release, he can run a mvn versions:something and everything gets converted to RELEASE versions in place of SNAPSHOTS. Then back to SNAPSHOTS for developers.

1
is this a single big-bang release, or are all the separate modules released independently? IOW how many projects does the SCM run mvn release:prepare release:perform on in order to cut the release - Stephen Connolly
20 projects released one by one . each would have 2-15 modules like projA-parent, projA-jar,projA-war,projA-Ear.. so total POMs modified by the release plugin would be 100+, but I am ok to do 20 iterations of a solution if there is one.. - Pulak Agrawal

1 Answers

3
votes

I am putting this as an answer, even though at present this is not quite working answer.

When I added the completionGoals configuration option in the Maven Release Plugin, my aim was to enable the work-flow where development used version ranges, but that releases would be pinned to concrete versions only.

One of the enabling goals that was added to the Versions Maven Plugin was the versions:resolve-ranges goal. What is missing is a way to unresolve those ranges again afterwards.

We don't really have anywhere safe to stash the originating ranges that the release plugin will not object to or clean up before we need it again.

The closest solution I have thought of is to inject XML PI's beside the version containing the version range... in such a situation, the pom.xml would get transformed from, e.g.

<project>
  ...
  <dependencies>
    ...
    <dependency>
      <groupId>com.foo.bar</groupId>
      <artifactId>manchu</artifactId>
      <version>[1.2.3,2.0)</version>
    </dependency?
    ...
  </dependencies>
  ...
</project>

to

<project>
  ...
  <dependencies>
    ...
    <dependency>
      <groupId>com.foo.bar</groupId>
      <artifactId>manchu</artifactId>
      <version>1.5.7</version>
      <?versions-maven-plugin allowed-version-range="[1.2.3,2.0)"?>
    </dependency?
    ...
  </dependencies>
  ...
</project>

by ensuring that the preparationGoals included the versions:resolve-ranges goal... (Note: the versions plugin might have to fork a third Maven to work around the lack of pom.xml reloading in order to have the clean verify be meaningful, though resolve-ranges is supposed to resolve in the exact version that the build is working with, so it shouldn't be an issue).

Then in completionGoals you have the (as yet unimplemented) versions-maven-plugin goal that removes the XML PI's and puts the ranges back in place.

There are a number of issues preventing this at present:

  • Unsure if the Maven Release Plugin's pom rewriting will remove the XML PI's (needs testing to confirm)

  • The XML parsing library in versions-maven-plugin is hacky at best, and a better solution is needed to enable the XML PI injection

  • My son demands attention, leaving very little time for me to attend to these issues.

However, you might be able to codge something together.

  1. Set completionGoals to something like versions:use-next-snapshots versions:commit

  2. Run your releases like so mvn versions:use-releases versions:commit scm:commit release:prepare release:perform install

So what should happen:

  • We switch the -SNAPSHOTs to releases

  • We commit the change to SCM

  • We start the release preparation

  • When the pom.xml is transformed to the next development version, we also advance the dependencies (using the fact that all our dependencies had the exact same command (with the install at the end) so their next -SNAPSHOT is already in the local repository, so they will get advanced for us automatically (in theory)) and we rely on release:prepare to commit the changes for us.

  • The release is performed as normally

  • We install the next development -SNAPSHOT into the local repo so that all the down-stream projects will get their version of this updated when they run versions:use-next-snapshots

The above is slightly error prone... I'd far prefer if I could offer you the version range based solution, but, well right now this is the best solution I can see.