Release cycle / version numbers / breaking changes

Great to actually discuss these topics so we can reach a consensus for the project since there are clearly different incompatible views on these topics.

These topics are difficult and can influence each other and thus make sense discussing individually and together. I’ll try to add some points to the discussion to get a better view of the big picture.


Assumptions

Some assumptions are made in this post, would be good to back that up with some actual feedback from users on this matter. Are projects not using Neos due to a lack of SemVer or no defined release dates or fear of investment protection due to deprecated versions?

What are the problems with the way we’ve done it so far and are how big are they?


Definition of how we’re done it so far for Neos (as seen from my perspective)

Minor releases (1.1, 1.2) included a small/medium amount of breaking changes that wouldn’t require major changes in project code to upgrade and small/medium new features. Major release (2.0) required bigger changes in project code to upgrade and included large new features. Very important breaking bugfixes were included in patch versions. Everything has been based on “sentimental versioning”, where every breaking changes were taking into consideration.


API

Following SemVer requires a clearly defined API, which cannot be said for Flow and especially not for Neos.

What defines the public api? The @api annotation? Something being documented? Interfaces? Settings?
This needs a clear definition and be put into practice before we can even think about applying SemVer.

Flow
The @api annotation can work for most cases in Flow, but doesn’t cover things like configuration, policies and routing. Additionally the definition of the @api has never really been done thoroughly AFAIK.

Neos
Even fewer things are defined as API in Neos, and thus far if something was documented it became API. Which is not really a good practice. Since there’s no clear definition, we really don’t have an API we can use to follow SemVer with. That doesn’t mean we don’t have an API, but it’s hard to make rules about not breaking it.

In general SemVer works well for libraries with limited scope and a clear public API. However if you have a large surface area, which I’d definitely say about Neos, it becomes hard to follow.


What makes/justifies major releases?

A time schedule? Enough breaking changes? Bigger features requiring breaking changes? Marketable features?


Semantic versioning

One point about SemVer is that it’s based on breaking the public API. One important point is that you should not fear major releases, which works well for libraries, but poorly for things that need marketing. A new marketable feature might not require breaking changes, but unmarketable refactorings might. So either following SemVer puts constraints on the marketing or not following it puts constraints on SemVer. It is possible these things can work together, but it would be far from optimal and one would likely often weight more than the other.

It’s also highly likely than that the immature (API) we now have will either require more major releases or hinder progress.


Breaking changes

I see breaking changes as basically everything that can break project code, since we don’t have a clearly defined API.

Additionally automated migrations can also break project code, and thus I don’t agree with the given definition.

So far everything (in most cases due to different approaches) that potentially could affect end users have been marked as breaking. This have been assumption based though. To me this is actually very useful, because I can easily check the list of breaking changes to see if any of them apply to my project. Also helps if you’re using the development version of a branch.

As long as we don’t have a clearly defined API, I think this is our only sensible option.


Release cycle

What exactly are we solving by setting specific dates on releases? Plenty of projects don’t rely on that without any problems. It does put a lot of pressure on us as a project, which I really don’t think is worth it. Additionally it’s not agile in any way. If a release makes sense, then a release is due. I find it much more important that we strive for smaller releases and release more often than trying to stick to a predictable schedule.

If the problem it’s solving is investment security, then I’d argue we can solve it better by promising certain lifetimes for releases in terms of bugfixes and security fixes. This doesn’t put pressure on the releases, but secures investment. If you want to have new features you can upgrade if there’s a new version out.

Since predictability puts constraints on progress and quality, consider what has more value: predictability or progress and quality? Personally I prefer delivering a good product when it’s ready over a forced release according to a schedule.

When a new version is out then you can consider if you want to upgrade or not based on the estimated amount of work required depending on the release.

And basing a decision on our experience about half a year per release should be avoided since in reality those deadlines have primarily been met due to select individuals putting in unhealthy amounts of effort to finalize them due to broken promises on release dates. Which is why I don’t think we should set those dates. Rather be agile, make smaller scoped releases more often and improve our development and delivery process. Feel like we’re discussing Optimizing release development workflow for Neos/Flow here again.


My take

In general I see Neos in a maturing state without a clearly defined API. This doesn’t mean that it’s not perfectly usable, but following SemVer at this state doesn’t make much sense on my opinion. It still has broken or flawed concepts and even missing important ones, that require maturing and doesn’t have a clearly defined API. I’d suggest we keep following a more pragmatic and agile approach and adopt SemVer at a later state. This should be combined with trying to keep things backwards compatible and keep an easy migration path. I think our user base will be better off with that in the end.

Flow could adopt SemVer, but even there are quite some things that still need basic plumbing (just see the changes @christianm is pushing lately) and a clearly defined API. In Flows case I don’t see any good reason not to release major releases more often, since it’s not marketed and serves more as a library.

  • -1 for time scheduled releases
  • +1 for promising release lifetimes
  • -1 for SemVer for Neos (now)
  • (+1) for SemVer for Flow (now)
  • +1 sentimental versioning for Neos (now)
  • Release major when migration path becomes too difficult.
  • DoD: all changes potentially breaking project code are breaking until a clear API is defined

Ps. an interesting post and discussion regarding semantic versioning.