mirror of
https://github.com/zebrajr/react.git
synced 2025-12-07 00:20:28 +01:00
Updates the release script to publish tags as well as take a `--ci` option Test plan: ``` $ yarn npm:publish --debug --frfr yarn run v1.22.22 $ node scripts/release/publish --debug --frfr ℹ Preparing to publish (for real) [debug=true] ℹ Building packages ✔ Successfully built babel-plugin-react-compiler ✔ Successfully built eslint-plugin-react-compiler ✔ Successfully built react-compiler-healthcheck NPM 2-factor auth code: ****** ✔ Wrote package.json for babel-plugin-react-compiler@0.0.0-experimental-10cf18a-20240806 ========== babel-plugin-react-compiler ========== ⠧ Publishing babel-plugin-react-compiler@0.0.0-experimental-10cf18a-20240806 to npm + babel-plugin-react-compiler@0.0.0-experimental-10cf18a-20240806 ✔ Successfully published babel-plugin-react-compiler to npm ℹ dry-run: npm dist-tag add babel-plugin-react-compiler@0.0.0-experimental-10cf18a-20240806 experimental --otp=****** ✔ Successfully pushed dist-tag experimental for babel-plugin-react-compiler to npm ✔ Wrote package.json for eslint-plugin-react-compiler@0.0.0-experimental-532f76b-20240806 ========== eslint-plugin-react-compiler ========== ⠹ Publishing eslint-plugin-react-compiler@0.0.0-experimental-532f76b-20240806 to npm + eslint-plugin-react-compiler@0.0.0-experimental-532f76b-20240806 ✔ Successfully published eslint-plugin-react-compiler to npm ℹ dry-run: npm dist-tag add eslint-plugin-react-compiler@0.0.0-experimental-532f76b-20240806 experimental --otp=****** ✔ Successfully pushed dist-tag experimental for eslint-plugin-react-compiler to npm ✔ Wrote package.json for react-compiler-healthcheck@0.0.0-experimental-48a8743-20240806 ========== react-compiler-healthcheck ========== ⠙ Publishing react-compiler-healthcheck@0.0.0-experimental-48a8743-20240806 to npm + react-compiler-healthcheck@0.0.0-experimental-48a8743-20240806 ✔ Successfully published react-compiler-healthcheck to npm ℹ dry-run: npm dist-tag add react-compiler-healthcheck@0.0.0-experimental-48a8743-20240806 experimental --otp=****** ✔ Successfully pushed dist-tag experimental for react-compiler-healthcheck to npm ✅ All done ✨ Done in 50.64s. ``` ghstack-source-id: 405cc001c2ab2adaad2bfe4f11fdb7fd28d7e2d1 Pull Request resolved: https://github.com/facebook/react/pull/30614
211 lines
6.5 KiB
JavaScript
211 lines
6.5 KiB
JavaScript
const ora = require('ora');
|
|
const path = require('path');
|
|
const yargs = require('yargs');
|
|
const {hashElement} = require('folder-hash');
|
|
const promptForOTP = require('./prompt-for-otp');
|
|
const {PUBLISHABLE_PACKAGES} = require('./shared/packages');
|
|
const {
|
|
execHelper,
|
|
getDateStringForCommit,
|
|
spawnHelper,
|
|
} = require('./shared/utils');
|
|
const {buildPackages} = require('./shared/build-packages');
|
|
const {readJson, writeJson} = require('fs-extra');
|
|
|
|
/**
|
|
* Script for publishing PUBLISHABLE_PACKAGES to npm. By default, this runs in tarball mode, meaning
|
|
* the script will only print out what the contents of the files included in the npm tarball would
|
|
* be.
|
|
*
|
|
* Please run this first (ie `yarn npm:publish`) and double check the contents of the files that
|
|
* will be pushed to npm.
|
|
*
|
|
* If it looks good, you can run `yarn npm:publish --for-real` to really publish to npm. You must
|
|
* have 2FA enabled first and the script will prompt you to enter a 2FA code before proceeding.
|
|
* There's a small annoying delay before the packages are actually pushed to give you time to panic
|
|
* cancel. In this mode, we will bump the version field of each package's package.json, and git
|
|
* commit it. Then, the packages will be published to npm.
|
|
*
|
|
* Optionally, you can add the `--debug` flag to `yarn npm:publish --debug --for-real` to run all
|
|
* steps, but the final npm publish step will have the `--dry-run` flag added to it. This will make
|
|
* the command only report what it would have done, instead of actually publishing to npm.
|
|
*/
|
|
async function main() {
|
|
const argv = yargs(process.argv.slice(2))
|
|
.option('packages', {
|
|
description: 'which packages to publish, defaults to all',
|
|
choices: PUBLISHABLE_PACKAGES,
|
|
default: PUBLISHABLE_PACKAGES,
|
|
})
|
|
.option('for-real', {
|
|
alias: 'frfr',
|
|
description:
|
|
'whether to publish to npm (npm publish) or dryrun (npm publish --dry-run)',
|
|
type: 'boolean',
|
|
default: false,
|
|
})
|
|
.option('debug', {
|
|
description:
|
|
'If enabled, will always run npm commands in dry run mode irregardless of the for-real flag',
|
|
type: 'boolean',
|
|
default: false,
|
|
})
|
|
.option('ci', {
|
|
description: 'Publish packages via CI',
|
|
type: 'boolean',
|
|
default: false,
|
|
})
|
|
.option('tags', {
|
|
description: 'Tags to publish to npm',
|
|
type: 'choices',
|
|
choices: ['experimental'],
|
|
default: ['experimental'],
|
|
})
|
|
.help('help')
|
|
.parseSync();
|
|
|
|
if (argv.debug === false) {
|
|
const currBranchName = await execHelper('git rev-parse --abbrev-ref HEAD');
|
|
const isPristine = (await execHelper('git status --porcelain')) === '';
|
|
if (currBranchName !== 'main' || isPristine === false) {
|
|
throw new Error(
|
|
'This script must be run from the `main` branch with no uncommitted changes'
|
|
);
|
|
}
|
|
}
|
|
|
|
let pkgNames = argv.packages;
|
|
if (Array.isArray(argv.packages) === false) {
|
|
pkgNames = [argv.packages];
|
|
}
|
|
const spinner = ora(
|
|
`Preparing to publish ${
|
|
argv.forReal === true ? '(for real)' : '(dry run)'
|
|
} [debug=${argv.debug}]`
|
|
).info();
|
|
|
|
await buildPackages(pkgNames);
|
|
|
|
if (argv.forReal === false) {
|
|
spinner.info('Dry run: Report tarball contents');
|
|
for (const pkgName of pkgNames) {
|
|
console.log(`\n========== ${pkgName} ==========\n`);
|
|
spinner.start(`Running npm pack --dry-run\n`);
|
|
try {
|
|
await spawnHelper('npm', ['pack', '--dry-run'], {
|
|
cwd: path.resolve(__dirname, `../../packages/${pkgName}`),
|
|
stdio: 'inherit',
|
|
});
|
|
} catch (e) {
|
|
spinner.fail(e.toString());
|
|
throw e;
|
|
}
|
|
spinner.stop(`Successfully packed ${pkgName} (dry run)`);
|
|
}
|
|
spinner.succeed(
|
|
'Please confirm contents of packages before publishing. You can run this command again with --for-real to publish to npm'
|
|
);
|
|
}
|
|
|
|
if (argv.forReal === true) {
|
|
const commit = await execHelper(
|
|
'git show -s --no-show-signature --format=%h',
|
|
{
|
|
cwd: path.resolve(__dirname, '..'),
|
|
}
|
|
);
|
|
const dateString = await getDateStringForCommit(commit);
|
|
const otp = argv.ci === false ? await promptForOTP() : null;
|
|
|
|
for (const pkgName of pkgNames) {
|
|
const pkgDir = path.resolve(__dirname, `../../packages/${pkgName}`);
|
|
const pkgJsonPath = path.resolve(
|
|
__dirname,
|
|
`../../packages/${pkgName}/package.json`
|
|
);
|
|
const {hash} = await hashElement(pkgDir, {
|
|
encoding: 'hex',
|
|
folders: {exclude: ['node_modules']},
|
|
files: {exclude: ['.DS_Store']},
|
|
});
|
|
const truncatedHash = hash.slice(0, 7);
|
|
const newVersion = `0.0.0-experimental-${truncatedHash}-${dateString}`;
|
|
|
|
spinner.start(`Writing package.json for ${pkgName}@${newVersion}`);
|
|
await writeJson(
|
|
pkgJsonPath,
|
|
{
|
|
...(await readJson(pkgJsonPath)),
|
|
version: newVersion,
|
|
},
|
|
{spaces: 2}
|
|
);
|
|
spinner.succeed(`Wrote package.json for ${pkgName}@${newVersion}`);
|
|
|
|
console.log(`\n========== ${pkgName} ==========\n`);
|
|
spinner.start(`Publishing ${pkgName}@${newVersion} to npm\n`);
|
|
|
|
let opts = [];
|
|
if (argv.debug === true) {
|
|
opts.push('--dry-run');
|
|
}
|
|
if (otp != null) {
|
|
opts.push(`--otp=${otp}`);
|
|
}
|
|
try {
|
|
await spawnHelper(
|
|
'npm',
|
|
[
|
|
'publish',
|
|
...opts,
|
|
'--registry=https://registry.npmjs.org',
|
|
'--tag=experimental',
|
|
],
|
|
{
|
|
cwd: pkgDir,
|
|
stdio: 'inherit',
|
|
}
|
|
);
|
|
console.log('\n');
|
|
} catch (e) {
|
|
spinner.fail(e.toString());
|
|
throw e;
|
|
}
|
|
spinner.succeed(`Successfully published ${pkgName} to npm`);
|
|
|
|
spinner.start('Pushing tags to npm');
|
|
for (const tag of argv.tags) {
|
|
try {
|
|
let opts;
|
|
if (otp != null) {
|
|
opts = [
|
|
'dist-tag',
|
|
'add',
|
|
`${pkgName}@${newVersion}`,
|
|
tag,
|
|
`--otp=${otp}`,
|
|
];
|
|
} else {
|
|
opts = ['dist-tag', 'add', `${pkgName}@${newVersion}`, tag];
|
|
}
|
|
if (argv.debug === true) {
|
|
spinner.info(`dry-run: npm ${opts.join(' ')}`);
|
|
} else {
|
|
await spawnHelper('npm', opts);
|
|
}
|
|
} catch (e) {
|
|
spinner.fail(e.toString());
|
|
throw e;
|
|
}
|
|
spinner.succeed(
|
|
`Successfully pushed dist-tag ${tag} for ${pkgName} to npm`
|
|
);
|
|
}
|
|
}
|
|
|
|
console.log('\n\n✅ All done');
|
|
}
|
|
}
|
|
|
|
main();
|