The Plone 6 backend/classic parts are ready for beta. What does it mean when we move from alpha to beta? I have some ideas on this that I want to share. They can be discussed, I am interested in your opinions.
This will be a long post. TLDR: A change should make Plone more stable, not less stable.
We first need to say something about semantic versioning. semver.org says as first rule:
Software using Semantic Versioning MUST declare a public API. This API could be declared in the code itself or exist strictly in documentation. However it is done, it SHOULD be precise and comprehensive.
In other words: if we want to use semantic versioning for "Plone the product" then we MUST define what our api is. The closest idea we have for that, is: Python imports should not fail, public classes, methods and functions should not be removed, and zcml should not give a component lookup error when Plone starts up. Properly defining our api is a tough exercise, and I won't do that in this post. But we can start with a guiding principle.
The guiding principle for the beta stage is this.
A change should make Plone more stable, not less stable.
Saying "no new features" and "no breaking changes" are nice approximations of this, but they are not always accurate.
For example: the latest version 1.6.0 of package
plone.app.querystring is used in both Plone 5.2 and 6.0. If we drop 5.2 support, this is a breaking change for this package, and we should give it a major version bump to 2.0.0. But from a Plone 6 standpoint, it is no problem at all to include this breaking change.
These are indications that a change you are making is something that we really do not want in beta:
- It drops support for a Python version that is supported by current Plone 6.0 (Python 3.7-3.10).
- It removes a file, a class, a function, a variable, an argument, a template, etc. Exception is when something is clearly marked as private, for example a method starting with an underscore.
If you are not sure, or if you think you have a good reason, please talk to fellow developers and open an issue.
These are warning flags that what you do may not be right for beta:
- It requires a change in multiple packages. Exceptions: an upgrade step in
plone.app.upgrade, changes to translations, or updates in other packages just for tests.
- It requires a new feature in plone.restapi.
- It needs an upgrade step that goes through all or most content to update something.
- It pulls in a new dependency, or requires a new major version of an existing dependency.
A warning flag does not mean that you must abandon your work. It may be acceptable. But please ask feedback before you put a lot of time into this.
This is usually fine:
- Anything that fixes a bug, without triggering any of the red or warning flags.
- Anything that increases compatibility with previous or next Plone versions.
- Fixes for compatibility with new upstream versions, especially new Zope or Python versions.
- A new browser view, helper function, template, etc.
- Marking a function or anything else as deprecated.
If you make a too big change in Python code, the Plone instance may fail to start up, or pages may give errors. This is clear breakage that must be avoided.
Rules of thumb:
- No big restructurings.
- Don't change ids or classes. Adding is fine.
- Don't update the css to Bootstrap 6.
Volto is the default frontend for Plone 6. The Volto 16 release that will accompany the Plone 6.0.0 final release should be an LTS version. It should be maintained during the maintenance and security life time of Plone 6.0.x. Minor version increases are fine.
New major Volto releases can be made that work with latest 6.0.x, but there will always be an accompanying Volto 16 release.
It is up to the Volto team how to fill this in, under the restrictions of the fast-moving front-end world. If this means it is practically only possible to create bugfix releases for half a year and then only security releases, that seems fine to me.
First as background an interesting quote from semver.org:
What should I do if I update my own dependencies without changing the public API?
That would be considered compatible since it does not affect the public API. Software that explicitly depends on the same dependencies as your package should have their own dependency specifications and the author will notice any conflicts. Determining whether the change is a patch level or minor level modification depends on whether you updated your dependencies in order to fix a bug or introduce new functionality. We would usually expect additional code for the latter instance, in which case it’s obviously a minor level increment.
So from a semantic versioning viewpoint, it is fine if Plone 6 beta gets lots of major version upgrades of dependencies. This may not always be what we want though.
In the core development buildout I have split the versions into three files. This split is fairly recent, and Plone 6.0.0a6 is the first release that has this. I can imagine we do some structural changes still. Let me tackle this per file.
- These packages are what you get when installing Plone plus test dependencies.
- This starts with about 100 packages marked as core Plone. The above rules apply.
- For the other packages in here: minor upgrades are fine, major not. The release team can use its discretion to disallow a minor upgrade or allow a major upgrade.
- Packages in here should be kept during the 6.0 lifetime.
- These are often used modules and we want to have canonical versions of them, for example for tiles and
- As above, in general minor upgrades are fine, major not. We might be more lenient here though. Ecosystem packages may move faster.
- Packages in here should be kept during the 6.0 lifetime.
- This is for tools like
zest.releaserwhich are not used in a Plone instance. Some of these keep adding new dependencies, or removing old ones.
- Packages in here can receive new major versions, or be removed entirely without notice.
Note that we do not have control over how packages outside of core Plone are developed. Ideally each package is tested on all Python versions that we support, and the package version we use in 6.0.0 will be maintained for the next few years. In practice, we have no way of knowing. We can't even tell if all packages use semantic versioning, so a minor or major version increase might mean something completely different than we expect, and reading the changelog is not always enough.
- We will use Zope 5.x for the entire lifetime of Plone 6.0.
- The latest release is 5.5.2, but the Zope community will not create a 5.5.x maintenance branch for us for getting only bug fixes. So we will include minor version upgrades.
- Zope has a list of package versions and we extend this. So anything that they change, will be included in the Plone versions. Generally Zope updates to the latest versions compatible with the respective Python versions.
- We fully support Python 3.7, 3.8. and 3.9. These are all only getting security updates, no more bug fixes.
- Plone 6.0 supports Python 3.10, but there is some trouble getting it to run again on our testing machines, so this is still provisional. Locally I do core development on 3.10 though, so it should be fine.
- During the Plone 6.0 lifetime we may add support for newer Python versions.
- No Python version must be dropped in 6.0.
- One year from now, June 2023, the Python community stops supporting Python 3.7. At that point, Plone can and probably should decide to stop testing on this version. We must not deliberately remove support for it, introducing new syntax or using modules that only work on later versions. If possible, we could still check the syntax.
The same rules apply as for beta. I would probably be most strict in the release candidate stage: really only bug fixes, no dependency updates at all, except maybe a Zope bugfix.
Reactions are very welcome!