From dedb0c978f791497e6bed7c0902ee692dd8d4514 Mon Sep 17 00:00:00 2001 From: Chris Krycho Date: Tue, 12 Jul 2022 08:45:03 -0600 Subject: [PATCH 1/5] RFC: Evolving Ember's Major Version Process --- ...0-evolving-embers-major-version-process.md | 273 ++++++++++++++++++ 1 file changed, 273 insertions(+) create mode 100644 text/0830-evolving-embers-major-version-process.md diff --git a/text/0830-evolving-embers-major-version-process.md b/text/0830-evolving-embers-major-version-process.md new file mode 100644 index 0000000000..4bf1574425 --- /dev/null +++ b/text/0830-evolving-embers-major-version-process.md @@ -0,0 +1,273 @@ +--- +Stage: Accepted +Start Date: 2022-07-12 +Release Date: Unreleased +Release Versions: + ember-source: vX.Y.Z + ember-data: vX.Y.Z +Relevant Team(s): "Steering, Ember.js, Learning" +RFC PR: https://github.com/emberjs/rfcs/pull/830 +--- + +# Evolving Ember's Major Version Process + +## Summary + +Introduce a standard release train for *major* releases, analogous to Ember's release train for minor releases: + +- After every `X.8` minor release, Ember will ship a new major, `(X+1).0`, which removes any deprecated code targeted for that major release. +- Deprecations targeting the next major cannot be introduced later than the `X.7` release. +- There will be a planned 12 week cycle for the transition between an `X.8` and an `(X+1).0` release to allow for stabilizing the `X.*` LTS release while working on the `(X+1).0` release. + +**The result is a steady 60-week cadence between Ember major releases, complementing our steady 6-week cadence between Ember minor releases.** + +
How this would work in practice for Ember's lifecycle from 4.8 to 7.0 + +| Ember Release | Approximate date | +| ------------- | ---------------------- | +| 4.8 | mid October 2022 | +| 4.8 LTS | late November 2022 | +| **5.0** | **early January 2023** | +| 5.4 | late June 2023 | +| 5.4 LTS | early August 2023 | +| 5.8 | early December 2023 | +| 5.8 LTS | late January 2024 | +| **6.0** | **early March 2024** | +| 6.4 | mid August 2024 | +| 6.4 LTS | late September 2024 | +| 6.8 | early February 2025 | +| 6.8 LTS | mid March 2025 | +| **7.0** | **late April 2025** | + +
+ + +### Note + +There are two related considerations in this space: + +- How does this relate to the lockstep versioning policy Ember, Ember CLI, and Ember Data have historically followed? +- What do we expect the timing of Ember Polaris to be relative to this cadence? More generally, exactly how should Editions relate to major releases? + +However, those questions are orthogonal to this proposal: we can maintain lockstep, or not, with a standard cadence for major releases; and we can also decide whether (and if so, how) to align editions with major releases whatever cadence majors come on. + + +### Outline + +- [Motivation](#motivation) +- [Detailed design](#detailed-design) + - [Freeze deprecations at `X.7`](#freeze-deprecations-at-x7) + - [Formalize a 12-week gap between `X.8` and `(X+1).0`](#formalize-a-12-week-gap-between-x8-and-x10) + - [Bootstrap with Ember v5](#bootstrap-with-ember-v5) + - [Ember v5 deprecations](#ember-v5-deprecations) + - [Ember CLI v5 deprecations](#ember-cli-v5-deprecations) + - [Ember Data v5 deprecations](#ember-data-v5-deprecations) + - [Prior art](#prior-art) +- [How we teach this](#how-we-teach-this) + - [Publicize the change](#publicize-the-change) + - [Website 'Releases' page](#website-releases-page) +- [Drawbacks](#drawbacks) +- [Alternatives](#alternatives) + - [No change](#no-change) + - [Pick a different cadence](#pick-a-different-cadence) + - [Different point for freezing deprecations](#different-point-for-freezing-deprecations) +- [Unresolved Questions](#unresolved-questions) + + +## Motivation + +Ember's approach to release versioning has served us well for the last seven years. We target minor releases every six weeks, and then do a major release to remove deprecated code on some long interval. Major releases being rare has been an explicit goal. Per [the Releases page][releases-current]: + +> You might notice that although Ember has been around for a long time, it's version number is low. +> That is because Ember aims to ship new features in minor releases, and make + major releases as rare as possible. +> When you see a library or framework that has many major versions, each one of those numbers + represents a "breaking change." +> Breaking changes force development teams to spend time researching + the changes and modifing their codebase before they can upgrade. +> The bigger the codebase, or the more complex the app, the more time and effort it takes. +> Ember is committed to providing a better experience than that. + +[releases-current]: https://github.com/ember-learn/ember-website/blob/a7a4191dc76170c855c9a0e93108c75456cdc554/app/templates/releases/index.hbs#L74-L84 + +The result is a steadily increasing time between major releases:[^pandemic] + +| Transition | Time | Start of major | Start of next major | +| ---------- | --------- | ----------------- | ------------------- | +| 1.0 → 2.0 | 2 years | August 13, 2013 | August 13, 2015 | +| 2.0 → 3.0 | ~2½ years | August 13, 2015 | February 14, 2018 | +| 3.0 → 4.0 | ~4 years | February 14, 2018 | December 20, 2021 | + +This is as we would expect given the explicit goal to "make major releases as rare as possible", especially given how the framework has matured such that it has not *needed* breaking changes as often. However, this policy of minimizing the number of major releases has actually tended over time to make major upgrades *more* rather than less painful—for both Ember users and Ember maintainers.[^maintainers] + +- **For users:** Since each release major release comes after a longer period of time, it includes more deprecations to remove. This means that while the major releases may be more rare, they actually become *harder* over time. They also are not predictable, and therefore are difficult to account for in planning—unlike minor and LTS releases, which are *very* predictable! + +- **For maintainers:** There is planning and coordination required for a major release, as well as a great deal of removal of deprecated code. This currently happens on an _ad hoc_ basis when the Framework team decides it is time. However, that means that the amount of planning work can grow very large, and the amount of work involved in removing deprecated code can be more or less unbounded. This is hard! + +Switching to a predictable cadence will address both of these problems. In particular, it means that a deprecation targeting a given release will come with an expected *timeline*. Seeing that a deprecation targets v6 will tell someone that it will be removed in roughly March 2024, with the first LTS release in August 2024. That is incredibly valuable for medium- and long-term planning. + +Additionally, removing deprecated code regularly decreases the surface area of the framework. This has a number of benefits: + +- The API surface area is smaller, making it easier for users to know what they should use and what they should not. + +- There is less code shipped in a bundle (though we also plan to address this by making Ember fully tree-shake-able and implementing "deprecation shaking"). + +- Introducing new features and fixing bugs are both easier, because there are fewer legacy interactions to account for over time. + +- Related, new contributors can onboard more easily, because there are fewer crufty old parts of the code base to understand. + +Finally, doing releases on a predictable cadence/release train also has the same effect on *major* releases that it does on *minor* releases: it decreases the pressure to get deprecations in before a major release, because there will always be another major release—and it won't be that long! It also means that the "freeze" period doesn't become a worry: it only freezes deprecations targeting the *next* major. This also enables longer-targeted deprecations where it makes sense. + +For example: imagine a deprecation of some major piece of Ember landing early in 5.x (maybe deprecating the classic router in favor of some hypothetical new router design). Knowing the release cadence means that can *intentionally* target removal in 7.0 instead of 6.0. This will allow the deprecation to do its work as a messaging signal ("Don't use this in new code, and start migrating to the new thing"), while also providing a predictable and *long-term* schedule for its removal. + + +[^pandemic]: Even granting that the pandemic likely increased the time between 3.0 and 4.0 somewhat, we would likely have had *at least* a 2½–3-year gap between those releases. + +[^maintainers]: We always prioritize users over maintainers if there is a hard choice between the two, but we also care about the long-term sustainability of the project. Things that make maintainers' lives hard decrease the sustainability of the project over time! + + +## Detailed design + + +### Freeze deprecations at `X.7` + +One of the major things we learned from the 1.13 → 2.0 transition was that having too many deprecations piled up at the end of a major release can *feel* like it violates Ember's commitment to "stability without stagnation". Since then, we have frozen deprecations targeting the next major release late in the previous major release cycle. However, there have been two ongoing issues with this: + +- Users have not known *when* that freeze would come. This made it difficult to know when to target a deprecation, or whether a deprecation was valuable at a given point in time, since it wasn't clear when the next major would even be. + +- There has been a tendency to rush to get in deprecations in the period just before the freeze (in large part because major releases have been unpredictable: if you don't get it in *now*, it may be *years* before the deprecation takes effect!), which again undermines. + +Given a known major release cadence, we can explicitly target a specific release as the last allowed time to target a given major. However, we can *also* keep landing deprecations past that freeze: they just have to target the next major. You could, for example, land a deprecation in 4.8 targeting 6.0, or even 7.0! + + +### Formalize a 12-week gap between `X.8` and `(X+1).0` + +Major releases have sometimes taken longer than the targeted 6-week cadence to release. For example, there was an 8 week gap between 1.13 and 2.0, a 6 week gap between 2.18 and 3.0, and a 14-week gap between the releases of Ember 3.28 and Ember 4.0. We should embrace the that a major release is likely to be more work than a normal minor release, and make it *easy* to hit the cadence. + +Accordingly, introduce an extra 6-week buffer for the major release. This also has the happy effect of making the release cadence super easy to explain and remember: 6 weeks between minor releases, 60 weeks between major releases. + + +### Bootstrap with Ember v5 + +When Ember adopted its 6-week "release train" cadence for minor releases, it used the 1.1 release to "bootstrap" the process and help the team learn how to do it, identify gaps, etc., with no features added. We should do the same here with 5.0. There are *very* few deprecations currently targeting Ember v5, so we can use this in a similar way. + + +#### Ember v5 deprecations + +- [`Ember.assign`](https://deprecations.emberjs.com/v4.x#toc_ember-polyfills-deprecate-assign), replaced by `Object.assign` or object spread +- [implicit injections](https://deprecations.emberjs.com/v4.x#toc_implicit-injections) (already a no-op and do nothing, and just need to be removed) +- [AutoLocation class](https://deprecations.emberjs.com/v4.x#toc_deprecate-auto-location), switching to explicitly using `'history'` or `'hash'` as appropriate + + +#### Ember CLI v5 deprecations + +- removal of Bower (via a number of separate feature deprecations) +- deprecate "blacklist" and "whitelist" build options + + +#### Ember Data v5 deprecations + +N/A: none exist at the time of authoring. + + +### Prior art + +- Angular uses a six-month cadence for major releases, with every other major release (the even-numbered releases) being an LTS release. + +- Node uses a six-month cadence for major releases, with every other major release (the even-numbered releases) being an LTS release. + +- TypeScript uses a quarterly release cadence, and releases a "major" once they hit the `X.9` release. Notably, they do not use SemVer, so this is not a particularly relevant comparison for *how* we approach this. It is relevant mostly by way of providing another example of a standard cadence for releases. + + +## How we teach this + +### Publicize the change + +When this RFC is accepted, we will publish a blog post to the Ember.js blog, tweet about it from the official account, and post the update to the official Discord and Discourse instances. We may also consider publishing in other media about it (e.g. publishing a dedicated video to the Ember Videos channel on YouTube). + +Additionally, when we release the final minor version of the 4.x series and again when we release 5.0, we should explicitly describe the updated policy. This is similar to how Ember approached the introduction of the "release train" with 1.x and the messaging around major releases at the 2.0 release. + + +### Website 'Releases' page + +Update the **Our Goals** section: + +- Update this bullet point to include major releases: + + > - Make a minor release about every six weeks, so teams that use Ember can plan their work + + Updated: + + > - Make a minor release about every six weeks and a major release about every sixty weeks, so teams that use Ember can plan their work + +- Wholly reframe this bullet point: + + > - Only cut a new major version (i.e. make a breaking change) when we really, really have to + + Instead of focusing on duration, emphasize that we don't make breaking changes lightly: + + > - Only make breaking changes when we really, really have to + +Update the **How Ember uses SemVer** section to clarify that we want to make breaking changes both rare *and predictable* and therefore manageable. We should also take this as an opportunity to clarify how we use major releases and editions. + +The previous text: + +> You might notice that although Ember has been around for a long time, it's version number is low. That is because Ember aims to ship new features in minor releases, and make major releases as rare as possible. When you see a library or framework that has many major versions, each one of those numbers represents a "breaking change." Breaking changes force development teams to spend time researching the changes and modifing their codebase before they can upgrade. The bigger the codebase, or the more complex the app, the more time and effort it takes. Ember is committed to providing a better experience than that. + +Updated: + +> Ember aims to ship new features in minor releases, to make breaking changes rare, and to make major releases predictable. Breaking changes force development teams to spend time researching the changes and modifing their codebase before they can upgrade. The bigger the codebase, or the more complex the app, the more time and effort it takes. Ember is committed to providing a better experience than that: +> +> 1. **We never couple the addition of new features to breaking changes.** Instead, we introduce a new feature to replace an existing feature, provide a migration path, then sometime later deprecate the old feature, and finally remove the old feature in a later major release. +> +> 2. **Ember major versions only remove deprecated features. They never introduce new features.** This means major releases are not exciting, just a predictable point where some cleanup happens. +> +> 3. **Ember's big releases are "Editions.** An Edition lands in a minor release and is therefore always backwards compatible. It represents the point where all the features we shipped in minor releases are polished, well-documented, and recommended for everyone to use. [Read more here.](https://emberjs.com/editions/) + + +## Drawbacks + +- We must use this as a way of *getting better* at doing major releases. As we have done them to date, this would be incredibly stressful. + +- If we land too many large deprecations in a major release, it will still cause painful churn for both users and maintainers. + +- If we do not communicate clearly about this, it could surprise or confuse both existing and potential new Ember users. + + +## Alternatives + + +### No change + +Keep our existing approach, releasing new majors rarely. Focus *all* of our efforts on "deprecation shaking." That solves two parts of the motivation: allowing users not to pay for deprecated code in their bundle which they aren't using, and allowing Ember to signal clearly that users *should* stop using a given pattern. The rest of the motivation would be unaddressed, though. + + +### Pick a different cadence + +We could adopt a time-based cadence: the proposed 60-week cadence takes just *over* a year, so the cycle drifts through following years, and does not align *especially* well with most teams' planning processes. Aligning major releases to something which predictably fits year or quarter boundaries could be helpful. + +- **Annual:** This would involve doing a major release just 4 weeks after the `X.8` release, which is a very compressed timeline, so we might need to instead target `X.7` as an LTS, followed by a 10-week cycle for the major release. Alternatively, we could shift to 8-week release cycles and update our LTS cadence accordingly. + +- **18- or 24-month cycles:** the same basic idea as an annual cycle, just longer. Similar issues apply for aligning the timing (though see below). + +Both of those have the downside of requiring *additional* changes to our existing process and communications. + +We could also keep the idea of this RFC, but pick a longer cadence: + +- **11 minor releases:** This would see us do e.g. 4.8 LTS, 4.11 LTS, 5.0, etc. This would make the release cycle just a bit longer, and slot in at *exactly* an 18-month cadence if we kept the extra long (12-week) cycle for a major. + +- **12 minor releases:** This is the other way of getting to an 18-month cadence for major releases, *if* we maintain the requirement that there be only 6 weeks between releases. (Keeping it to only six weeks may be easier than it was for e.g. 3.28 → 4.0, given a predictable *and* a shorter release cadence.) + +- **an even longer cycle:** 16 minor releases, 24 minor releases, etc. That would still make the releases *predictable*, but we would still pile up deprecations for longer, and the work for both users and maintainers at the release cycle would still be higher. Additionally, we know from experience in software in general (especially around "devops") that the longer the cycles involved in any given process, the harder they tend to be. A higher cadence for releases actually tends to be *easier*. + +That might suggest picking an even shorter cadence: new majors after every LTS release, e.g. 5.0, 5.4 LTS, 6.0, etc. That *would* help with the planning and we would get quite good at the process. There is also precedent, in that this is how both Angular and Node work. However, Angular and Node also *constantly* have LTS releases in active support across major releases, which ups the maintenance burden significantly. Picking a timeline of approximately a year (2 LTS releases) seems to best balance these tradeoffs. + + +### Different point for freezing deprecations + +The `X.7` release is chosen as a point late in the cycle, and matches the point we have frozen deprecations relative to the next major in the pas. It is also relatively arbitrary, though! By taking the pressure off of any given major release, it's also less important. Our only *hard* constraint is that new deprecations targeting the next major not be introduced in the final LTS, so we could equally well choose `X.6`. And of course, if we picked a different cadence, we would pick a different value here as well. + + +## Unresolved Questions + +- Given the intent to use Ember v5 for a "bootstrapping" process, should we freeze targeting deprecations for it early (say, as soon as this RFC is merged), to avoid making it more painful? From 7d44fd7c7b77de8e8e78d18d9670e1f696f19084 Mon Sep 17 00:00:00 2001 From: Chris Krycho Date: Tue, 12 Jul 2022 08:54:20 -0600 Subject: [PATCH 2/5] No needless
--- text/0830-evolving-embers-major-version-process.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/text/0830-evolving-embers-major-version-process.md b/text/0830-evolving-embers-major-version-process.md index 4bf1574425..d97e5f805f 100644 --- a/text/0830-evolving-embers-major-version-process.md +++ b/text/0830-evolving-embers-major-version-process.md @@ -21,7 +21,7 @@ Introduce a standard release train for *major* releases, analogous to Ember's re **The result is a steady 60-week cadence between Ember major releases, complementing our steady 6-week cadence between Ember minor releases.** -
How this would work in practice for Ember's lifecycle from 4.8 to 7.0 +How this would work in practice for Ember's lifecycle from 4.8 to 7.0 | Ember Release | Approximate date | | ------------- | ---------------------- | @@ -39,8 +39,6 @@ Introduce a standard release train for *major* releases, analogous to Ember's re | 6.8 LTS | mid March 2025 | | **7.0** | **late April 2025** | -
- ### Note From c6eaf4393d20351eb086db7d1f00b49efa0d11af Mon Sep 17 00:00:00 2001 From: Chris Krycho Date: Mon, 15 Aug 2022 09:45:57 -0600 Subject: [PATCH 3/5] Use an 18-month cadence instead - drop the extra long upgrade cycle - set final introduction of deprecations to M.10 - use `M.` instead of `X.` for 'Major' --- ...0-evolving-embers-major-version-process.md | 104 ++++++------------ 1 file changed, 32 insertions(+), 72 deletions(-) diff --git a/text/0830-evolving-embers-major-version-process.md b/text/0830-evolving-embers-major-version-process.md index d97e5f805f..491d3745fd 100644 --- a/text/0830-evolving-embers-major-version-process.md +++ b/text/0830-evolving-embers-major-version-process.md @@ -15,29 +15,26 @@ RFC PR: https://github.com/emberjs/rfcs/pull/830 Introduce a standard release train for *major* releases, analogous to Ember's release train for minor releases: -- After every `X.8` minor release, Ember will ship a new major, `(X+1).0`, which removes any deprecated code targeted for that major release. -- Deprecations targeting the next major cannot be introduced later than the `X.7` release. -- There will be a planned 12 week cycle for the transition between an `X.8` and an `(X+1).0` release to allow for stabilizing the `X.*` LTS release while working on the `(X+1).0` release. +- After every `M.12` minor release, Ember will ship a new major, `(M+1).0`, which removes any deprecated code targeted for that major release. +- Deprecations targeting the next major cannot be introduced later than the `M.10` release. -**The result is a steady 60-week cadence between Ember major releases, complementing our steady 6-week cadence between Ember minor releases.** +**The result is a steady 18-month cadence between Ember major releases, complementing our steady 6-week cadence between Ember minor releases.** How this would work in practice for Ember's lifecycle from 4.8 to 7.0 -| Ember Release | Approximate date | -| ------------- | ---------------------- | -| 4.8 | mid October 2022 | -| 4.8 LTS | late November 2022 | -| **5.0** | **early January 2023** | -| 5.4 | late June 2023 | -| 5.4 LTS | early August 2023 | -| 5.8 | early December 2023 | -| 5.8 LTS | late January 2024 | -| **6.0** | **early March 2024** | -| 6.4 | mid August 2024 | -| 6.4 LTS | late September 2024 | -| 6.8 | early February 2025 | -| 6.8 LTS | mid March 2025 | -| **7.0** | **late April 2025** | +| Ember Release | Release date | LTS date | +| ------------- | ----------------- | ------------- | +| 4.8 | October 2022 | November 2022 | +| 4.12 | April 2023 | May 2023 | +| **5.0** | **May 2023** | | +| 5.4 | October 2023 | December 2023 | +| 5.8 | April 2024 | May 2024 | +| 5.12 | September 2024 | November 2024 | +| **6.0** | **November 2024** | | +| 6.4 | April 2025 | May 2024 | +| 6.8 | October 2025 | November 2025 | +| 6.12 | March 2026 | May 2026 | +| **7.0** | **May 2026** | | ### Note @@ -54,12 +51,8 @@ However, those questions are orthogonal to this proposal: we can maintain lockst - [Motivation](#motivation) - [Detailed design](#detailed-design) - - [Freeze deprecations at `X.7`](#freeze-deprecations-at-x7) - - [Formalize a 12-week gap between `X.8` and `(X+1).0`](#formalize-a-12-week-gap-between-x8-and-x10) - - [Bootstrap with Ember v5](#bootstrap-with-ember-v5) - - [Ember v5 deprecations](#ember-v5-deprecations) - - [Ember CLI v5 deprecations](#ember-cli-v5-deprecations) - - [Ember Data v5 deprecations](#ember-data-v5-deprecations) + - [Freeze deprecations at `M.10`](#freeze-deprecations-at-m10) + - [Bootstrap with Ember v5.0](#bootstrap-with-ember-v50) - [Prior art](#prior-art) - [How we teach this](#how-we-teach-this) - [Publicize the change](#publicize-the-change) @@ -127,7 +120,7 @@ For example: imagine a deprecation of some major piece of Ember landing early in ## Detailed design -### Freeze deprecations at `X.7` +### Freeze deprecations at `M.10` One of the major things we learned from the 1.13 → 2.0 transition was that having too many deprecations piled up at the end of a major release can *feel* like it violates Ember's commitment to "stability without stagnation". Since then, we have frozen deprecations targeting the next major release late in the previous major release cycle. However, there have been two ongoing issues with this: @@ -135,37 +128,12 @@ One of the major things we learned from the 1.13 → 2.0 transition was that hav - There has been a tendency to rush to get in deprecations in the period just before the freeze (in large part because major releases have been unpredictable: if you don't get it in *now*, it may be *years* before the deprecation takes effect!), which again undermines. -Given a known major release cadence, we can explicitly target a specific release as the last allowed time to target a given major. However, we can *also* keep landing deprecations past that freeze: they just have to target the next major. You could, for example, land a deprecation in 4.8 targeting 6.0, or even 7.0! +Given a known major release cadence, we can explicitly target a specific release as the last allowed time to target a given major. However, we can *also* keep landing deprecations past that freeze: they just have to target the next major. You could, for example, land a deprecation in 4.11 targeting 6.0, or even 7.0! -### Formalize a 12-week gap between `X.8` and `(X+1).0` +### Bootstrap with Ember v5.0 -Major releases have sometimes taken longer than the targeted 6-week cadence to release. For example, there was an 8 week gap between 1.13 and 2.0, a 6 week gap between 2.18 and 3.0, and a 14-week gap between the releases of Ember 3.28 and Ember 4.0. We should embrace the that a major release is likely to be more work than a normal minor release, and make it *easy* to hit the cadence. - -Accordingly, introduce an extra 6-week buffer for the major release. This also has the happy effect of making the release cadence super easy to explain and remember: 6 weeks between minor releases, 60 weeks between major releases. - - -### Bootstrap with Ember v5 - -When Ember adopted its 6-week "release train" cadence for minor releases, it used the 1.1 release to "bootstrap" the process and help the team learn how to do it, identify gaps, etc., with no features added. We should do the same here with 5.0. There are *very* few deprecations currently targeting Ember v5, so we can use this in a similar way. - - -#### Ember v5 deprecations - -- [`Ember.assign`](https://deprecations.emberjs.com/v4.x#toc_ember-polyfills-deprecate-assign), replaced by `Object.assign` or object spread -- [implicit injections](https://deprecations.emberjs.com/v4.x#toc_implicit-injections) (already a no-op and do nothing, and just need to be removed) -- [AutoLocation class](https://deprecations.emberjs.com/v4.x#toc_deprecate-auto-location), switching to explicitly using `'history'` or `'hash'` as appropriate - - -#### Ember CLI v5 deprecations - -- removal of Bower (via a number of separate feature deprecations) -- deprecate "blacklist" and "whitelist" build options - - -#### Ember Data v5 deprecations - -N/A: none exist at the time of authoring. +When Ember adopted its 6-week "release train" cadence for minor releases, it used the 1.1 release to "bootstrap" the process and help the team learn how to do it, identify gaps, etc., with no features added. We should do the same here with 5.0. ### Prior art @@ -174,7 +142,7 @@ N/A: none exist at the time of authoring. - Node uses a six-month cadence for major releases, with every other major release (the even-numbered releases) being an LTS release. -- TypeScript uses a quarterly release cadence, and releases a "major" once they hit the `X.9` release. Notably, they do not use SemVer, so this is not a particularly relevant comparison for *how* we approach this. It is relevant mostly by way of providing another example of a standard cadence for releases. +- TypeScript uses a quarterly release cadence, and releases a "major" once they hit the `M.9` release. Notably, they do not use SemVer, so this is not a particularly relevant comparison for *how* we approach this. It is relevant mostly by way of providing another example of a standard cadence for releases. ## How we teach this @@ -196,7 +164,7 @@ Update the **Our Goals** section: Updated: - > - Make a minor release about every six weeks and a major release about every sixty weeks, so teams that use Ember can plan their work + > - Make a minor release about every six weeks and a major release about every eighteen months, so teams that use Ember can plan their work - Wholly reframe this bullet point: @@ -210,17 +178,17 @@ Update the **How Ember uses SemVer** section to clarify that we want to make bre The previous text: -> You might notice that although Ember has been around for a long time, it's version number is low. That is because Ember aims to ship new features in minor releases, and make major releases as rare as possible. When you see a library or framework that has many major versions, each one of those numbers represents a "breaking change." Breaking changes force development teams to spend time researching the changes and modifing their codebase before they can upgrade. The bigger the codebase, or the more complex the app, the more time and effort it takes. Ember is committed to providing a better experience than that. +> You might notice that although Ember has been around for a long time, it's version number is low. That is because Ember aims to ship new features in minor releases, and make major releases as rare as possible. When you see a library or framework that has many major versions, each one of those numbers represents a "breaking change." Breaking changes force development teams to spend time researching the changes and modifying their codebase before they can upgrade. The bigger the codebase, or the more complex the app, the more time and effort it takes. Ember is committed to providing a better experience than that. Updated: -> Ember aims to ship new features in minor releases, to make breaking changes rare, and to make major releases predictable. Breaking changes force development teams to spend time researching the changes and modifing their codebase before they can upgrade. The bigger the codebase, or the more complex the app, the more time and effort it takes. Ember is committed to providing a better experience than that: +> Ember aims to ship new features in minor releases, to make breaking changes rare, and to make major releases predictable. Breaking changes force development teams to spend time researching the changes and modifying their codebase before they can upgrade. The bigger the codebase, or the more complex the app, the more time and effort it takes. Ember is committed to providing a better experience than that: > > 1. **We never couple the addition of new features to breaking changes.** Instead, we introduce a new feature to replace an existing feature, provide a migration path, then sometime later deprecate the old feature, and finally remove the old feature in a later major release. > > 2. **Ember major versions only remove deprecated features. They never introduce new features.** This means major releases are not exciting, just a predictable point where some cleanup happens. > -> 3. **Ember's big releases are "Editions.** An Edition lands in a minor release and is therefore always backwards compatible. It represents the point where all the features we shipped in minor releases are polished, well-documented, and recommended for everyone to use. [Read more here.](https://emberjs.com/editions/) +> 3. **Ember's big releases are *Editions*.** An Edition lands in a minor release and is therefore always backwards compatible. It represents the point where all the features we shipped in minor releases are polished, well-documented, and recommended for everyone to use. [Read more here.](https://emberjs.com/editions/) ## Drawbacks @@ -242,28 +210,20 @@ Keep our existing approach, releasing new majors rarely. Focus *all* of our effo ### Pick a different cadence -We could adopt a time-based cadence: the proposed 60-week cadence takes just *over* a year, so the cycle drifts through following years, and does not align *especially* well with most teams' planning processes. Aligning major releases to something which predictably fits year or quarter boundaries could be helpful. - -- **Annual:** This would involve doing a major release just 4 weeks after the `X.8` release, which is a very compressed timeline, so we might need to instead target `X.7` as an LTS, followed by a 10-week cycle for the major release. Alternatively, we could shift to 8-week release cycles and update our LTS cadence accordingly. - -- **18- or 24-month cycles:** the same basic idea as an annual cycle, just longer. Similar issues apply for aligning the timing (though see below). - -Both of those have the downside of requiring *additional* changes to our existing process and communications. - -We could also keep the idea of this RFC, but pick a longer cadence: +We could adopt a different time-based cadence: -- **11 minor releases:** This would see us do e.g. 4.8 LTS, 4.11 LTS, 5.0, etc. This would make the release cycle just a bit longer, and slot in at *exactly* an 18-month cadence if we kept the extra long (12-week) cycle for a major. +- This RFC originally proposed a **60-week cadence**, including the idea of an extra-long cycle for doing the major release. -- **12 minor releases:** This is the other way of getting to an 18-month cadence for major releases, *if* we maintain the requirement that there be only 6 weeks between releases. (Keeping it to only six weeks may be easier than it was for e.g. 3.28 → 4.0, given a predictable *and* a shorter release cadence.) +**Annual:** This would involve doing a major release just 4 weeks after the `M.8` release, which is a very compressed timeline, so we might need to instead target `M.7` as an LTS, followed by a 10-week cycle for the major release. Alternatively, we could shift to 4- or 8-week release cycles and update our LTS cadence accordingly. -- **an even longer cycle:** 16 minor releases, 24 minor releases, etc. That would still make the releases *predictable*, but we would still pile up deprecations for longer, and the work for both users and maintainers at the release cycle would still be higher. Additionally, we know from experience in software in general (especially around "devops") that the longer the cycles involved in any given process, the harder they tend to be. A higher cadence for releases actually tends to be *easier*. +**An longer cycle:** 16 minor releases, 24 minor releases, etc. That would still make the releases *predictable*, but we would still pile up deprecations for longer, and the work for both users and maintainers at the release cycle would still be higher. Additionally, we know from experience in software in general (especially around "devops") that the longer the cycles involved in any given process, the harder they tend to be. A higher cadence for releases actually tends to be *easier*. That might suggest picking an even shorter cadence: new majors after every LTS release, e.g. 5.0, 5.4 LTS, 6.0, etc. That *would* help with the planning and we would get quite good at the process. There is also precedent, in that this is how both Angular and Node work. However, Angular and Node also *constantly* have LTS releases in active support across major releases, which ups the maintenance burden significantly. Picking a timeline of approximately a year (2 LTS releases) seems to best balance these tradeoffs. ### Different point for freezing deprecations -The `X.7` release is chosen as a point late in the cycle, and matches the point we have frozen deprecations relative to the next major in the pas. It is also relatively arbitrary, though! By taking the pressure off of any given major release, it's also less important. Our only *hard* constraint is that new deprecations targeting the next major not be introduced in the final LTS, so we could equally well choose `X.6`. And of course, if we picked a different cadence, we would pick a different value here as well. +The `M.10` release is chosen as a point late in the cycle, and is actually earlier the point we have frozen deprecations relative to the next major in the pas. It is also relatively arbitrary, though! By taking the pressure off of any given major release, it's also less important. Our only *hard* constraint is that new deprecations targeting the next major not be introduced in the final LTS, so we could equally well choose `M.9` or `M.11`. And of course, if we picked a different cadence, we would pick a different value here as well. ## Unresolved Questions From 55064fc54e0c9bbf363e5a5fe451b82e7b554ad2 Mon Sep 17 00:00:00 2001 From: Chris Krycho Date: Mon, 15 Aug 2022 09:54:18 -0600 Subject: [PATCH 4/5] RFC 830: frontmatter tweaks --- ...830-evolving-embers-major-version-process.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/text/0830-evolving-embers-major-version-process.md b/text/0830-evolving-embers-major-version-process.md index 491d3745fd..e0309ff245 100644 --- a/text/0830-evolving-embers-major-version-process.md +++ b/text/0830-evolving-embers-major-version-process.md @@ -1,12 +1,17 @@ --- -Stage: Accepted -Start Date: 2022-07-12 -Release Date: Unreleased -Release Versions: +stage: accepted +start-date: 2022-07-12 +release-date: Unreleased +release-versions: ember-source: vX.Y.Z ember-data: vX.Y.Z -Relevant Team(s): "Steering, Ember.js, Learning" -RFC PR: https://github.com/emberjs/rfcs/pull/830 +teams: + - steering + - framework + - learning +prs: + accepted: https://github.com/emberjs/rfcs/pull/830 + --- # Evolving Ember's Major Version Process From 1017889cc3267864ee9e7ab7c29ce44579343b19 Mon Sep 17 00:00:00 2001 From: Chris Krycho Date: Tue, 16 Aug 2022 09:45:22 -0600 Subject: [PATCH 5/5] RFC 830: note about simplification of major process --- ...0830-evolving-embers-major-version-process.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/text/0830-evolving-embers-major-version-process.md b/text/0830-evolving-embers-major-version-process.md index e0309ff245..833f32990e 100644 --- a/text/0830-evolving-embers-major-version-process.md +++ b/text/0830-evolving-embers-major-version-process.md @@ -58,6 +58,7 @@ However, those questions are orthogonal to this proposal: we can maintain lockst - [Detailed design](#detailed-design) - [Freeze deprecations at `M.10`](#freeze-deprecations-at-m10) - [Bootstrap with Ember v5.0](#bootstrap-with-ember-v50) + - [Simplify major version process](#simplify-major-version-process) - [Prior art](#prior-art) - [How we teach this](#how-we-teach-this) - [Publicize the change](#publicize-the-change) @@ -141,6 +142,21 @@ Given a known major release cadence, we can explicitly target a specific release When Ember adopted its 6-week "release train" cadence for minor releases, it used the 1.1 release to "bootstrap" the process and help the team learn how to do it, identify gaps, etc., with no features added. We should do the same here with 5.0. +### Simplify major version process + +Given the commitment to ship a major version on a schedule, it is critical that we make it as easy as possible to do so. We will therefore simplify the process of enabling a major so that there is no need for a large amount of work to be done immediately before its release. + +**The following is non-normative but reflects our current best thinking:** + +One likely mechanic for the `ember-source` package (and its internal subpackages) is to update our deprecation workflow and mechanics in the following ways: + +1. Introduce new tooling to Ember's internal tests which simulate the mode in which the deprecation fails. (We already have some of this, but need to iterate on it.) + +2. Require that all new deprecations test both the deprecated and non-deprecated paths, so we can be confident that removing the deprecation will not cause test failures. (This was an issue in the run up to 4.0.) + +3. When releasing a major, the deprecations will be enabled *automatically* because they target that major version. Then the dead (deprecated) code paths can be removed incrementally and at will, rather than it *having* to be removed prior to the major release. + + ### Prior art - Angular uses a six-month cadence for major releases, with every other major release (the even-numbered releases) being an LTS release.