Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some release script fixes #20718

Merged
merged 2 commits into from Feb 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
126 changes: 70 additions & 56 deletions scripts/release/publish-commands/print-follow-up-instructions.js
Expand Up @@ -10,13 +10,6 @@ const theme = require('../theme');
const {execRead} = require('../utils');

const run = async ({cwd, packages, tags}) => {
// All packages are built from a single source revision,
// so it is safe to read build info from any one of them.
const arbitraryPackageName = packages[0];
const {commit} = readJsonSync(
join(cwd, 'build', 'node_modules', arbitraryPackageName, 'build-info.json')
);

// Tags are named after the react version.
const {version} = readJsonSync(
`${cwd}/build/node_modules/react/package.json`
Expand All @@ -28,6 +21,10 @@ const run = async ({cwd, packages, tags}) => {
console.log(
theme`{header A "next" release} {version ${version}} {header has been published!}`
);
} else if (tags.length === 1 && tags[0] === 'experimental') {
console.log(
theme`{header An "experimental" release} {version ${version}} {header has been published!}`
);
} else {
const nodeModulesPath = join(cwd, 'build/node_modules');

Expand All @@ -36,6 +33,23 @@ const run = async ({cwd, packages, tags}) => {
);

if (tags.includes('latest')) {
// All packages are built from a single source revision,
// so it is safe to read build info from any one of them.
const arbitraryPackageName = packages[0];
// FIXME: New build script does not output build-info.json. It's only used
// by this post-publish print job, and only for "latest" releases, so I've
// disabled it as a workaround so the publish script doesn't crash for
// "next" and "experimental" pre-releases.
const {commit} = readJsonSync(
join(
cwd,
'build',
'node_modules',
arbitraryPackageName,
'build-info.json'
)
);

console.log();
console.log(
theme.header`Please review and commit all local, staged changes.`
Expand All @@ -54,61 +68,61 @@ const run = async ({cwd, packages, tags}) => {
if (status) {
console.log(theme.path`• packages/shared/ReactVersion.js`);
}
}

console.log();
console.log(
theme`{header Don't forget to also update and commit the }{path CHANGELOG}`
);
console.log();
console.log(
theme`{header Don't forget to also update and commit the }{path CHANGELOG}`
);

// Prompt the release engineer to tag the commit and update the CHANGELOG.
// (The script could automatically do this, but this seems safer.)
console.log();
console.log(
theme.header`Tag the source for this release in Git with the following command:`
);
console.log(
theme` {command git tag -a v}{version %s} {command -m "v%s"} {version %s}`,
version,
version,
commit
);
console.log(theme.command` git push origin --tags`);
// Prompt the release engineer to tag the commit and update the CHANGELOG.
// (The script could automatically do this, but this seems safer.)
console.log();
console.log(
theme.header`Tag the source for this release in Git with the following command:`
);
console.log(
theme` {command git tag -a v}{version %s} {command -m "v%s"} {version %s}`,
version,
version,
commit
);
console.log(theme.command` git push origin --tags`);

console.log();
console.log(theme.header`Lastly, please fill in the release on GitHub.`);
console.log(
theme.link`https://github.com/facebook/react/releases/tag/v%s`,
version
);
console.log(
theme`\nThe GitHub release should also include links to the following artifacts:`
);
for (let i = 0; i < packages.length; i++) {
const packageName = packages[i];
if (existsSync(join(nodeModulesPath, packageName, 'umd'))) {
const {version: packageVersion} = readJsonSync(
join(nodeModulesPath, packageName, 'package.json')
);
console.log(
theme`{path • %s:} {link https://unpkg.com/%s@%s/umd/}`,
packageName,
packageName,
packageVersion
);
console.log();
console.log(theme.header`Lastly, please fill in the release on GitHub.`);
console.log(
theme.link`https://github.com/facebook/react/releases/tag/v%s`,
version
);
console.log(
theme`\nThe GitHub release should also include links to the following artifacts:`
);
for (let i = 0; i < packages.length; i++) {
const packageName = packages[i];
if (existsSync(join(nodeModulesPath, packageName, 'umd'))) {
const {version: packageVersion} = readJsonSync(
join(nodeModulesPath, packageName, 'package.json')
);
console.log(
theme`{path • %s:} {link https://unpkg.com/%s@%s/umd/}`,
packageName,
packageName,
packageVersion
);
}
}
}

// Update reactjs.org so the React version shown in the header is up to date.
console.log();
console.log(
theme.header`Once you've pushed changes, update the docs site.`
);
console.log(
'This will ensure that any newly-added error codes can be decoded.'
);
// Update reactjs.org so the React version shown in the header is up to date.
console.log();
console.log(
theme.header`Once you've pushed changes, update the docs site.`
);
console.log(
'This will ensure that any newly-added error codes can be decoded.'
);

console.log();
console.log();
}
}
};

Expand Down
92 changes: 41 additions & 51 deletions scripts/release/publish-commands/publish-to-npm.js
Expand Up @@ -3,70 +3,60 @@
'use strict';

const {exec} = require('child-process-promise');
const clear = require('clear');
const {readJsonSync} = require('fs-extra');
const {join} = require('path');
const {confirm, execRead} = require('../utils');
const theme = require('../theme');

const run = async ({cwd, dry, packages, tags}, otp) => {
clear();
const run = async ({cwd, dry, tags}, packageName, otp) => {
const packagePath = join(cwd, 'build/node_modules', packageName);
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Only real change here is I hoisted the for loop into the outer caller

const {version} = readJsonSync(join(packagePath, 'package.json'));

for (let i = 0; i < packages.length; i++) {
const packageName = packages[i];
const packagePath = join(cwd, 'build/node_modules', packageName);
const {version} = readJsonSync(join(packagePath, 'package.json'));
// Check if this package version has already been published.
// If so we might be resuming from a previous run.
// We could infer this by comparing the build-info.json,
// But for now the easiest way is just to ask if this is expected.
const info = await execRead(`npm view ${packageName}@${version}`);
if (info) {
console.log(
theme`{package ${packageName}} {version ${version}} has already been published.`
);
await confirm('Is this expected?');
} else {
console.log(theme`{spinnerSuccess ✓} Publishing {package ${packageName}}`);

// Check if this package version has already been published.
// If so we might be resuming from a previous run.
// We could infer this by comparing the build-info.json,
// But for now the easiest way is just to ask if this is expected.
const info = await execRead(`npm view ${packageName}@${version}`);
if (info) {
console.log(
theme`{package ${packageName}} {version ${version}} has already been published.`
);
await confirm('Is this expected?');
} else {
console.log(
theme`{spinnerSuccess ✓} Publishing {package ${packageName}}`
);
// Publish the package and tag it.
if (!dry) {
await exec(`npm publish --tag=${tags[0]} --otp=${otp}`, {
cwd: packagePath,
});
}
console.log(theme.command(` cd ${packagePath}`));
console.log(theme.command(` npm publish --tag=${tags[0]} --otp=${otp}`));

// Publish the package and tag it.
for (let j = 1; j < tags.length; j++) {
if (!dry) {
await exec(`npm publish --tag=${tags[0]} --otp=${otp}`, {
cwd: packagePath,
});
}
console.log(theme.command(` cd ${packagePath}`));
console.log(theme.command(` npm publish --tag=${tags[0]} --otp=${otp}`));

for (let j = 1; j < tags.length; j++) {
if (!dry) {
await exec(
`npm dist-tag add ${packageName}@${version} ${tags[j]} --otp=${otp}`,
{cwd: packagePath}
);
}
console.log(
theme.command(
` npm dist-tag add ${packageName}@${version} ${tags[j]} --otp=${otp}`
)
await exec(
`npm dist-tag add ${packageName}@${version} ${tags[j]} --otp=${otp}`,
{cwd: packagePath}
);
}
console.log(
theme.command(
` npm dist-tag add ${packageName}@${version} ${tags[j]} --otp=${otp}`
)
);
}

if (tags.includes('untagged')) {
// npm doesn't let us publish without a tag at all,
// so for one-off publishes we clean it up ourselves.
if (!dry) {
await exec(`npm dist-tag rm ${packageName} untagged --otp=${otp}`);
}
console.log(
theme.command(
` npm dist-tag rm ${packageName} untagged --otp=${otp}`
)
);
if (tags.includes('untagged')) {
// npm doesn't let us publish without a tag at all,
// so for one-off publishes we clean it up ourselves.
if (!dry) {
await exec(`npm dist-tag rm ${packageName} untagged --otp=${otp}`);
}
console.log(
theme.command(` npm dist-tag rm ${packageName} untagged --otp=${otp}`)
);
}
}
};
Expand Down
14 changes: 10 additions & 4 deletions scripts/release/publish.js
Expand Up @@ -4,6 +4,7 @@

const {join} = require('path');
const {readJsonSync} = require('fs-extra');
const clear = require('clear');
const {getPublicPackages, handleError} = require('./utils');
const theme = require('./theme');

Expand Down Expand Up @@ -49,17 +50,22 @@ const run = async () => {
await validateSkipPackages(params);
await checkNPMPermissions(params);

while (true) {
clear();
let otp = await promptForOTP(params);
const packageNames = params.packages;
for (let i = 0; i < packageNames.length; ) {
const packageName = packageNames[i];
try {
const otp = await promptForOTP(params);
await publishToNPM(params, otp);
break;
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;
}
}
Expand Down