Question

Assuming the following tree:

foo
├──trunk
├──branches
│   ├──1.0-rc1
│   ├──2.0
│   └──2.0-crazy-feature
└──tags
    ├──1.0-rc1
    └──1.0-final 

what Maven/Ivy version number should the artifacts from each directory have? -- actually, I can guess for the branches and tags, but trunk has me stumped.

foo
├──trunk                  ⇐ ????
├──branches
│   ├──1.0                ⇐ 1.0-SNAPSHOT
│   ├──2.0                ⇐ 2.0-SNAPSHOT
│   └──2.0-crazy-feature  ⇐ 2.0-crazy-feature
└──tags
    ├──1.0-rc1            ⇐ 1.0-rc1
    └──1.0-final          ⇐ 1.0

The Maven convention doesn't really match up exactly with the Subversion convention here, especially if you're trying to be strict (cf. Vincent Driessen's git branching model) about never checking code directly into the trunk, only via merges.

A spot check in the wild suggests that most people aren't being that strict, and the trunk (or git master) just starts as 1.0-SNAPSHOT, later becomes 2.0-SNAPSHOT, etc. But assuming your release schedule is complex enough that you need to distinguish the trunk from the version release branches, and you don't want your build system to get confused as to whether trunk or branches/2.0 is the "real" 2.0-SNAPSHOT, what version number should trunk produce?


N.b. we're stuck with SVN here for the time being, but I don't want us to make decisions now that will preclude moving to git once we first get everybody comfortable with proper branches and proper versioned artifacts. Also, the tree above is just one project but what we actually have is (literally) about 500 individual modules, currently in a single monolithic repository.

Was it helpful?

Solution

It depends what your trunk represents.

If you use the unstable trunk methodology, your trunk version will be whatever your future version will be. For example, If your last release was 4.9, your trunk will be 4.10 or maybe 5.0 depending what you plan to call the next release after 4.9.

Maven and Ivy have differing ways to refer to preliminary revisions. In Maven, preliminary revisions are SNAPSHOT revisions. They have their own repository. With SNAPSHOTS, Maven automatically downloads the latest version even if the user has a previous SNAPSHOT revision. When a jar is in the Release repo, Maven doesn't automatically download a newer revision if the user is using an older revision.

Maven will integrate with your revision control system, and automatically update the pom.xml to change the version to a non-snapshot number.

I am not a big fan of that. We test particular Subversion revisions. They go through a series of tests. First, Dev will test. When they are happy, they pass that Subversion revision to QA. QA tests, and when they are happy, they send that revision to UAT. When UAT is happy, I want that particular revision to be my official release and I want to tag that one. In Maven, I am suppose to let Maven do the checkout, update my pom.xml, do a new build, deploy that new completely untested jar as my official release, and then tag my release.

In Ivy, the jar has a status associated with it in the ivy.xml file:

  • integration: revisions builded by a continuous build, a nightly build, and so on, fall in this category
  • milestone: revisions delivered to the public but not actually finished fall in this category
  • release: a revision fully tested and labelled fall in this category

I actually like this way much better. I don't have to change the revision. I don't need a second repository for snapshots, etc. It's clean and simple. Unfortunately, it's not compatible with Maven's methodology. I can't imagine things being that different with Git and Subversion is the way Maven works. In either system, you must create a new revision with a new non-snapshot pom.xml. In ether system, you must rebuild the jar. In either system, you must let Maven handle the tagging.

We do the following:

  • We use Jenkins as our CI system.
  • Most of our projects use Ivy and not Maven for historic reasons.
  • When I build a jar, I create two POMs from the ivy.xml. I create a pom-snapshot.xml and a pom.xml. We have a special <jar.macro> task I defined that is almost 100% compatible with the normal <jar> task. Except this task produces a pom.xml, a pom-snapshot.xml and the jar with the Maven information embedded in it.
  • We use the Jenkins Promoted build plugin with two defined promotions. One uses the pom-snapshot.xml to deploy the jar to the Maven snapshot repository. The other uses the pom.xml to deploy the jar to the Maven release repository. Developers promote the jar to the snapshot repo (some projects automatically do this with every build). When we have an actual releasable jar, we promote the jar to the Maven release repository. It also will tag that particular build as the actual release.

That means our branches do both the snapshot and release versions of our jars. We get to pick and choose which Subversion revision (actually which Jenkins build) is our official release build.

OTHER TIPS

Based on a casual inspection of the Apache projects' revision history, it looks like the version number in the trunk should be a snapshot "one greater" than the highest version of any branch/tag.

For example, the Maven release plugin was used to prepare the 2.11.0 release of the Camel project as follows: In revision 1468763 the trunk version of the Camel project was changed from "2.11-SNAPSHOT" to "2.11.0". The next revision copied the trunk to the new "2.11.0" tag. The succeeding revision updated the trunk version to "2.12-SNAPSHOT".

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