Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC] Versioning strategy #2858

Closed
flaviendelangle opened this issue Oct 13, 2021 · 17 comments
Closed

[RFC] Versioning strategy #2858

flaviendelangle opened this issue Oct 13, 2021 · 17 comments
Assignees
Labels
discussion RFC Request For Comments

Comments

@flaviendelangle
Copy link
Member

flaviendelangle commented Oct 13, 2021

Release schedule after the v5.0.0 stable version (final decision)

Once v5.0.0 is released, we will respect semver and do no breaking change until the release of v6.0.0-alpha.0.
The next features that don't require any breaking change will be release in minor versions 5.1, 5.2, ...
We will start the v6.0.0 alpha process when we will really have to do some breaking changes.

The v6.0.0 alpha process may occur before the @mui/material v6.0.0 alpha process.
We are willing to do more major version on the X packages if it allows us to build important features quicker. But with the current internals, we should be able to release the next big features (at least #210, #212, #193, #211) in v5.

Limit the surface of the public API

As of today, almost all our internal states / internal components / internal methods are somehow public because they are either exported (we export all our components) or exposed in props or callback (props.state and props.onStateChange on the DataGrid component)

To help building new advanced features with as little breaking change as possible, we will reduce the surface of our public API through several measures

Prefix all internal apiRef methods with UNSTABLE_

For instance apiRef.current.getLogger will become apiRef.current.UNSTABLE_getLogger.
Any method prefixed by UNSTABLE_ can be broken at any point and should be used with care.

Replace props.statewith props.initialState that only contains a subset of the state

More details on #2848
Any substate not listed in props.initialState can be broken at any point.
In most cases, you should not interact directly with the state but rather use a selector or an apiRef method (pro-plan only for now).

Stop exporting every component

The list is yet to be finalized but you can follow our discussion on this issue #2227 (comment).

Release schedule after the v5.0.0 stable version (outdated)

Our current release strategy is to do one minor version per week with a lot of breaking changes in them.
After the stable release, we will have to follow a clean breaking change policy. But we think that the surface of the public API makes it hard to have one major per year and not a single breaking change between them. We do not want to slow down the development of new feature too much and we need to find a good balance between breaking changes and feature development efficiency.

We discussed several options in today's meeting.
We think that these options make sense and that the most important point is to have a consistent schedule so that developers using the product can anticipate their migration.

Option 1 : More frequent major release than the core

  • One minor release with no breaking change once a week.
  • One major release when we need to do breaking changes (the frequency would probably be one every 4 months / 6 months for vert big features).

Option 2 : Minor version every week with small breaking changes and keep major releases in sync with the core

  • One minor release with small breaking changes once a week (only breaking changes with easy migration).
  • One major release at the same time as https://github.com/mui-org/material-ui (once every 12 months / 18 months), can contain important breaking changes.

Option 3 : Minor version every month with small breaking changes and keep major releases in sync with the core

  • One patch release with no breaking change and no feature once a week.
  • One minor release with small breaking changes once a month (only breaking changes with easy migration).
  • One major release at the same time as https://github.com/mui-org/material-ui (once every 12 months / 18 months), can contain important breaking changes.

Seems to be the approach of React Admin.

@flaviendelangle flaviendelangle added the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Oct 13, 2021
@flaviendelangle flaviendelangle self-assigned this Oct 13, 2021
@flaviendelangle flaviendelangle added discussion and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Oct 13, 2021
@DanailH
Copy link
Member

DanailH commented Oct 14, 2021

All looks good to me, as we discussed yesterday.

Regarding the release strategy, Option 3 makes the most sense, where after each minor release at the end of the month we merge the 'feature' branch back into next.

I would propose one more option:

Option 4: Go with the flow:

We work as we usually do and restrain ourselves from introducing truly breaking changes, we will need the self-disciple either way. When the time for a release comes each week we see what has been merged and if there is a feature we bump minor, if no features have been added then we bump the patch.

@oliviertassinari
Copy link
Member

oliviertassinari commented Oct 17, 2021

@flaviendelangle Thanks for the summary.

Prefix all internal apiRef methods with UNSTABLE_

I think that we should respect the capitalization in the context. For instance, we have Unstable_TrapFocus, React has ReactDOM.unstable_createRoot. So I would propose apiRef.current.unstable_getLogger in this example.

Limit the surface of the public API

These proposals make sense to me. I had the same thoughts as you when we introduced these public APIs a year ago.

Release schedule after the v5.0.0 stable version

  • Option 1: 🆗 This could work. We would need to add a compatibility table, easy.
  • Option 2: ⚠️ "Minor version every week with small breaking change" is not semver. If we make a breaking change, then we introduce an incompatibility, developers have to do extra work.

MAJOR version when you make incompatible API changes,

https://semver.org/. This would also go against the statement in https://mui.com/versions/#versioning-strategy where we say MUI follows semver. I think that Semver is only valuable because it creates a clear and shared signal on how easy/likely to work the upgrade is.

So at the end of the day, it seems to be about one question. Is it better to create our own versioning strategy to communicate which version X depends on the Core, or to go with something that asks to check the compatibility table?

From my perspective, the answer is easy, not it's not worth it. Developers that get started installs with @latest. They don't have to know about the compatibility table, no pain. Also, I don't buy that we will be able to teach most developers the custom versioning strategy. I expect that most developers will get confused about why it's breaking in a minor. We can do a poll on Twitter if we have a doubt

  • Option 3: ⚠️ Same as 2
  • Option 4: ⚠️ What's the difference with Option 1? It seems to be the same but with no breaking changes planned. Meaning, waiting for the BC pain to be strong to ask about doing one. I would personally prefer that we say every 6-months. Why? 1. to give visibility to the developers that it won't break tomorrow 2. so we don't wait 1 year for doing the BCs, that we unlock the innovations that are blocked by BCs as soon as we can.

On a different note, the methodology with the "MUI X Decision-making" meeting. I don't think that we should discuss topics that are not already discussed async. Why? Because if what we need is to prioritize 1-hour in our agenda to give feedback to peers, then we can create a personal event. We don't need to jump into a meeting :).

