Release & Publishing Pipeline
This pipeline turns a selected CI commit into staged release artifacts, validates the selected release channel, checks the package contents, and prepares publication to npm.
It exists so prereleases can ship continuously without affecting production users. Stable releases are promoted manually from the canary channel after testing.
Sources: scripts/release/prepare-release-from-ci.js:15-36, scripts/release/shared-commands/download-build-artifacts.js:87-158, scripts/release/README.md:47-58
Core concepts
CI build artifact
A CI build artifact is the packaged output attached to the runtime_build_and_test.yml workflow for a specific commit.
Sources: scripts/release/shared-commands/download-build-artifacts.js:18, scripts/release/shared-commands/download-build-artifacts.js:49-55, scripts/release/shared-commands/download-build-artifacts.js:177-182
Release channel
A release channel selects which built directory becomes the staged package tree: stable, experimental, rc, or latest.
| Channel | Staged source directory | Meaning in the release flow |
|---|---|---|
stable | oss-stable | Stable channel artifacts |
experimental | oss-experimental | Experimental channel artifacts |
rc | oss-stable-rc | Release-candidate artifacts |
latest | oss-stable-semver | Semver-oriented stable artifacts |
Sources: scripts/release/shared-commands/parse-params.js:47-57, scripts/release/shared-commands/download-build-artifacts.js:129-145
Dist-tag
A dist-tag is the single npm tag passed to each npm publish invocation; the workflow chooses it when dispatching the release.
Sources: scripts/release/publish-commands/publish-to-npm.js:10-53, scripts/release/publish-commands/parse-params.js:16-21
Packaging fixture
The packaging fixture is the validation step that prepare-release-from-ci.js runs after downloading artifacts, unless tests were explicitly skipped.
Sources: scripts/release/prepare-release-from-ci.js:15-36
Dependency compatibility check
The dependency check verifies that dependency versions inside the staged stable packages satisfy their declared dependency ranges.
Sources: scripts/release/check-release-dependencies.js:10-46, scripts/release/check-release-dependencies.js:48-57
How a commit becomes a staged release
A commit first passes the repository’s build and test workflow; the release scripts then locate the workflow run for that exact commit, wait while it is still running, and process its combined artifact after a successful conclusion.
The preparation entrypoint defaults the commit to main, parses release parameters, downloads the selected channel, runs the packaging fixture, and prints a prerelease summary.
The workflow below shows the preparation call path and the artifact’s movement into build/node_modules.
Evidence
- release-preparerscripts/release/prepare-release-from-ci.js:15
- artifact-downloaderscripts/release/shared-commands/download-build-artifacts.js:215
- github-artifactsscripts/release/shared-commands/download-build-artifacts.js:160
- artifact-processorscripts/release/shared-commands/download-build-artifacts.js:87
- packaging-fixturescripts/release/prepare-release-from-ci.js:15
- release-summaryscripts/release/prepare-release-from-ci.js:15
The downloader queries GitHub for the workflow run matching the commit, finds the artifacts_combined artifact, and waits up to twenty 30-second retries while the run is queued, in progress, or waiting.
The processor removes the old build directory, downloads and extracts the archive, and optionally verifies it with gh attestation verify; noVerify skips that verification.
It then copies the selected channel directory into the staging location and compares build/COMMIT_SHA with the requested commit, rejecting a mismatch before preparation completes.
Sources: scripts/release/README.md:20-24, scripts/release/shared-commands/download-build-artifacts.js:160-189, scripts/release/prepare-release-from-ci.js:15-36, scripts/release/shared-commands/download-build-artifacts.js:49-65, scripts/release/shared-commands/download-build-artifacts.js:160-213, scripts/release/shared-commands/download-build-artifacts.js:87-158
How preparation protects the release
Preparation has two distinct safeguards: artifact identity and package behavior. Artifact identity is checked by matching the embedded commit SHA, while package behavior is exercised by testPackagingFixture unless skipTests is set.
The artifact verifier also rejects a missing workflow run, missing artifact, unsuccessful workflow conclusion, invalid workflow status, or exhaustion of its retry window.
The packaging fixture is followed by the prerelease summary rather than publication inside prepare-release-from-ci.js; the surrounding release workflow performs the later publishing step.
For stable publication, check-release-dependencies.js requires build/oss-stable-semver and requires every package listed by stablePackages to have a package manifest there.
It collects package metadata, walks both dependencies and peerDependencies, and checks only relationships whose dependency package is also present in the staged package map.
checkDependency uses semver.satisfies; an incompatible range throws an error containing the package, dependency, declared range, and actual release version.
This protects a coordinated release from publishing packages whose internal dependency declarations do not accept the versions being released together.
Sources: scripts/release/prepare-release-from-ci.js:15-36, scripts/release/shared-commands/download-build-artifacts.js:87-158, scripts/release/shared-commands/download-build-artifacts.js:49-65, scripts/release/shared-commands/download-build-artifacts.js:67-85, scripts/release/shared-commands/download-build-artifacts.js:160-213, scripts/release/README.md:57-60, scripts/release/check-release-dependencies.js:10-46, scripts/release/check-release-dependencies.js:48-57
How publication selects packages and tags
The publishing entrypoint parses parameters, derives the public package list, and distinguishes the experimental case from other tags.
It rejects simultaneous onlyPackages and skipPackages, filters to onlyPackages when supplied, and removes validated skipped packages before any publish command runs.
Unknown skipped package names fail immediately, so a typo cannot silently produce a different package set.
The validation order is deliberate: validateTags, confirmVersionAndTags, and validateSkipPackages all run before the package loop begins.
The sequence below shows that ordering and the per-package hand-off.
Evidence
- publish-entrypointscripts/release/publish.js:15
- parameter-parserscripts/release/publish.js:15
- tag-validatorscripts/release/publish.js:15
- version-confirmationscripts/release/publish.js:15
- skip-validatorscripts/release/publish.js:15
- npm-publisherscripts/release/publish.js:15
For each remaining package, publishToNPM reads its version from the staged package path and first checks whether that exact package version already exists on npm; an existing version is skipped so a resumed run does not republish it.
Otherwise it invokes npm publish --tag <tag>, optionally adding --dry-run, and treats a nonzero status as a package failure.
The loop records failures, continues attempting remaining packages, and exits unsuccessfully after the loop if any package failed.
The repository guide describes the release progression as green CI, automated canary and experimental prereleases, and a manual stable promotion.
Stable releases should come from a tested canary release, and the stable workflow can publish either stable-latest or stable-backport.
Sources: scripts/release/publish.js:15-81, scripts/release/publish-commands/publish-to-npm.js:10-53, scripts/release/README.md:20-24, scripts/release/README.md:47-58
How it connects
Build and test produce the artifacts consumed here, so the release process depends on the workflow described in Build, Test, and Feature Flags.
The staged package set is drawn from the repository’s public packages and version metadata, connecting this pipeline to Repository Map and Release, Build & Lint Scripts.
The artifact directories are produced by the channel-specific bundling process described in Rollup Bundles & Module Forks.
The resulting npm packages are the distributable form of the runtime pieces introduced in React Overview.
Sources: scripts/release/README.md:20-22, scripts/release/publish.js:15-81, scripts/release/shared-commands/download-build-artifacts.js:129-145, scripts/release/README.md:20-24
Key takeaways
- CI artifacts are selected by commit and channel, verified against
COMMIT_SHA, then staged. - Preparation runs the packaging fixture before the release summary and later publication.
- Publication validates tags and package selection before invoking npm.
- Each package is published under one workflow-selected dist-tag, with already-published versions skipped.
- Stable dependency checks enforce compatible internal
dependenciesandpeerDependencies.