Discussion: Strategies for handling multi-version package compatibility

I have several packages that I’m looking to update for version 17 compatibility. I’m thinking about the best way to go about doing this. I thought I would come here and ask for everyone’s opinions about best practices, or just explanations of how you do things and why you chose that strategy. :blush:

My current thoughts on the topic…

I would prefer to have a multi-targeted package if that’s not too difficult to manage. This would allow a smoother upgrade process for people and would mean that any underlying logic updates that were made (for instance, for version 17) would be usable in version 13 without any extra effort on my part. So far, for my packages which are just class libraries, this seems to be working pretty well.

My question really relates to packages that involve either dramatic API/code differences between version 13 and version 17, or perhaps ones that require back-office UI bits, which are definitely different between those versions.

I’ve noticed on a lot of great packages (like Contentment) there are different major version numbers to manage compatibility between Umbraco versions. So the same code base is being used, and there are just different branches for each version. I can see the convenience of this, and it also means that you don’t actually have to change the installed NuGet package when you update your website, you just need to change the version number of the package.

However, another perspective I’ve had is about convenience for updating via NuGet. Oftentimes, the NuGet Package Manager will show a package as being ready for update, but in your current Umbraco website version, you really shouldn’t be updating it to the latest version of the package (because it won’t be compatible). This is not so much an issue for experienced Umbraco developers, but I think it could cause confusion for people that are less familiar with the ecosystem. In this case, actually having a different package with its own version-specific name would eliminate the possibility of accidentally updating to an incompatible package, because unless that package itself was actually updated, it would not show as having a new version available.

Anyway, I would love to get other people’s thoughts so that I can make a decision and move forward with my upgrades. Thanks!

1 Like

For Umbraco packages, I have a major version per Umbraco major version. I also set the supported version locked to Umbraco 17, so it won’t install on Umbraco 18, or Umbraco 16 anyway. So it’s locked to that Umbraco major. This prevents accidental updates of the package when you shouldn’t.

Yes, it means that I have to do a package update very time a new major comes out, but I also see that as a moment to do some rework, check if it needs maintenance, throw away some deprecated stuff and just test the bloody thing. So sometimes the ‘major’ update is really easy and fast (v16 > v17 for instance), but it’s at the very least a small maintenance moment. Or a very large moment if important things have changed in Umbraco.

And I keep the lifecycle that Umbraco uses so that I don’t have to support 10 different versions at the same time. I consider per situation what I need to back port and what not. I also like the fact that in NuGet browser it’s VERY clear what version of my package you need for the Umbraco major that you are on.

In my view, if a package is really simple, it might be worth doing multi-targeting, but my experience for anything larger is not good. Maybe someone else has a different perspective and I would be happy to hear those as well :slight_smile:

4 Likes

Hi Heather,

I used to multi target my packages. For example the V5 version my OEmbed Picker package supported both Umbraco 8 and Umbraco 9.

But my code base started to get cluttered with #if statements for different .net versions. Also I had to come up to target specific Umbraco versions. Some major versions of Umbraco run on the same .net versions, but can have API changes that need to be handled in your package.

So I also use the same way as @Luuk. Now I have a major version that aligns with the versions of Umbraco.

Dave

1 Like

Hi Heather!

Back when uMarketingSuite was still uMarketingSuite, we also started out with a multi-targeted approach. Over time however we ran into the same scenario as @dawoe and @Luuk where the codebase began to get cluttered with too many conditional rendering statements, and making it very difficult to manage our codebase. Especially in the later version of Umbraco we could no longer target just different .NET versions as multiple Umbraco versions rely on the same .NET version.

We’ve since switched over to the same approach as mentioned by the others, being different branches for each Major (same with all HQ Commercial Products), which has made it a lot easier to maintain and makes the code a lot cleaner to work with. If it’s a feature we develop those solely on the latest majors, if it’s a bugfix we develop them on the oldest still-in-support version and simply merge (or cherry-pick) those changes up the Major tree (Which takes very little time).

2 Likes

I found it especially annoying when you can’t features that would greatly improve code quality. I had a package that supported .NET Standard 2.0 and .NET Core and I couldn’t use ‘nullables’ from .NET Core because .NET standard did not support it.

To be fair, that was some time ago, but the annoyance stuck :stuck_out_tongue:

Thanks everyone for your feedback! I feel more confident moving forward with my updates now :blush:

While researching this, I also came across this other package-dev-related topic (Should a new package I am working on test agasint 17.0 or the latest release of 17? - #13 by mistyn8) with more interesting multi-version debates.

I think that at this time my strategy will be for my baseline packages (which are referenced by many of the other packages and are primarily class libraries providing useful models, calculations and extensions), I will try to keep as multi-targeted as possible just to make referencing simpler, and if I start to bump up against umbraco-version-specific issues, I’ll create new majors of those as needed.

For the more complicated packages, particularly ones that have any sort of back-office components, I’m going to go with the major version strategy that you all have mentioned. However, I don’t know if I’ll be devoted enough to keeping up with every STS version, perhaps only the LTSs, since those are the ones that I use for my clients. This might result in weird jumpy version lists, but I agree with many of you that having your package version number somewhat match the Umbraco version number is the least confusing to consumers of the packages. (I easily recognize that if I have a v13 site, and the latest package version is “17.2”, I’m not gonna update. This is way less clear if the latest version is “4.0.2” and my current package version is “3.9.6”…)

1 Like