From e662e01bef165692e8e4f736ee07f8db25122da7 Mon Sep 17 00:00:00 2001 From: "@NullVoxPopuli's reduced-access machine account for AI usage" Date: Sat, 6 Jun 2026 00:56:42 -0400 Subject: [PATCH 1/3] Move off the release train to a simpler release model (#17) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add RFC: move off the release train to a simpler release model Propose retiring Ember's calendar-driven release train (fixed six-week minor cadence, rotating release-manager ceremony, hand-maintained canary/beta/release channels) in favor of an automated, PR-driven model powered by release-plan. Work integrates on `develop`; every merge can release from `main`, with the npm publish gated behind a protected GitHub deployment environment requiring manual approval. Stable releases go through the same gated release-plan publish. SemVer and existing compatibility guarantees are unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) * Drop the develop branch; release from a single `main` PRs merge to `main`, canary builds come off `main`, and the gated release-plan publish runs from `main`. Removes the develop/main split and the "promote develop to main" framing throughout. Co-Authored-By: Claude Opus 4.8 (1M context) * Keep the six-week cadence; drop only the canary/beta channels Reframe: the proposal retains the six-week release schedule and SemVer/ deprecation/major (RFC 830)/LTS policies unchanged. What changes is the branch-and-channel machinery — a single `main`, stable cut from it via release-plan on the existing cadence (gated by a GitHub deployment env), and the published canary/beta channels removed in favor of tracking `main` via git. Updates motivation, channels, deprecation/major/LTS, drawbacks, alternatives, and unresolved questions accordingly. Co-Authored-By: Claude Opus 4.8 (1M context) * Correct canary/beta channel facts; alpha auto-published from main Canary is consumed from git, not an ember-source@canary npm dist-tag; only @beta is a published prerelease tag today. Reframe the prerelease story: publish an `@alpha` dist-tag automatically from `main` (like Embroider's prereleases) while keeping main's git-ref workflow, drop the `@beta` tag, and resolve the former "build artifact consumption" open question. Updates motivation, channels, teaching, drawbacks, alternatives, and unresolved questions to match. Co-Authored-By: Claude Opus 4.8 (1M context) * Holistic pass: reconcile cadence with release-plan and RFC 830 Close the gaps the incremental edits left: - Explain that release-plan collapses a cycle's labeled PRs into a single bump (highest impact wins -> one minor per six weeks, as today), and how the continuous @alpha relates to the scheduled stable snapshot. - Reconcile majors with RFC 830: the M.10 freeze already gates when a breaking change may merge, so a label-driven major bump only happens in the major window -- not mid-cycle. - Clarify the scheduled cut is triggered by a maintainer or scheduled workflow; note ember-data is now WarpDrive. Co-Authored-By: Claude Opus 4.8 (1M context) * Address review: no canary branch, accurate release-plan, drop ember-data Incorporate all inline review feedback: - canary was never a branch; remove canary-branch framing everywhere and the duplicate-the-git-repo section - release-plan is label-driven (breaking/enhancement/bug/documentation/ internal); changelog comes from PR titles; remove changeset "fluff" - we publish from CI already (no "hand-publish"); the cost is maintainer time and bus-factor (Katie/Chris), and release-plan lets any maintainer release - emphasize release-plan handles version+changelog for us - majors aren't manual: breaking label + RFC 830's 12x6-week cadence - drop ember-data mentions; strip em-dash/colon taglines from headings - remove the "main lives in git" statement from the summary Co-Authored-By: Claude Opus 4.8 (1M context) * Reflow: one line per paragraph and list item, no hard wrapping Co-Authored-By: Claude Opus 4.8 (1M context) * Resolve open decisions: nightly @alpha, drop beta, timing-lockstep, maintainer cut, informal approvers - @alpha publishes nightly from main (not every merge) - beta fully dropped; the keep-beta option is now an alternative, not a TBD - lockstep is timing-based: ember-source/ember-cli release independently on the same six-week date, with no cross-repo coordination - the six-week stable cut is a maintainer merging the release-preview PR - publish approvers are the same active people who release today (informal) - prune the now-decided unresolved questions Co-Authored-By: Claude Opus 4.8 (1M context) * Clarify canary is unchanged; alpha scheme is release-plan default; beta cleanup is removal - canary stays exactly as today (main consumed from git); add it explicitly to the channels list and stop implying alpha replaces it - @alpha is a new published npm prerelease of main; release-plan handles the version scheme, nothing special - ember-try/beta consumers remove their @beta scenarios (canary unaffected) - Unresolved questions: none outstanding; only implementation remains Co-Authored-By: Claude Opus 4.8 (1M context) * Unresolved questions: n/a Co-Authored-By: Claude Opus 4.8 (1M context) * Rewrite in NullVoxPopuli's RFC voice; remove all em-dashes Conversational tone (today/folks, underscore emphasis, parentheticals), no em-dashes, lighter bold lead-ins. Content unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) * Drop the status-quo alternative Co-Authored-By: Claude Opus 4.8 (1M context) * Alternatives: drop keep-beta and changesets options Co-Authored-By: Claude Opus 4.8 (1M context) * Address PR review: trim drawbacks, drop Steering, keep LTS backports - remove redundant 'long-lived branch' phrasing; main is always that - just state release-plan's labels, no preamble - drop the soak-stage, labeling-discipline, publish-authority, and tooling-dependency drawbacks (non-issues / we own release-plan) - remove the Steering bullet and the steering team; steering doesn't decide this - scope removed backporting to the beta/release branches; keep LTS backports when needed - note consumers won't notice a difference Co-Authored-By: Claude Opus 4.8 (1M context) * Don't frame the cadence as in question; state the cost directly Co-Authored-By: Claude Opus 4.8 (1M context) * Apply suggestion from @NullVoxPopuli * Apply suggestion from @NullVoxPopuli * Apply suggestion from @NullVoxPopuli * Tone down marketing language Drop superlatives and sales phrasing (biggest win, trivially, turnkey, well loved, the important bit, everyone else already trusts, from anywhere, tribal knowledge) in favor of plain description. Co-Authored-By: Claude Opus 4.8 (1M context) --------- Co-authored-by: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) --- ...-release-train-to-simpler-release-model.md | 152 ++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 text/0000-move-off-the-release-train-to-simpler-release-model.md diff --git a/text/0000-move-off-the-release-train-to-simpler-release-model.md b/text/0000-move-off-the-release-train-to-simpler-release-model.md new file mode 100644 index 0000000000..17fdc8a68a --- /dev/null +++ b/text/0000-move-off-the-release-train-to-simpler-release-model.md @@ -0,0 +1,152 @@ +--- +stage: accepted +start-date: 2026-06-05T00:00:00.000Z +release-date: # In format YYYY-MM-DDT00:00:00.000Z +release-versions: +teams: # delete teams that aren't relevant + - cli + - framework +prs: + accepted: # Fill this in with the URL for the Proposal RFC PR +project-link: +suite: +--- + +# Move off the release train to a simpler release model + +## Summary + +Ember's "release train" today is really two things bundled together: + +1. A six-week release cadence. A new minor ships on a steady, predictable clock. +2. A multi-branch promotion pipeline. Code gets promoted from the default branch through dedicated `beta` and `release` branches (plus LTS branches), shepherded by a small number of folks who manage each release. + +This RFC keeps (1) and replaces (2). The six-week cadence stays as it is. What goes away is the extra release branches and the per-cycle process that goes with them. + +Concretely: + +- Just `main`. No `beta` or `release` branches. +- Stable releases are cut from `main` by [`release-plan`][release-plan] on the same six-week schedule. The `npm publish` is gated behind a protected [GitHub deployment environment][gh-environments], so a maintainer approves before anything publishes. +- We drop the `beta` channel. `@alpha` prerelease is nearly the same as before, but published nightly from `main`, and `ember-source@beta` users either move to `@alpha` or drop the scenario. + +SemVer, the six-week cadence, the deprecation policy, LTS, and the major-version process from [RFC #0830][rfc-830] are all unchanged. The only things that change are the branch structure and the publishing mechanics. + +[release-plan]: https://github.com/embroider-build/release-plan +[gh-environments]: https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment +[rfc-830]: https://github.com/emberjs/rfcs/blob/master/text/0830-evolving-embers-major-version-process.md + +## Motivation + +The expensive part of the release train is all the machinery around it, plus the time it takes maintainers with limited availability to keep it running. + +### Releases depend on too few people + +We don't actually have a formal release-manager rotation. In practice the release comes down to essentially one person per project: @katiegengler for `ember.js`, @mansona for `ember-cli`. This is a bus-factor and burnout risk -- which other teams have already faced. When that person isn't around (due to life, unplanned things, etc (this alone is not a big deal)), the release slips. + +Moving off the train means releasing stops being specialized knowledge (despite efforts to write it all down). With [`release-plan`][release-plan], _any_ maintainer can cut a release: they look over the release-preview PR and approve a deployment. + +### Extra release branches are overhead + +Keeping `beta`, `release`, and the LTS branches alive next to the default branch means constant backporting and branch bookkeeping that only exists to service the shape of the train. A single `main` removes that. + +### release-plan automates the mechanical work + +Working out the next version number and assembling the changelog are mechanical, error-prone steps that shouldn't be done by hand. release-plan does this for us, deterministically, from the labels and titles of the PRs that got merged. The ecosystem has already standardized on release-plan for almost every addon, so the framework doesn't need a bespoke process that's more work than the tooling everyone else uses. + +### Keep the cadence + +The six-week cadence is predictable and well understood, so we keep it. We're moving off the branch-and-process model, not the calendar. + +## Detailed design + +### Branching model + +Everything merges to `main`. It's both where work integrates and the source of every release. There are no `beta` or `release` branches, and none of the backporting onto them that the train needs. + +### Per-PR release metadata + +release-plan uses these labels: + +- `breaking` (major impact) +- `enhancement` (minor impact) +- `bug` (patch impact) +- `documentation`, `internal` (recorded, but don't cause a release on their own) + +The changelog entry for a release _is_ the set of merged PR titles (you can edit a title later to fix it up), so there's nothing extra to write. release-plan reads the labels and titles of everything merged since the last release, then works out the next version and assembles the changelog. The judgment a maintainer used to apply by reading the diff is captured by the label on each PR when it lands. + +### Releasing + +The cadence is unchanged. The mechanics are just release-plan's defaults: + +1. release-plan keeps a release-preview PR up to date. It bumps the version in `package.json`, edits `CHANGELOG.md`, and records the plan from the labels and titles merged since the last release. +2. On the scheduled six-week date, a maintainer merges that preview PR, which kicks off the publish workflow. (The schedule is the rhythm. Nothing forces a release between scheduled dates, and a date can still be held or moved like it can today.) +3. The publish job targets a protected GitHub environment (say, `npm-publish`) with a required-reviewers rule. The npm token / trusted-publishing identity is scoped to that environment, so nothing publishes until a required reviewer hits Approve on the pending deployment. Maintainers never need npm keys locally. +4. Once approved, the CI job runs `release-plan publish`: it tags, pushes, and publishes to npm (with provenance via OIDC trusted publishing). + +Across a cycle, release-plan collapses everything merged into a single version bump (highest impact wins), so six weeks of `enhancement` PRs becomes one minor, exactly like one stable minor per cycle does today. `@alpha` publishes the in-progress version nightly (e.g. `6.5.0-alpha.N`), and the scheduled stable cut publishes the finished version (`6.5.0`) as `@latest`. That stable release is just a snapshot of `main` on the scheduled date, which is the same thing promoting `release` from `beta` produced before. + +Approving the deployment is the only manual step left. No manual version edit, no manual changelog, no manual publish, and no branch to cut or promote. Because the gate is a GitHub environment, the normal GitHub permission and audit model applies, so who can approve and who approved what live in repo settings and the audit log. + +### Channels + +- Stable (`latest`): published from `main` through the gated environment, on the six-week cadence, as above. +- Canary: _unchanged by this RFC._ Canary is the default branch (`main`) consumed from git, and that keeps working exactly like it does today. +- `alpha`: new. A published, npm-installable prerelease of `main`, cut nightly the way Embroider and Glint _used to_ publish theirs. It gives `main` an npm dist-tag (`ember-source@alpha`) for folks who want canary's code without consuming from git. release-plan's defaults handle the version scheme. +- `beta`: removed. The `beta` branch and the `ember-source@beta` dist-tag both go away. Anything that needs extra baking can still merge early and get exercised via canary or `@alpha` before the next scheduled stable release. + +### Deprecations, majors, and LTS + +Since we keep the six-week cadence, everything layered on top of it is unaffected: + +- Deprecations still land as SemVer-minor and get removed in majors, on the same deprecation-freeze schedule. +- Majors aren't a manual process either. A PR gets labeled `breaking`, and because RFC #0830 puts a major on the normal cadence (roughly one major every twelve 6-week minors, after the `M.10` deprecation freeze), `breaking` PRs only merge in that window. So release-plan's label-driven bump produces the major right on schedule, with no manual version work. The major-version process itself doesn't change; it just runs through release-plan from `main`. +- LTS keeps working like it does today. + +So this RFC changes _how_ a release is cut and _which branches exist_, not _when_ releases happen or _what_ they guarantee. + +### Lockstep across packages + +`ember-source` and `ember-cli` keep releasing in lockstep, but lockstep here is a timing thing, not a coupling. Each repo releases independently through release-plan (its natural per-repo mode), and the releases don't need to know about each other. Since both cut stable on the same six-week date, their versions stay lined up. There's no cross-repo coordination step in the workflow; the shared cadence is what keeps them in step. + +### What this removes + +- The `beta` and `release` branches, and the `ember-source@beta` dist-tag. +- The backporting onto the `beta` and `release` branches. +- The bespoke per-cycle release process. Version bumps, changelog assembly, and the cut/promote steps are all release-plan's job now. + +### What this keeps + +- The six-week release cadence, unchanged. +- SemVer and every compatibility guarantee we make today. +- The deprecation policy, LTS, and the major-version process (RFC #0830). +- Backports to LTSes, when needed. +- A deliberate human gate before every publish. +- From a consumer's point of view, nothing changes. They won't notice a difference. + +## How we teach this + +Contributors keep doing what they already do in basically every addon: label each PR with a release-plan label. The PR title becomes the changelog entry. + +Maintainers get the ability to release. The role goes from "shepherd the branches and the cut" to "look over the release-preview PR and approve the deployment," which any maintainer can do without npm keys. + +`beta` users are the folks whose workflow moves. If your `ember-try` config or CI matrix tests `ember-source@beta`, you remove that scenario, since `@beta` won't exist anymore. You can add `@alpha` if you want a published prerelease. Canary testing (consuming `main` from git) is unaffected. + +Docs work: + +- Rewrite the website Releases page: `main` is the release line, the six-week cadence is unchanged, the prerelease stream is `@alpha` (published nightly from `main`), and `beta` is gone. +- Update the contributor guide with the labeling workflow. +- Document the environment, who can approve, and how approval works. +- A migration / announcement blog post about dropping `@beta`. + +## Drawbacks + +- Dropping `@beta` moves some consumers. Any `ember-try` scenario or addon CI matrix pinned to `ember-source@beta` has to remove that scenario (and can adopt `@alpha` if it wants). It's a one-time, mechanical cleanup rather than a lost capability, since canary testing is unaffected, but it's still ecosystem-wide churn that needs coordinating. +- Cultural change. `beta` is a long-standing, load-bearing part of Ember's testing culture and infrastructure, so removing it isn't only a mechanical change. + +## Alternatives + +- Drop the cadence too (fully continuous releases). A more radical model where every merge can release. We're explicitly _not_ proposing that here, because the six-week cadence works. + +## Unresolved questions + +n/a From 2169e45a722b8ee0d5b8a8171366434c7c2afee7 Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Sat, 6 Jun 2026 01:10:07 -0400 Subject: [PATCH 2/3] Apply suggestion from @NullVoxPopuli --- .../0000-move-off-the-release-train-to-simpler-release-model.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/text/0000-move-off-the-release-train-to-simpler-release-model.md b/text/0000-move-off-the-release-train-to-simpler-release-model.md index 17fdc8a68a..e73a4404e9 100644 --- a/text/0000-move-off-the-release-train-to-simpler-release-model.md +++ b/text/0000-move-off-the-release-train-to-simpler-release-model.md @@ -39,6 +39,8 @@ SemVer, the six-week cadence, the deprecation policy, LTS, and the major-version The expensive part of the release train is all the machinery around it, plus the time it takes maintainers with limited availability to keep it running. +Moving to release-plan also enables us to easily release the other packages in this repo (`@glimmer/syntax`, etc) + ### Releases depend on too few people We don't actually have a formal release-manager rotation. In practice the release comes down to essentially one person per project: @katiegengler for `ember.js`, @mansona for `ember-cli`. This is a bus-factor and burnout risk -- which other teams have already faced. When that person isn't around (due to life, unplanned things, etc (this alone is not a big deal)), the release slips. From f20a466c045d2d6ac23a8d00103a44d0d426f12d Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Sat, 6 Jun 2026 01:10:56 -0400 Subject: [PATCH 3/3] Rename release model documentation file --- ...1198-move-off-the-release-train-to-simpler-release-model.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename text/{0000-move-off-the-release-train-to-simpler-release-model.md => 1198-move-off-the-release-train-to-simpler-release-model.md} (99%) diff --git a/text/0000-move-off-the-release-train-to-simpler-release-model.md b/text/1198-move-off-the-release-train-to-simpler-release-model.md similarity index 99% rename from text/0000-move-off-the-release-train-to-simpler-release-model.md rename to text/1198-move-off-the-release-train-to-simpler-release-model.md index e73a4404e9..c321bda754 100644 --- a/text/0000-move-off-the-release-train-to-simpler-release-model.md +++ b/text/1198-move-off-the-release-train-to-simpler-release-model.md @@ -7,7 +7,7 @@ teams: # delete teams that aren't relevant - cli - framework prs: - accepted: # Fill this in with the URL for the Proposal RFC PR + accepted: https://github.com/emberjs/rfcs/pull/1198 # Fill this in with the URL for the Proposal RFC PR project-link: suite: ---