RFC: Experimental feature flags
See original GitHub issueVolto development has gone at a fast pace while Volto 16 was in the alpha stage. Now that we’re ready to release Plone 6, we need to make a stable release of Volto 16 and start to be much more careful about making breaking changes, so that organizations that have built sites with Plone do not get a bad impression of its stability. At the same time, we have lots of good ideas and don’t want to prevent moving forward. This is a proposal about how to balance these concerns, for the Volto team to discuss.
One way to do this is to create a maintenance branch for Volto 16. Then we can add new features on the main branch and only backport the fixes to the 16 branch. But, this way has some problems:
- It’s a lot of work for the release manager and difficult to make sure we backport every fix.
- It’s not very flexible. If I’m building a site with Plone, I can choose to have stability or to have new features, but there’s no in between. I can’t opt in to one particular feature that I really need but wait to add others until they are proven.
- If I’m a developer working with a client that has chosen to go with the stable release, then I am incentivized to implement new features as addons rather than adding them to core, because I can’t add them to the stable branch. That’s not necessarily a problem, but sometimes it requires extensive customizations of core Volto components which can be hard to maintain. And it means the work has to be redone (to some extent) if the community decides the feature belongs in core (e.g. volto-slate).
As an alternative, I’d like to explore using experimental feature flags. This is something you may have seen in other large software projects like Firefox, Chrome, and Kubernetes. The idea is that we add conditional logic to enable a new feature based on a config setting. There would be a section of the config that looks like this:
config.experimental = {
featureName: {
enabled: false,
},
};
A particular volto app or addon could opt in to enabling the feature like this:
config.experimental.featureName.enabled = true;
How is this different from an add-on? Experimental features are changing how Volto’s core components work, rather than adding or overriding components. How is this different from a config setting? Experimental features are intended to become the new default behavior in the future, rather than a permanent choice.
A feature is a candidate for experimental status if there is already broad agreement in the community that we want it in core, but:
- it’s a breaking change that we don’t want to force on existing projects immediately
- OR we want a chance to test it in production before committing to it 100%
The context for why I’m thinking about this is that I’d like to implement the new add block button (#3815) as an experimental feature. There are 2 reasons:
- It’s time for a Plone 6 release candidate but the new add block button implementation is not ready to merge. I probably need another week or two to finish it. Implementing it as an experimental feature ensures we can make it available as soon as possible even if it doesn’t make the cut for Plone 6 release candidates.
- kitconcept likes the new add block button in general, but we have a big project that is nearing completion and we can’t easily change how the add button works at this stage in the project. Implementing it as an experimental feature provides a way to make it easily available for new projects but keep it disabled for projects that have been underway for a while.
Rules for experimental features:
- Experimental feature flags are meant to be a temporary solution for features that are on a trajectory to being on by default. If a feature should always remain optional, then it belongs as a config setting or an add-on rather than an experimental feature.
- New experimental features can be added when agreed in the volto team meeting. There needs to be broad agreement that the feature is desired as a default core feature in the future. If not, maybe it works better as an addon.
- New experimental features are disabled by default, so they are not a breaking change and can be added in a minor release.
- The implementation should include tests both with the feature disabled and enabled.
- In a major release of volto, there are several possibilities for what to do with existing experimental features, depending on what level of confidence has been achieved that it is the correct path forward:
- we’re sure we like it -> remove the conditionals and turn it into a normal, non-experimental feature
- we’re pretty sure we like it -> switch the feature to be enabled by default, but keep the conditionals so there is still a way to disable it
- we’re still not sure -> keep it as an experimental feature that is disabled by default
- it didn’t work out -> remove the feature
What are the downsides?
- There’s a bit more effort to develop an experimental feature, because of needing to keep it working 2 different ways. (But, overall this is better than the maintenance branch approach, because the extra work is only needed for some features, not all bugfixes.)
- It adds a bit to the size of the codebase. (This is why it’s important that experimental features are temporary.)
- Maybe a bit more complexity, but of course the goal is to have good defaults so that you don’t need to think about experimental features unless you’re following Volto development closely and in a hurry to get something new.
- There’s a risk that a feature doesn’t work out but someone is depending on it. Then what do we do? (But, I would argue that’s already a risk, and this proposal gives a better chance of finding that out before everyone is depending on it.)
What are the upsides?
- Better control over the amount of risk a project takes on when it needs to try a new feature
- There is a way to implement a new feature for a client even if they want stability in other features.
Issue Analytics
- State:
- Created 10 months ago
- Comments:8 (7 by maintainers)
then we don’t care how big it is, as it won’t impact client-side.
I’m +1 for this.
Regarding the lazy loading, might be hard, because the feature (eg. the new add button placement in #3815) could be entangled with the current behavior. Although I agree that whenever possible, we should make this happen.
Also in the same direction, we are pushing for having permanent “core” integrated add-ons. Following the ‘volto-slate’ integration now we are able to add them at will.
https://6.dev-docs.plone.org/volto/developer-guidelines/volto-core-addons.html
And the use case: https://github.com/plone/volto/pull/3877
I can imagine experimental features in the form of add-ons (even with customizations) that at some point get into core (or stay as core add-ons)