diff --git a/scripts/release/publish-commands/print-follow-up-instructions.js b/scripts/release/publish-commands/print-follow-up-instructions.js index 7eb12c77723cf..db3ed9f713084 100644 --- a/scripts/release/publish-commands/print-follow-up-instructions.js +++ b/scripts/release/publish-commands/print-follow-up-instructions.js @@ -25,16 +25,39 @@ const run = async ({cwd, packages, tags}) => { ); if (tags.includes('latest')) { + console.log(); console.log( - theme.header`\nLocal versions may require updating after a stable release. Please verify the following files:` + theme.header`Please review and commit all local, staged changes.` ); + + console.log(); + console.log('Version numbers have been updated in the following files:'); for (let i = 0; i < packages.length; i++) { const packageName = packages[i]; console.log(theme.path`• packages/%s/package.json`, packageName); } console.log(theme.path`• packages/shared/ReactVersion.js`); + + console.log(); + if (environment === 'ci') { + console.log('Auto-generated error codes have been updated as well:'); + console.log(theme.path`• scripts/error-codes/codes.json`); + } else { + console.log( + theme`{caution The release that was just published was created locally.} ` + + theme`Because of this, you will need to update the generated ` + + theme`{path scripts/error-codes/codes.json} file manually:` + ); + console.log(theme` {command git checkout} {version ${commit}}`); + console.log(theme` {command yarn build -- --extract-errors}`); + } } + console.log(); + console.log( + theme`{header Don't forget to 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(); @@ -49,31 +72,8 @@ const run = async ({cwd, packages, tags}) => { ); console.log(theme.command` git push origin --tags`); - if (tags.includes('latest')) { - console.log(); - console.log( - theme`{header Don't forget to commit the generated }{path scripts/error-codes/codes.json}` - ); - if (environment === 'ci') { - console.log( - `This file has been updated locally. Please review it before committing.` - ); - } else { - console.log( - `The release that was just published was created locally. ` + - `Because of this, you will need to update error codes manually with the following commands:` - ); - console.log(theme` {command git checkout} {version ${commit}}`); - console.log(theme` {command yarn build -- --extract-errors}`); - } - } - - console.log(); - console.log( - theme`{header Don't forget to update and commit the }{path CHANGELOG}` - ); console.log(); - console.log(theme.header`Then fill in the release on GitHub:`); + 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 diff --git a/scripts/release/publish-commands/update-stable-version-numbers.js b/scripts/release/publish-commands/update-stable-version-numbers.js new file mode 100644 index 0000000000000..b94caa43c147f --- /dev/null +++ b/scripts/release/publish-commands/update-stable-version-numbers.js @@ -0,0 +1,49 @@ +#!/usr/bin/env node + +'use strict'; + +const {readFileSync, writeFileSync} = require('fs'); +const {readJson, writeJson} = require('fs-extra'); +const {join} = require('path'); + +const run = async ({cwd, packages, tags}) => { + if (!tags.includes('latest')) { + // Don't update version numbers for alphas. + return; + } + + const nodeModulesPath = join(cwd, 'build/node_modules'); + const packagesPath = join(cwd, 'packages'); + + // Update package versions and dependencies (in source) to mirror what was published to NPM. + for (let i = 0; i < packages.length; i++) { + const packageName = packages[i]; + const publishedPackageJSON = await readJson( + join(nodeModulesPath, packageName, 'package.json') + ); + const sourcePackageJSONPath = join( + packagesPath, + packageName, + 'package.json' + ); + const sourcePackageJSON = await readJson(sourcePackageJSONPath); + sourcePackageJSON.version = publishedPackageJSON.version; + sourcePackageJSON.dependencies = publishedPackageJSON.dependencies; + sourcePackageJSON.peerDependencies = publishedPackageJSON.peerDependencies; + + await writeJson(sourcePackageJSONPath, sourcePackageJSON, {spaces: 2}); + } + + // Update the shared React version source file. + const sourceReactVersionPath = join(cwd, 'packages/shared/ReactVersion.js'); + const {version} = await readJson( + join(nodeModulesPath, 'react', 'package.json') + ); + const sourceReactVersion = readFileSync( + sourceReactVersionPath, + 'utf8' + ).replace(/module\.exports = '[^']+';/, `module.exports = '${version}';`); + writeFileSync(sourceReactVersionPath, sourceReactVersion); +}; + +module.exports = run; diff --git a/scripts/release/publish.js b/scripts/release/publish.js index 3a28d1bf536b5..4923204a1333f 100755 --- a/scripts/release/publish.js +++ b/scripts/release/publish.js @@ -12,6 +12,7 @@ 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 run = async () => { @@ -26,6 +27,7 @@ const run = async () => { const otp = await promptForOTP(params); await publishToNPM(params, otp); await downloadErrorCodesFromCI(params); + await updateStableVersionNumbers(params); await printFollowUpInstructions(params); } catch (error) { handleError(error);