Release cycle and versioning

During the Dresden code sprint in March I prepared a summary of Release cycle / version numbers / breaking changes which we discussed and decided upon.

Here is what we decided upon, as shown during the sprint, including some open ends. It is being added to the Neos website and will be announced in a news item.

Note: The authoritative source for the release cycle, versioning, etc. will be the website, not this post.


Neos Versions

Semantic Versioning

Neos releases follow Semantic Versioning, meaning in a nutshell that given a version number MAJOR.MINOR.PATCH, increments to the:

  • MAJOR version indicate incompatible changes,
  • MINOR version indicate added functionality in a backwards-compatible manner, and
  • PATCH version inidcate backwards-compatible bug fixes.

See http://semver.org/ for the full details on this.

It is notable that a major release is not always defined by great new features. Features are introduced in minor releases as well. But a major release will come with breaking changes (and usually some new features made possible by them).

Definition of Incompatible Changes

The public API of Neos and Flow is made up of the following components:

  • PHP API as documented on https://www.neos.io/documentation/api.html
  • Validator settings, VH parameters, TS objects, Eel helpers, FlowQuery operations
  • Configuration provided by our packages (YAML files)
    • Settings: no removals / renamings!
    • Caches: adding caches / changing defaults needs to be documented!
    • Policy: about the syntax, predefined roles
    • Objects: mostly about the syntax, changes limited by public API
    • Routes: in general there should be few interaction with third-party packages, so it’s about the syntax here
    • NodeTypes:
  • Database schema: <define scope of “breaking”, ways to keep system up>
  • JavaScript: no defined public API yet, except the documented editors/validators
  • Public default output (e.g. Neos markup in frontend)
  • Minimum requirements (PHP, Browser)

Every change to the above which requires an action by the user, integrator or developer which can’t be easily executed as an automated task during deployment is a breaking change and requires a major version to be released.

According to that definition, code migrations are breaking, but database schema upgrades or node migrations (if they can really be executed safely during a deployment) are okay.

Even the cases were the needed adjustments can be automated will be clearly documented so the consumer can assess the impact of such a change.

Release Cycle

When following Semantic Versioning, there is no point in releasing one major version after another. That means we need to take an extra look on changes which break backwards-compatibility. A release schedule helps to plan ahead - if we know when the next major version is being scheduled, we can either postpone backwards incompatible changes to a later version or maybe find a creative way to make the change compatible.

  • Three minor releases per year, with patch level releases as needed in between.
  • Major releases happen yearly, assuming there will be breaking changes.
  • Each release receives bug fixes for 1 year and security fixes for 1 additional year (2 in total).
  • Each Long Term Support (LTS) version receives bug fixes for 2 years and security fixes for 1 additional year (3 in total).

This results in a simple and predictable scheme. For Neos (Flow follows the same rhythm) this currently means:

  • 2.0: August 2015
  • 2.1: December 2015
  • 2.2: April 2016
  • 2.3: August 2016 (LTS)
  • 3.0: December 2016
  • 3.1: April 2017
  • 3.2: August 2017
  • 3.3: December 2017 (LTS)
  • 4.0: April 2018
  • 4.1: August 2018
  • 4.2: December 2018

In the (unlikely) event of no breaking changes being present, no major version is released, minor versions are released instead. In such a case a minor release will be declared as LTS, making sure the flow of LTS releases stays intact.

What’s in a Release?

While this may be an interesting question to some, it isn’t to us. In some cases we might plan a certain feature to be done for a specific release, but in general we just work on features and merge them into the master branch when they are done.

From this branch the next minor release is done as scheduled. So whenever a feature is merged in master, it is known when it will be released.

Breaking changes are usually held back (maybe in a separate branch or even a developer’s fork) until it is known the next release done off of master will be a major release. Another option is the use of a branch to officially collect changes for the next major release earlier.

Stupid Versions Chart

    | 2016           | 2017           | 2018           | 2019           | 2020             
----+----------------+----------------+----------------+----------------+------------------
    | JFMA MJJA SOND | JFMA MJJA SOND | JFMA MJJA SOND | JFMA MJJA SOND | JFMA MJJA SOND   
2.0 | ++++ +++
2.1 | ++++ ++++ ++++ |                |                |                |                  
2.2 |    + ++++ ++++ | +++            |                |                |                  
2.3 |         + ++++ | ++++ ++++ ++++ | ++++ +++       |                |                  
3.0 |              + | ++++ ++++ +++  |                |                |                  
3.1 |                |    + ++++ ++++ | +++            |                |                  
3.2 |                |         + ++++ | ++++ +++       |                |                  
3.3 |                               + | ++++ ++++ ++++ | ++++ ++++ +++  |                  
4.0 |                                      + ++++ ++++ | +++            |                  
4.1 |                                           + ++++ | ++++ +++       |                  
4.2 |                                                + | ++++ ++++ +++  |                  
4.3 |                                                  |    + ++++ ++++ | ++++ ++++ ++++ ++

Breaking the Rules

This policy will be followed on a best-effort basis. In extreme cases it may not be possible to support a release for the planned lifetime; for example if a serious bug is found that cannot be resolved in a given major version without significant risk to the stability of the code or loss of compatibility. In such cases, early retirement of a version may be required.


This was accepted by:

5 Likes