Semver and dev/preview/stable - a proposal

First off, thank you for responding promptly to the recent security issue and releasing a new stable version containing the fix.

Some folks were annoyed that in order to get the security fix, they had to take an entire new release with a lot of additional functionality, requiring they do a lot more testing before putting that release introduction production. Below I make a proposal for easing that problem.

Railo and Lucee have long followed a variant of Semantic Versioning that has enabled a very smooth, automated update process. It has always been the case that version numbers are strictly monotonically increasing and that releases are strictly cumulative, i.e., version x.y.z.(nnn+1) always includes all the functionality of version x.y.z.nnn.

The current process of always pushing new versions out through the dev provider, then promoting some of those to the preview provider, and then promoting some of those to stable has generally worked well, but it creates a problem when a small, high-priority fix such as a security patch is needed.

Consider what happened with this latest release: 4.5.1.000 was the previous stable release, and 4.5.1.001 thru 4.5.1.021 had already been pushed out through the dev provider, so when the security patch was made, there was “no choice” but to add it to 4.5.1.022 and push it out through the same channels: there was no space in the number sequence to push a security patch to 4.5.1.000 that would have preserved semver and cumulative releases.

Proposal

When any version is promoted to the stable provider, immediately reset the next dev version to increase the minor version number (with the patch number set to 000). This would ensure that if version x.y.z.nnn is stable, the next dev stream would be x.y.(z+1).000 onward. This would always leave space for high-priority security patches to be applied in isolation to the stable version (as x.y.z.(nnn+1) etc).

Proposal Applied

For the case in hand, once 4.5.1.000 was declared stable, the next dev version should have been 4.5.2.000 and it could have been rev’d up to 4.5.2.021 as before, but when the security patch came in, it could have been made available as 4.5.1.001 on the stable provider, allowing users to “safely” update without needing to pick up a lot of other functionality, whilst still preserving the purely cumulative native of releases on each provider stream. So we would have had 4.5.2.022 on dev containing the security patch, and 4.5.1.001 on stable containing the security patch, reducing the risk for users who want to maintain a stable-only production server.

You could then have promoted 4.5.2.022 to preview for extended testing and ultimately to stable (at which point dev would change to 4.5.3.000).

Now, of course, if you’d released 4.5.1.021 as the new stable release a few weeks back as indicated in your blog post, and then 4.5.1.022 had come out containing only the security patch in addition, folks would still have had to accept a block of functionality in order to update from 4.5.1.000 but it’s reasonable to argue that 4.5.1.021 had been out as stable for two weeks and they had time to start testing. Still not ideal, but better than what actually happened, IMO.

Anyway, I hope you will consider bumping the minor version in future every time you release a new stable version, so that you can leave space in the version numbers for high-priority patches. Thank you.

5 Likes

Well thought out approach, Sean. I like it, though it will ultimately be up to @micstriit. The other nice thing about this is that each stable release will get tagged with a unique “z” which will help set them apart a bit.

Cheers for taking the time to write that up Sean. Makes sense to me.


Adam

To be honest with Lucee we have broken the release pattern we had with Railo and I plan to go back to our old pattern. Means the next release for Lucee 4 will be 4.5.2.000 on dev, so then maybe with 4.5.2.013 we decide to make a new stable release, the next release AFTER that stable release will be 4.5.3.000. This is how we handled this with Railo for one simple release, we could always make new releases for older versions, for example 4.5.2.014 for the example above, if a client was asking for a fix for an older release. So in other words we already had this pattern with Railo and I plan to go back to it with Lucee.
Why we not used that pattern with Lucee? The first stable release from Lucee was 4.5.0.042, problem was that this version had an issue we needed to address ASAP and because of that 4.5.1.000 was already the next release. Now I did a mistake, the next release was 4.5.1.001, but it should be 4.5.2.000.

1 Like

That’s good to know, thank you @micstriit! I hadn’t gone back and checked the Railo releases but I had wondered why we’d never run into this complaint before, with years of Railo builds (and a few security patches).

Glad to hear you’ll be doing it the same way for Lucee going forward. Thank you!

We’re doing a big migration from Railo to Lucee, specifically because of the security fix (we’re not worried about the additional functionality this time as we’ve been running locally with Lucee 4.5.1 builds for a while).

an update on this, with the move to maven as as our central repo for builds, we will also adapt the maven pattern for handling builds. means we will only have 2 update channels for Lucee 5.

Snapshots:
every commit triggers a new snapshot build (if the testcases passes) automaticely to central.sonatype.org.

Releases:
build is triggered manually by the Lucee Team and published to central.sonatype.org and maven central (core file and jar).

2 Likes