For instance, here, I think that a great workflow would have been:

  1. First we open this discussion
  2. We chat on it async, we can't find a decision
  3. Add it to the agenda of the event, ask everyone to read it before joining, make a decision during the event, share the outcome back here.

@alexfauquette
Copy link
Member

Realy clear summary 👍 For the part "Limit the surface of the public API" it makes sense to me.

In the beginning, I was in favor of Option 3, because I thought "only small breaking changes, dev can handle them". But I see two problems.

  • if you don't need the new feature, you tend to do not to upgrade to avoid the extra work. Up to the time you need a bug fix, and then you have to correct all the small breaking changes.
  • most of the time I read the doc in its latest version. If because I'm using version 5.4.0 which has breaking changes with examples on the doc in version 5.5.0, I will need some time before understanding the problem.

@DanailH
Copy link
Member

DanailH commented Oct 18, 2021

  • Option 4: ⚠️ What's the difference with Option 1? It seems to be the same but with no breaking changes planned. Meaning, waiting for the BC pain to be strong to ask about doing one. I would personally prefer that we say every 6-months. Why? 1. to give visibility to the developers that it won't break tomorrow 2. so we don't wait 1 year for doing the BCs, that we unlock the innovations that are blocked by BCs as soon as we can.

The main difference between this and Option 1 is that in this we keep the same major version as the core

Why do I think this is important?

  • I think it is really valuable to keep it very simple for developers which version of MUI-X is compatible with which version of the core. Sitting on different major versions will complicate things in the long run and we will potentially get a lot of questions regarding compatibility. It will also require, probably, to have a compatibility matrix, which IMO is not ideal.
  • Regarding the breaking changes - I still think we can do no breaking changes - once we make most of the API private and add a clear explanation in the docs about the state and the CSS classes that are not documented we should be ok. If we have to introduce a breaking change because of a feature it will force us to rethink the implementation twice before proceeding.

@flaviendelangle
Copy link
Member Author

flaviendelangle commented Oct 18, 2021

I think Option 2 is a bad idea because a potential breaking change every week, even small, feels very uncomfortable for our users. And like @alexfauquette, I fear that they will stop upgrading the library to save time.

My idea with Option 3 is to find a middle-ground with breaking change less frequent than Option 2 but more than the core.
Personnaly, I would go with Option 3 or Option 1.
The trade-off between the two is quite simple : do people prefer inconsistent versions between core and X or small breaking changes every month (or every 3 - 4 months, the frequency can be discussed of course).

Another option would be to avoid all breaking changes in the few following changes and to see in a few months if it seems realistic to do 0 breaking change during 12-18 months.
And if not, to decide which option we pick.
I'm am less optimistic than @DanailH on our capacity to do 0 breaking change during this amount of time. But it's based on a feeling, maybe it's worth taking the time to really try 0 breaking change.


I think that we should respect the capitalization in the context. For instance, we have Unstable_TrapFocus, React has ReactDOM.unstable_createRoot. So I would propose apiRef.current.unstable_getLogger in this example.

OK for me 👍

@m4theushw
Copy link
Member

Since we have to respect semver, the only option available is 1. We treat the X as a different set of packages, thrilling its own path. I think comparing it with the Core is not good, we don't have yet a stable codebase. If I was going to compare with something, I would use the lab. The lab is in alpha forever because it needs to move faster, like the X.

From https://semver.org/#if-even-the-tiniest-backwards-incompatible-changes-to-the-public-api-require-a-major-version-bump-wont-i-end-up-at-version-4200-very-rapidly

If even the tiniest backwards incompatible changes to the public API require a major version bump, won’t I end up at version 42.0.0 very rapidly?

This is a question of responsible development and foresight. Incompatible changes should not be introduced lightly to software that has a lot of dependent code. The cost that must be incurred to upgrade can be significant. Having to bump major versions to release incompatible changes means you’ll think through the impact of your changes, and evaluate the cost/benefit ratio involved.

