1

Maven versioning parallel development process

I work on a project using SVN with the usual trunk and branches. I have nexus with two repositories with two different policies "Release" and "Snapshot". This project produces artifacts that are used from other projects in my company. Let's say at moment we are on version 1.0.1 so on Nexus in the Release repository I have artifacts-1.0.1.jar

When a new feature is required I perform the following steps:

  1. Create a new branch from trunk let's say feature_1 from trunk so I now have branches/feature_1
  2. Increase the version to 1.0.2-SNAPSHOT and on Nexus I’ll have 1.0.2-SNAPSHOT.jar

Before 1.0.2-SNAPSHOT is released, another feature is required and I'll repeat the previous steps:

  1. Create a new branch from trunk let's say feature_1 from trunk so I now have branches/feature_2
  2. Increase the version to 1.0.3-SNAPSHOT and on Nexus I’ll have 1.0.2-SNAPSHOT.jar and 1.0.3-SNAPSHOT.jar

At some stage I need feature_2 to go live and I perform the following steps:

  1. Merge feature_2 in trunk
  2. Deploy in prod and push the artifacts 1.0.3.jar to Nexus.

The process works fine if I didn't have a feature_1 that still in progress and has the version 1.0.2-SNAPSHOT.jar while the release version is 1.0.3.

Unfortunately the feature branches are not released sequentially. How can I manage versioning in this case? What am I missing?

Should I force the team working on 1.0.2-SNAPSHOT (feature_1) to merge trunk down to branches/feature_1 and increase the version from 1.0.2-SNAPSHOT to 1.0.4-SNAPSHOT?

It doesn't sound right to me.

carlitos081
  • 645
  • 2
  • 7
  • 19

1 Answers1

2

Only trunk should have a release version number, and merging in from a branch should cause it to increase. The branches should have trunk merged into them regularly (whenever it changes), and should have the version number of the intended release with the snapshot suffix.

Thus, prod is at 1.0, so is trunk. Feature 1 is targeting release 1.1, and feature 2 is targeting release 1.2. Feature 1 branch is 1.1-snapshot, and Feature 2 branch is 1.2-snapshot. If everything goes according to plan, you merge feature 1 into trunk, up the version number to 1.1 and release, deleting snapshots, and merge trunk into the feature 2 branch. Feature 2 is released in a similar way.

If Feature 1 is late, you merge feature 2 into trunk, up trunk's version number to 1.1, and release (deleting snapshots), merge trunk into feature 1, up the version to 1.2-snapshot (assuming it is now targeting that release), and build your first snapshot.

You should use build-numbers or some other incremental counter as a suffix to your version number: 1.0.0.4432. You're using svn, so I'd recommend using the revision number from svn as the final part, rather than a build number.

The real problem here is long-lived branches. You should investigate feature-flags if you really want to work on big features. Alternatively, work on smaller features so that this rarely happens, delivering large features incrementally through evolution rather than revolution. Personally I don't like feature flags, so I prefer an evolutionary approach.

An associated problem is that you're using what is sometimes called 'vanity versioning' The real version is the revision number in svn (which is why old folks like me sometimes called svn a Revision Management System), everything else is made up and has no basis in reality. This is one reason companies like IntelliJ and Microsoft stopped using them and started talking about release year and count -- thus, IntelliJ 2016 release 3 is currently in EAP (beta), and I have build 163.4396 which is a vanity number (163 -- year and release) followed by a build-number from their CI.

Software Engineer
  • 15,457
  • 7
  • 74
  • 102
  • Considering that I have sometime 5/6 and more feature branch in the same time and there is really no plan on which one goes first as this product depends on other systems that maybe can have problems/delay. I should maybe have the feature branches with no version but the name of the functionality let's say "SomeFunctionality1-SANAPHOT", "SomeName2-SANAPHOT" and then only when I merge up to trunk give the version number like 2016.x.rn where x is the build number and rn is the revision number from SVN. What do you think? – carlitos081 Sep 22 '16 at 20:04
  • 2
    You can't work like that and hope to reach a positive outcome. Assuming you have one team per feature then you have a program of work that needs a lot more management than it sounds like you're getting. You should be able to roughly plan out the timetables for feature development and release at a program level. Having said that, deferring versioning until you know what the version is, as you describe, seems to be the best option you have at the moment. – Software Engineer Sep 22 '16 at 20:08
  • Yes we are working on that aspect, we know that our process is not right and versioning is something that can hopefully help! – carlitos081 Sep 22 '16 at 20:13
  • 1
    Just don't use gradle, otherwise you will end up totally failing :). Good luck. – Software Engineer Sep 22 '16 at 21:33
  • 1
    Why I shouldn't use gradle? I push the artifact with Gradle and then I use it retrieve them as well... Which is your concern? I won't take the jar manually, it will be crazy! – carlitos081 Sep 26 '16 at 15:10
  • I have to say I prefer Gradle! – carlitos081 Oct 03 '16 at 17:07
  • 1
    It's not a question of preference. Gradle is a throwback to the days where the build system for each project was a major bespoke project in its own right. It is basically Ant rewritten in groovy. What you have is an unpopular programming language that is unfamiliar to the majority of java devs which forces configuration over convention. As a travelling consultant with large corporate and financial clients, I've yet to see a successful implementation or in fact any use of it that is anything but a complete mess. – Software Engineer Oct 05 '16 at 00:57