mirror of
https://github.com/zebrajr/react.git
synced 2025-12-07 00:20:28 +01:00
PR #20728 added a command to initiate a prerelease using CI, but it left the publish job unimplemented. This fills in the publish job. Uses an npm automation token for authorization, which bypasses the need for a one-time password. The token is configured via CircleCI's environment variable panel. Currently, it will always publish the head of the main branch. If the head has already been published, it will exit gracefully. It does not yet support publishing arbitrary commits, though we could easily add that. I don't know how important that use case is, because for PR branches, you can use CodeSandbox CI instead. Or as a last resort, run the publish script locally. Always publishing from main is nice because it further incentivizes us to keep main in a releasable state. It also takes the guesswork out of publishing a prerelease that's in a broken state: as long as we don't merge broken PRs, we're fine.
102 lines
3.4 KiB
JavaScript
Executable File
102 lines
3.4 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
|
|
'use strict';
|
|
|
|
const {join} = require('path');
|
|
const {readJsonSync} = require('fs-extra');
|
|
const clear = require('clear');
|
|
const {getPublicPackages, handleError} = require('./utils');
|
|
const theme = require('./theme');
|
|
|
|
const checkNPMPermissions = require('./publish-commands/check-npm-permissions');
|
|
const confirmSkippedPackages = require('./publish-commands/confirm-skipped-packages');
|
|
const confirmVersionAndTags = require('./publish-commands/confirm-version-and-tags');
|
|
const parseParams = require('./publish-commands/parse-params');
|
|
const printFollowUpInstructions = require('./publish-commands/print-follow-up-instructions');
|
|
const promptForOTP = require('./publish-commands/prompt-for-otp');
|
|
const publishToNPM = require('./publish-commands/publish-to-npm');
|
|
const updateStableVersionNumbers = require('./publish-commands/update-stable-version-numbers');
|
|
const validateTags = require('./publish-commands/validate-tags');
|
|
const validateSkipPackages = require('./publish-commands/validate-skip-packages');
|
|
|
|
const run = async () => {
|
|
try {
|
|
const params = parseParams();
|
|
|
|
const version = readJsonSync('./build/node_modules/react/package.json')
|
|
.version;
|
|
const isExperimental = version.includes('experimental');
|
|
|
|
params.cwd = join(__dirname, '..', '..');
|
|
params.packages = await getPublicPackages(isExperimental);
|
|
|
|
// Pre-filter any skipped packages to simplify the following commands.
|
|
// As part of doing this we can also validate that none of the skipped packages were misspelled.
|
|
params.skipPackages.forEach(packageName => {
|
|
const index = params.packages.indexOf(packageName);
|
|
if (index < 0) {
|
|
console.log(
|
|
theme`Invalid skip package {package ${packageName}} specified.`
|
|
);
|
|
process.exit(1);
|
|
} else {
|
|
params.packages.splice(index, 1);
|
|
}
|
|
});
|
|
|
|
await validateTags(params);
|
|
await confirmSkippedPackages(params);
|
|
await confirmVersionAndTags(params);
|
|
await validateSkipPackages(params);
|
|
await checkNPMPermissions(params);
|
|
|
|
const packageNames = params.packages;
|
|
|
|
if (params.ci) {
|
|
let failed = false;
|
|
for (let i = 0; i < packageNames.length; i++) {
|
|
try {
|
|
const packageName = packageNames[i];
|
|
await publishToNPM(params, packageName, null);
|
|
} catch (error) {
|
|
failed = true;
|
|
console.error(error.message);
|
|
console.log();
|
|
console.log(
|
|
theme.error`Publish failed. Will attempt to publish remaining packages.`
|
|
);
|
|
}
|
|
}
|
|
if (failed) {
|
|
console.log(theme.error`One or more packages failed to publish.`);
|
|
process.exit(1);
|
|
}
|
|
} else {
|
|
clear();
|
|
let otp = await promptForOTP(params);
|
|
for (let i = 0; i < packageNames.length; ) {
|
|
const packageName = packageNames[i];
|
|
try {
|
|
await publishToNPM(params, packageName, otp);
|
|
i++;
|
|
} catch (error) {
|
|
console.error(error.message);
|
|
console.log();
|
|
console.log(
|
|
theme.error`Publish failed. Enter a fresh otp code to retry.`
|
|
);
|
|
otp = await promptForOTP(params);
|
|
// Try publishing package again
|
|
continue;
|
|
}
|
|
}
|
|
await updateStableVersionNumbers(params);
|
|
await printFollowUpInstructions(params);
|
|
}
|
|
} catch (error) {
|
|
handleError(error);
|
|
}
|
|
};
|
|
|
|
run();
|