Skip to content

Unified release process#36456

Merged
eps1lon merged 5 commits into
facebook:mainfrom
eps1lon:sebbie/release-simple
May 26, 2026
Merged

Unified release process#36456
eps1lon merged 5 commits into
facebook:mainfrom
eps1lon:sebbie/release-simple

Conversation

@eps1lon
Copy link
Copy Markdown
Collaborator

@eps1lon eps1lon commented May 12, 2026

This unifies the release process for Nightlies and stable releases within a single workflow. The publish job now runs in a protected GitHub environment that matches our protected branches. This ensures release are only published from source that is reviewed by at least two people (commit author and reviewer). No self-review is allowed.

Any release going forward will be done from CI.

Discord notifications and automatic Nightlies should work like before.

Authentication is based on NPM's Trusted Publishing which allows us to drop usage of static automation tokens. However, this means

  1. Nightlies will only be tagged with canary (no more next tag)
  2. older releases will get a backport tag instead

These downsides are unavoidable with NPM's Trusted Publishing. OIDC tokens from GitHub are only allowed to use npm publish (which only allows a single tag). No npm dist-tag or npm deprecate operations are allowed.

Backport releases are blocked until we implement a custom Ruleset bypass to allow ref creation. If we'd allow ref creation for releases/**/*, a single compromised account with write access could just create the ref from an unreviewed commit.

For a stable release, manually bumping versions is still required.

I removed the "release from npm" workflow since that's largely defunct. Especially for backport releases we wouldn't validate a Canary before so all that adds is time between vulnerability discovery and fix being published. Still an interesting idea to implement but since we nowadays publish canaries from CI and use the same artifacts for stable, I don't see much added confidence we'd gain by using NPM artifacts.

Test plan

@meta-cla meta-cla Bot added the CLA Signed label May 12, 2026
@github-actions github-actions Bot added the React Core Team Opened by a member of the React Core Team label May 12, 2026
@react-sizebot
Copy link
Copy Markdown

react-sizebot commented May 12, 2026

Comparing: 926fa85...bf94d93

Critical size changes

Includes critical production bundles, as well as any change greater than 2%:

Name +/- Base Current +/- gzip Base gzip Current gzip
oss-stable/react-dom/cjs/react-dom.production.js = 6.84 kB 6.84 kB +0.05% 1.88 kB 1.88 kB
oss-stable/react-dom/cjs/react-dom-client.production.js = 614.17 kB 614.17 kB = 108.52 kB 108.52 kB
oss-experimental/react-dom/cjs/react-dom.production.js = 6.84 kB 6.84 kB +0.05% 1.88 kB 1.88 kB
oss-experimental/react-dom/cjs/react-dom-client.production.js = 680.11 kB 680.11 kB = 119.48 kB 119.48 kB
facebook-www/ReactDOM-prod.classic.js = 700.53 kB 700.53 kB = 123.05 kB 123.06 kB
facebook-www/ReactDOM-prod.modern.js = 690.84 kB 690.84 kB = 121.44 kB 121.44 kB

Significant size changes

Includes any change greater than 0.2%:

(No significant changes)

Generated by 🚫 dangerJS against bf94d93

@eps1lon eps1lon force-pushed the sebbie/release-simple branch 2 times, most recently from 95409bb to 56763b5 Compare May 12, 2026 17:27
@eps1lon eps1lon marked this pull request as ready for review May 12, 2026 17:31
@eps1lon eps1lon requested review from hoxyq and rickhanlonii May 12, 2026 17:40
Comment thread .github/workflows/runtime_build_and_test.yml Outdated
Comment thread scripts/release/publish.js Outdated
Comment on lines 19 to 23
// Publishing experimental versions as stable is forbidden
const isExperimental = false;

params.cwd = join(__dirname, '..', '..');
params.packages = await getPublicPackages(isExperimental);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this break the publishing of the react-markup package?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More details:

The new scripts/release/publish.js hardcodes:

  // Publishing experimental versions as stable is forbidden
  const isExperimental = false;
  ...
  params.packages = await getPublicPackages(isExperimental);

  But the workflow still drives the experimental publish path:

  - name: Stage experimental artifacts
    if: ${{ needs.resolve.outputs.release_type == 'nightly' || needs.resolve.outputs.release_type == 'experimental_only' }}
    run: scripts/release/prepare-release-from-ci.js --skipTests -r experimental --commit=${{ github.sha }}
  - name: Publish experimental to @experimental
    ...
    run: scripts/release/publish.js --tag=experimental ...

  getPublicPackages(false) returns only stablePackages from ReactVersions.js. experimentalPackages = ['react-markup'] is excluded. The new publish.js iterates params.packages (not build/node_modules/),
  so react-markup will sit in the staged build directory and never be published.

  Old behavior: publish.js derived isExperimental from build/node_modules/react/package.json version string, which for the experimental staging contains experimental-… → isExperimental=true →
  react-markup included.

  The PR's test runs cover canary publication but I don't see one that verifies the experimental publish actually pushed react-markup. Worth either:
  - deriving isExperimental from --tag === 'experimental' (or from the staged react package version, as before), or
  - iterating build/node_modules/* directly and verifying each is in the expected package set.

  The comment "Publishing experimental versions as stable is forbidden" describes a different concern than what the code actually does.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I missed that. Publishing of experimental packages should be fixed with 235f3a9 (this PR)

@eps1lon eps1lon force-pushed the sebbie/release-simple branch from d71a28d to 235f3a9 Compare May 26, 2026 15:09
e.g. we already dropped a static token in favor of OIDC tokens
@eps1lon eps1lon merged commit 75b0945 into facebook:main May 26, 2026
237 checks passed
@eps1lon eps1lon deleted the sebbie/release-simple branch May 26, 2026 15:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed React Core Team Opened by a member of the React Core Team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants