Skip to content

Commit 85acb8a

Browse files
committed
Simplify release-from-npm workflow
1 parent 1721e73 commit 85acb8a

16 files changed

+151
-702
lines changed

.github/workflows/runtime_releases_from_npm_manual.yml

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,9 @@ name: (Runtime) Publish Releases from NPM Manual
33
on:
44
workflow_dispatch:
55
inputs:
6-
version_to_promote:
6+
prerelease:
77
required: true
8-
description: Current npm version (non-experimental) to promote
9-
type: string
10-
version_to_publish:
11-
required: true
12-
description: Version to publish for the specified packages
8+
description: Current npm prerelease (non-experimental) to promote
139
type: string
1410
only_packages:
1511
description: Packages to publish (space separated)
@@ -65,7 +61,7 @@ jobs:
6561
- uses: actions/checkout@v4
6662
- uses: actions/setup-node@v4
6763
with:
68-
node-version-file: '.nvmrc'
64+
node-version-file: ".nvmrc"
6965
cache: yarn
7066
cache-dependency-path: yarn.lock
7167
- name: Restore cached node_modules
@@ -82,42 +78,40 @@ jobs:
8278
- run: yarn --cwd scripts/release install --frozen-lockfile
8379
if: steps.node_modules.outputs.cache-hit != 'true'
8480
- run: cp ./scripts/release/ci-npmrc ~/.npmrc
85-
- if: '${{ inputs.only_packages }}'
86-
name: 'Prepare ${{ inputs.only_packages }} from NPM'
81+
- if: "${{ inputs.only_packages }}"
82+
name: "Prepare ${{ inputs.only_packages }} from NPM"
8783
run: |
8884
scripts/release/prepare-release-from-npm.js \
8985
--ci \
9086
--skipTests \
91-
--version=${{ inputs.version_to_promote }} \
92-
--publishVersion=${{ inputs.version_to_publish }} \
87+
--prerelease=${{ inputs.prerelease }} \
9388
--onlyPackages=${{ inputs.only_packages }}
94-
- if: '${{ inputs.skip_packages }}'
95-
name: 'Prepare all packages EXCEPT ${{ inputs.skip_packages }} from NPM'
89+
- if: "${{ inputs.skip_packages }}"
90+
name: "Prepare all packages EXCEPT ${{ inputs.skip_packages }} from NPM"
9691
run: |
9792
scripts/release/prepare-release-from-npm.js \
9893
--ci \
9994
--skipTests \
100-
--version=${{ inputs.version_to_promote }} \
101-
--publishVersion=${{ inputs.version_to_publish }} \
95+
--prerelease=${{ inputs.prerelease }} \
10296
--skipPackages=${{ inputs.skip_packages }}
10397
- name: Check prepared files
10498
run: ls -R build/node_modules
105-
- if: '${{ inputs.only_packages }}'
106-
name: 'Publish ${{ inputs.only_packages }}'
99+
- if: "${{ inputs.only_packages }}"
100+
name: "Publish ${{ inputs.only_packages }}"
107101
run: |
108102
scripts/release/publish.js \
109103
--ci \
110104
--tags=${{ inputs.tags }} \
111-
--publishVersion=${{ inputs.version_to_publish }} \
105+
--prerelease=${{ inputs.prerelease }} \
112106
--onlyPackages=${{ inputs.only_packages }} ${{ (inputs.dry && '') || '\'}}
113107
${{ inputs.dry && '--dry' || '' }}
114-
- if: '${{ inputs.skip_packages }}'
115-
name: 'Publish all packages EXCEPT ${{ inputs.skip_packages }}'
108+
- if: "${{ inputs.skip_packages }}"
109+
name: "Publish all packages EXCEPT ${{ inputs.skip_packages }}"
116110
run: |
117111
scripts/release/publish.js \
118112
--ci \
119113
--tags=${{ inputs.tags }} \
120-
--publishVersion=${{ inputs.version_to_publish }} \
114+
--prerelease=${{ inputs.prerelease }} \
121115
--skipPackages=${{ inputs.skip_packages }} ${{ (inputs.dry && '') || '\'}}
122116
${{ inputs.dry && '--dry' || '' }}
123117
- name: Archive released package for debugging

scripts/release/README.md

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -84,28 +84,26 @@ scripts/release/publish.js --tags experimental
8484

8585
## Publishing a Stable Release
8686

87-
Stable releases should always be created from the "next" channel. This encourages better testing of the actual release artifacts and reduces the chance of unintended changes accidentally being included in a stable release.
87+
Stable releases should always be created from the "canary" channel. This encourages better testing of the actual release artifacts and reduces the chance of unintended changes accidentally being included in a stable release.
8888

89-
To prepare a stable release, choose a "next" version and run the [`prepare-release-from-npm`](#prepare-release-from-npm) script <sup>1</sup>:
89+
To prepare a stable release, choose a "canary" version that's published on NPM.
9090

91-
```sh
92-
scripts/release/prepare-release-from-npm.js --version=0.0.0-241c4467e-20200129
93-
```
94-
95-
This script will prompt you to select stable version numbers for each of the packages. It will update the package JSON versions (and dependencies) based on the numbers you select.
96-
97-
Once this step is complete, you're ready to publish the release:
91+
Use the prerelease part of that version as the `prerelease` parameter in https://github.com/facebook/react/actions/workflows/runtime_releases_from_npm_manual.yml.
92+
E.g. Use `fd524fe0-20251121` when the published Canary version is `19.3.0-canary-fd524fe0-20251121`.
9893

99-
```sh
100-
scripts/release/publish.js --tags latest
101-
102-
# Or, if you want to bump "next" as well:
103-
scripts/release/publish.js --tags latest next
104-
```
94+
Make sure to also include dependencies in the included packages.
95+
E.g. `react-dom` has a dependency on `react` and `scheduler` and
10596

106-
After successfully publishing the release, follow the on-screen instructions to ensure that all of the appropriate post-release steps are executed.
97+
### Backport
10798

108-
<sup>1: You can omit the `version` param if you just want to promote the latest "next" candidate to stable.</sup>
99+
1. Pick a release commit to which you want to backport
100+
1. Create new branch off of that commit
101+
1. Push new branch to facebook/react
102+
1. Make sure [ReactVersions.js](./ReactVersions.js) matches the designated versions and doesn't conflict with already published stable versions
103+
1. Cherry-pick desired commits
104+
1. Push
105+
1. [Publish prerelease](./actions/workflows/runtime_prereleases_manual.yml) (`commit` is the newly pushed commit containing cherry-picked changes)
106+
1. (running the workflow on the commit that should be published) [Promote prerelease from npm](./actions/workflows/runtime_releases_from_npm_manual.yml)
109107

110108
## Creating a Patch Release
111109

scripts/release/prepare-release-from-npm-commands/check-out-packages.js

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,10 @@
55
const {exec} = require('child-process-promise');
66
const {existsSync} = require('fs');
77
const {join} = require('path');
8-
const {execRead, logPromise} = require('../utils');
8+
const {execRead} = require('../utils');
99
const theme = require('../theme');
1010

11-
const run = async ({cwd, local, packages, version}) => {
12-
if (local) {
13-
// Sanity test
14-
if (!existsSync(join(cwd, 'build', 'node_modules', 'react'))) {
15-
console.error(theme.error`No local build exists.`);
16-
process.exit(1);
17-
}
18-
return;
19-
}
20-
11+
const run = async (packages, versionsMap, {cwd, prerelease}) => {
2112
if (!existsSync(join(cwd, 'build'))) {
2213
await exec(`mkdir ./build`, {cwd});
2314
}
@@ -31,6 +22,14 @@ const run = async ({cwd, local, packages, version}) => {
3122
// Checkout "next" release from NPM for all local packages
3223
for (let i = 0; i < packages.length; i++) {
3324
const packageName = packages[i];
25+
if (!(packageName in versionsMap)) {
26+
throw Error(
27+
`Package "${packageName}" has no version specified. Only ${JSON.stringify(
28+
Object.keys(versionsMap)
29+
)} are supported are valid package names.`
30+
);
31+
}
32+
const version = versionsMap[packageName] + '-canary-' + prerelease;
3433

3534
// We previously used `npm install` for this,
3635
// but in addition to checking out a lot of transient dependencies that we don't care about–
@@ -49,12 +48,12 @@ const run = async ({cwd, local, packages, version}) => {
4948
await exec(`tar -xvzf ${filePath} -C ${nodeModulesPath}`, {cwd});
5049
await exec(`mv ${tempPackagePath} ${packagePath}`, {cwd});
5150
await exec(`rm ${filePath}`, {cwd});
51+
52+
console.log(
53+
theme`{green ✔} NPM checkout {package ${packageName}}@{version ${version}}`
54+
);
5255
}
5356
};
5457

55-
module.exports = async params => {
56-
return logPromise(
57-
run(params),
58-
theme`Checking out "next" from NPM {version ${params.version}}`
59-
);
60-
};
58+
// Run this directly because logPromise would interfere with printing package dependencies.
59+
module.exports = run;

scripts/release/prepare-release-from-npm-commands/confirm-stable-version-numbers.js

Lines changed: 0 additions & 71 deletions
This file was deleted.

scripts/release/prepare-release-from-npm-commands/get-latest-next-version.js

Lines changed: 0 additions & 15 deletions
This file was deleted.

scripts/release/prepare-release-from-npm-commands/guess-stable-version-numbers.js

Lines changed: 0 additions & 63 deletions
This file was deleted.

scripts/release/prepare-release-from-npm-commands/parse-params.js

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,6 @@ const commandLineArgs = require('command-line-args');
66
const {splitCommaParams} = require('../utils');
77

88
const paramDefinitions = [
9-
{
10-
name: 'local',
11-
type: Boolean,
12-
description:
13-
'Skip NPM and use the build already present in "build/node_modules".',
14-
defaultValue: false,
15-
},
169
{
1710
name: 'onlyPackages',
1811
type: String,
@@ -34,15 +27,10 @@ const paramDefinitions = [
3427
defaultValue: false,
3528
},
3629
{
37-
name: 'version',
30+
name: 'prerelease',
3831
type: String,
3932
description:
40-
'Version of published "next" release (e.g. 0.0.0-0e526bcec-20210202)',
41-
},
42-
{
43-
name: 'publishVersion',
44-
type: String,
45-
description: 'Version to publish',
33+
'prerelease to publish (e.g. version 19.2.0-canary-86181134-20251001 has prerelease "86181134-20251001")',
4634
},
4735
{
4836
name: 'ci',

0 commit comments

Comments
 (0)