4

I have a question about versioning when I depend on a third party (TP) project's versioning. Our current process is to release a new version every time TP creates a release with security fixes. The problem is when a TP release contains new funcionally that we want to use in some but not all of the projects we maintain.

Scenario

Current project structure

Third party project (version 5.5)
    My base project (version 1.2 (inherits v5.x))
        My project 1 
        My project 2 
        My project 3 

New project structure

Third party project (version 5.6)
    My base project (version 1.3 (inherits v5.x))
        My project 1        
        My project 3 
Third party project (version 6.0)
    My base project (version ?? (inherits v6.x))        
        My project 2 

Key points

  • They are Maven projects and are inheriting from the parent project pom.xml
  • I cannot use the import scope because both projects (TP and Base projects) modify the lifecycle of the application.
  • In order to move from TP version 5.6 to 6.0 it is necesary a costly migration process.
  • Both new versions (5.6 & 6.0) have security fixes so it is advisable to update all the projects
  • Version 6.0 has new features that we need on My Project 2
  • TP might release version 7.0 and I would have 3 active versions of My base.

Question

I would like to have some advice about how to version My Base Project to keep more than one active version at the same time.

My current options are:

  • Match the version number of TP by updating the version number for MyBase to 5.6 and 6.0 respectively. This approach might generate gaps if I decide not to upgrade a specify version.
  • Use the semantic versioning and increase minor and micro version number for keeping both versions (Thank you Berin Loritsch). As a variant I coult increase major version number if the changes affects to end users (Thank you Ryathal)
  • Use semantic versioning plus sign to mark the one of the versions. How to Name Different Branches with Identical Functionality in Semantic Versioning
  • Get rid of My base project and add the features of it in each of My projects. This option will have maintainability issues so I don't thing it would be the better way.
8
  • 1
    I'm confused by the way you show your project as a child of the TP project. I would expect the TP projects are dependencies of your project, not the parent.
    – JimmyJames
    Jan 14, 2019 at 18:11
  • I completely agree about TP being a dependency. The thing is the project was created through a maven archetype and it is required that the pom of "My project X" inherits from TP. This is because TP alters maven lifecycle.
    – JCalcines
    Jan 15, 2019 at 9:21
  • Is the point of this TP project to modify maven or is that simply a requirement of using it?
    – JimmyJames
    Jan 15, 2019 at 14:21
  • TP modifies maven lifecycle for My project but it also acts as a required dependency.
    – JCalcines
    Jan 15, 2019 at 15:48
  • JCalcines That sounds awful. Is there another option for using it?
    – JimmyJames
    Jan 15, 2019 at 15:50

3 Answers 3

3

Versioning is hard, and there are no right answers, occasionally there is a good answer. At a minimum you should be bumping you minor version when you update third party dependencies. When a dependency gets a new major version you have to decide if updating requires you to release a new major version or not. If the new version doesn't change the functionality you were using in the previous version, then maybe you can do a minor version that may break your users relying on undocumented behavior. If you want to add new features or otherwise change your interface you need to increase your major version. The exact details of a branching strategy can vary wildly, but at a minimum you will want separate version 1.x and 2.x branches, possibly allowing updates from 1.x to be pulled to 2.x.

Maintaining multiple release branches is going to create overhead, and if the need for version 3.0 comes its going to cause even more overhead. To mitigate this you need to create a support window and publish it. The point of a support window is to state publicly when you will effectively delete a branch/version of your code base, so you really only have X versions of your code base active at any time.

3
  • Thank you for the answer! I was also concerned about source control but I didn't want to overcomplicate the question.
    – JCalcines
    Jan 15, 2019 at 9:58
  • 2
    @JCalcines proper source control will vastly simplify managing multiple versions.
    – Ryathal
    Jan 15, 2019 at 13:10
  • Thank you again! Focusing on source control I found this related issue: softwareengineering.stackexchange.com/questions/221925/…
    – JCalcines
    Jan 16, 2019 at 9:10
1

It looks like you actually have a couple problems here:

  • Versioning
  • Breaking changes in third party libraries

Within your application infrastructure, you only need to worry about the versioning and supporting the versions that you actually use right now. In other words keeping up with the bleeding edge is going to make things difficult in the long run.

There are several versioning schemes, but until recently one of the schemes that had a lot of support was the concept of "semantic versioning" which there are a few variations of that theme. The idea is that you had 4 parts to your version: Major.Minor.Micro.Patch. In this scheme, changing a number has sort of a meaning:

  • Major -- Usually a redesign, rewrite, or other big breaking changes that were needed to make it a reality
  • Minor -- Usually new features, but it should still be compatible with everything else
  • Micro -- Bug fixes, or security fixes
  • Patch -- Either a dependency update or a hot fix out of cycle (not all semantic versioning variants have this)

The nice thing about this approach is that it has a story behind the versions, and you can infer roughly how much work would be needed to make use of the library or tool.

However, these days it seems more in fashion to increase version numbers quickly. As a result you lose the idea of how much effort it would take to make use of the library. It may be a massive undertaking, or a drop-in replacement with more features. You just don't know. Most browsers follow this approach so you see the first number skyrocket from 1 to 60+ in a short period of time. Even Java itself is starting to follow this trend with major version changes in a short period of time (look at how quickly we went from Java 8 to Java 11, and now it looks like every six months the number will increase).

The bottom line is that you have a scheme that makes sense for your products. What you've outlined seems to make sense at a high level. What I don't get is a feeling for what versioning tactic your 3rd party library is using. It might inflate your version numbers unnecessarily if they are using the latter variation.

I would recommend one thing:

  • Only maintain as many separate versions of your base project as you have a current need for. In this case it might only be 2 even if they release version 7.
1
  • This make sense, I was talking about version 7 in the sense that we might need to migrate in the future because they include some other wanted feature. I cannot properly use the semantic versioning because stupidly this project is release depending on third parties but I get from your answer that the best approach would be to use minor and micro numbers
    – JCalcines
    Jan 15, 2019 at 9:41
0

I would always recommend using composition over inheritance in these scenarios. This will make your projects much more manageable and better scoped.

It might be better to create a facade in your base project that passes the command on to TP instead of inheriting it. For example

// Base
doSomething() {
    TP.doSomething();
}

This will keep the scope narrow and as long as a new version of TP.doSomething() doesn't change any behaviour of how your Base project, you should only update the patch of the semantic versioning of your Base project.

If a new method or functionality of TP should be added to the scope of your Base project, add it to the facade and bump up the minor version.

If doSomething() would have changed (other behaviour, other return value or arguments), then this is a breaking change for your Base project and a major should be bumped up.

If you use inheritance anyway, these same rules apply. If you can be sure that your TP applies these rules perfectly, than you should bump up the version of your Base project at the same level as the difference between the old and new version of TP was.

So for patches, if TP goes from 5.6.0 to 5.6.3 for example, your base project could go from 1.2.0 to 1.2.1.

For minor bumps: TP 5.6.2 to 5.7.0, base could go from 1.2.1 to 1.3.0.

For major bumps: TP 5.6.3 to 6.1.2, base could go from 1.2.1 to 2.0.0

It doesn't matter how many versions were between the old and new version of TP. Look at the highest level of version change (major, minor or patch) and bump your depending project up by the same level.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.