We could try zero breaking changes. Looking at the last releases, the BC were only related to the export cleaning. We could stop this effort for now, release the stable version, bump to v6-alpha and continue the cleaning.

About the compatibility table, we could try to create one, but I don't know if we need one. If the Core doesn't make big changes again (e.g. a new styling solution), I think we will be able to keep supporting all versions.

@flaviendelangle
Copy link
Member Author

We could try zero breaking changes. Looking at the last releases, the BC were only related to the export cleaning. We could stop this effort for now, release the stable version, bump to v6-alpha and continue the cleaning.

If we want to show that we are entering a more mature phase, I can even stop the export cleaning for a few months so we have a few v5.X releases before restarting an alpha process.
To be able to release the Q4 releases in v5 and then start the v6 alpha process.

But if the team prefer to start the v6 alpha as soon as the v5 stable is released, that would also be fine for me.

For the compatibility table, we can wait to have a real case of incompatibility before creating one. I suppose before the v6 of the core, the only incompatibility is with core v4 and X v5+. It can be described in a sentence.

@m4theushw
Copy link
Member

m4theushw commented Oct 20, 2021

My proposal is the following:

  • We respect https://semver.org/
  • Once v5.0.0 is released, no more breaking changes until v6.0.0-alpha.0
  • Releases every week
  • New features that don't require BC are released in minor versions
  • Bug fixes are released in patch versions
  • Breaking changes are released in major versions

Do we have an agreement?

Looking at the core's v6 milestone, we MIGHT be able to sync the release. If not, we add the compatibility table.

What will happen once we add a second component? Should we release them first in a @mui/x-lab package to be able to do BC whenever we need?

@flaviendelangle
Copy link
Member Author

Do we have an agreement?

Yes
And I propose we create an issue or a milestone for v6 once v5 is stable, to list all the features that are breaking and waiting for v6.
So that we can discuss if they are solutions for implementing them in a non-breaking way and if not, if they are important enough to release a v6 sooner than the core.


For the new components, they will be in their own package @mui/x-date-picker-pro for instance no ?
So for me we just have to mention clearly in the doc that they are not stable and follow the lab nomenclature.

@m4theushw
Copy link
Member

For the new components, they will be in their own package @mui/x-date-picker-pro for instance no ?

Yes, true. So which version to start them? The same as the core? v1.0.0?

@flaviendelangle
Copy link
Member Author

I think @oliviertassinari was in favor of keeping the same version across all X components.
But that's a tradeoff, I don't have a clear opinion on it yet.

@oliviertassinari
Copy link
Member

oliviertassinari commented Oct 26, 2021

Do we have an agreement?

@m4theushw I have upvoted the comment 👍

I think @oliviertassinari was in favor of keeping the same version across all X components.

@flaviendelangle Correct. One of the value propositions of MUI is that we reduce the number of vendors that developers have to depend on: this is simpler. I believe using the same major version between all the X components would fall under the same spirit of simplicity when it comes the time to update. You can find the same approach in Kendo.

@flaviendelangle
Copy link
Member Author

flaviendelangle commented Oct 27, 2021

The whole team has now validated this versioning strategy.
So I think we are good for the following months, we will just have to make sure that it works correctly when launching the new components.

I will edit the first message with the accepted proposal.


Once v5.0.0 is released, we will respect semver and do no breaking change until the release of v6.0.0-alpha.0.
The next features that don't require any breaking change will be release in minor versions v5.1, v5.2, ...
We will start the v6.0.0 alpha process when we will really have to do some breaking changes.

The v6.0.0 alpha process may occur before the @mui/material v6.0.0 alpha process.
We are willing to do more major version on the X packages if it allows us to build important features quicker. But with the current internals, we should be able to release the next big features (at least #210, #212, #193, #211) in v5.

@oliviertassinari
Copy link
Member

There is a tradeoff on the release strategy that we took a long time ago, that I wonder if there are better alternatives. There are libraries that release once a month. The advantage for them is that they can market bigger changes. Their release is more worth celebrating. But they also significantly deffer the feedback loop on regressions they introduce.

@flaviendelangle
Copy link
Member Author

They do a minor release once a month ?
Do you have examples ?

Currently we do not have patch releases so it is very important to release often for the bugfixes. If we had minor release and patch release, I guess the minor release could be less frequent.
But I'm not sure it's an evolution we should be looking for right now.
Maybe once we have a Developer Advocate, we could make our versioning strategy evolve to be more optimized for blog posts like NextJS does for instance.

@oliviertassinari
Copy link
Member

oliviertassinari commented Oct 27, 2021

Yeah, I'm going off-topic. I think that you got my point, we can stop the discussion here and resume it with the dev rel. For the examples, we can look at VSCode, React, Bootstrap, Next.js, Ant Design it's never really clear what they do.

Should we close this issue?

@flaviendelangle
Copy link
Member Author

I'm closing it yes

@oliviertassinari oliviertassinari added the RFC Request For Comments label Aug 12, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion RFC Request For Comments
Projects
None yet
Development

No branches or pull requests

5 participants