From 4434e6a739700ff86d7c155e7d2b4125b01e70b9 Mon Sep 17 00:00:00 2001 From: Brian Vaughn Date: Thu, 2 Nov 2017 20:36:42 -0700 Subject: [PATCH 1/6] Build script creates git tag --- scripts/release/build-commands/add-git-tag.js | 20 +++++++++++++++++++ scripts/release/build.js | 2 ++ 2 files changed, 22 insertions(+) create mode 100644 scripts/release/build-commands/add-git-tag.js diff --git a/scripts/release/build-commands/add-git-tag.js b/scripts/release/build-commands/add-git-tag.js new file mode 100644 index 000000000000..d8e3bf7bc2b4 --- /dev/null +++ b/scripts/release/build-commands/add-git-tag.js @@ -0,0 +1,20 @@ +#!/usr/bin/env node + +'use strict'; + +const chalk = require('chalk'); +const {execUnlessDry, logPromise} = require('../utils'); + +const run = async ({cwd, dry, version}) => { + await execUnlessDry(`git tag -a ${version} -m "Tagging ${version} release"`, { + cwd, + dry, + }); +}; + +module.exports = async ({cwd, dry, version}) => { + return logPromise( + run({cwd, dry, version}), + `Creating git tag ${chalk.yellow.bold(version)}` + ); +}; diff --git a/scripts/release/build.js b/scripts/release/build.js index 7295f16ebb92..13d7cfce782b 100755 --- a/scripts/release/build.js +++ b/scripts/release/build.js @@ -9,6 +9,7 @@ const run = async () => { const chalk = require('chalk'); const logUpdate = require('log-update'); + const addGitTag = require('./build-commands/add-git-tag'); const buildArtifacts = require('./build-commands/build-artifacts'); const checkCircleCiStatus = require('./build-commands/check-circle-ci-status'); const checkEnvironmentVariables = require('./build-commands/check-environment-variables'); @@ -39,6 +40,7 @@ const run = async () => { await runAutomatedTests(params); await updatePackageVersions(params); await buildArtifacts(params); + await addGitTag(params); await printPostBuildSummary(params); } catch (error) { logUpdate.clear(); From ea96f884b6dfc9bfe90249c50f4436e22faa63db Mon Sep 17 00:00:00 2001 From: Brian Vaughn Date: Thu, 2 Nov 2017 20:44:48 -0700 Subject: [PATCH 2/6] Build script post instructions print better relative paths --- .../print-post-build-summary.js | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/scripts/release/build-commands/print-post-build-summary.js b/scripts/release/build-commands/print-post-build-summary.js index 92cceff5140f..5ca50907ed07 100644 --- a/scripts/release/build-commands/print-post-build-summary.js +++ b/scripts/release/build-commands/print-post-build-summary.js @@ -3,16 +3,27 @@ 'use strict'; const chalk = require('chalk'); +const {join, relative} = require('path'); const {getUnexecutedCommands} = require('../utils'); const CHANGELOG_PATH = 'https://github.com/facebook/react/edit/master/CHANGELOG.md'; -module.exports = params => { +module.exports = ({cwd, dry, path, version}) => { + const publishPath = relative( + process.env.PWD, + join(__dirname, '../publish.js') + ); const command = - `./publish.js -v ${params.version}` + - (params.path ? ` -p ${params.path}` : '') + - (params.dry ? ' --dry' : ''); + `${publishPath} -v ${version}` + + (path ? ` -p ${path}` : '') + + (dry ? ' --dry' : ''); + + const packagingFixturesPath = join(cwd, 'fixtures/packaging'); + const standaloneFiturePath = join( + cwd, + 'fixtures/packaging/babel-standalone/dev.html' + ); console.log( chalk` @@ -29,9 +40,9 @@ module.exports = params => { {bold.underline Step 2: Smoke test the packages} - 1. Open {yellow.bold fixtures/packaging/babel-standalone/dev.html} in the browser. + 1. Open {yellow.bold ${standaloneFiturePath}} in the browser. 2. It should say {italic "Hello world!"} - 3. Next go to {yellow.bold fixtures/packaging} and run {bold node build-all.js} + 3. Next go to {yellow.bold ${packagingFixturesPath}} and run {bold node build-all.js} 4. Install the "serve" module ({bold npm install -g serve}) 5. Go to the repo root and {bold serve -s .} 6. Open {blue.bold http://localhost:5000/fixtures/packaging} From eeb91502a60299cebe623cfcd74ebf78a1786834 Mon Sep 17 00:00:00 2001 From: Brian Vaughn Date: Thu, 2 Nov 2017 20:54:46 -0700 Subject: [PATCH 3/6] Pre-release (<1.0) version numbers also include pre-release suffix (eg '-beta.0') --- scripts/release/build-commands/update-package-versions.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/scripts/release/build-commands/update-package-versions.js b/scripts/release/build-commands/update-package-versions.js index 84b0212e8270..d707c9d288b1 100644 --- a/scripts/release/build-commands/update-package-versions.js +++ b/scripts/release/build-commands/update-package-versions.js @@ -36,7 +36,13 @@ const update = async ({cwd, dry, version}) => { // In order to simplify DX for the release engineer, // These packages are auto-incremented by a minor version number. if (semver.lt(json.version, '1.0.0')) { - json.version = `0.${semver.minor(json.version) + 1}.0`; + const prerelease = semver.prerelease(version); + let suffix = ''; + if (prerelease) { + suffix = `-${prerelease.join('.')}`; + } + + json.version = `0.${semver.minor(json.version) + 1}.0${suffix}`; } else { json.version = version; } From 19e65c273ef459bf2477dc372e5b8c349213ec37 Mon Sep 17 00:00:00 2001 From: Brian Vaughn Date: Thu, 2 Nov 2017 21:33:03 -0700 Subject: [PATCH 4/6] Post-NPM-publish step properly handles minor rev comparison check --- .../release/publish-commands/publish-to-npm.js | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/scripts/release/publish-commands/publish-to-npm.js b/scripts/release/publish-commands/publish-to-npm.js index a4d11f54a7ef..cc4f7cb6b007 100644 --- a/scripts/release/publish-commands/publish-to-npm.js +++ b/scripts/release/publish-commands/publish-to-npm.js @@ -3,6 +3,7 @@ 'use strict'; const chalk = require('chalk'); +const {readJson} = require('fs-extra'); const {join} = require('path'); const semver = require('semver'); const {execRead, execUnlessDry, logPromise} = require('../utils'); @@ -23,9 +24,20 @@ const push = async ({cwd, dry, version}) => { ); const remoteVersion = status[tag]; - if (remoteVersion !== version) { + // Compare remote version to package.json version, + // To better handle the case of pre-release versions. + const packagePath = join( + cwd, + 'build', + 'packages', + project, + 'package.json' + ); + const packageJSON = await readJson(packagePath); + + if (remoteVersion !== packageJSON.version) { throw Error( - chalk`Publised version {yellow.bold ${version}} for ` + + chalk`Publised version {yellow.bold ${packageJSON.version}} for ` + `{bold ${project}} but NPM shows {yellow.bold ${remoteVersion}}` ); } @@ -48,5 +60,5 @@ const push = async ({cwd, dry, version}) => { }; module.exports = async params => { - return logPromise(push(params), 'Pushing to git remote'); + return logPromise(push(params), 'Publishing packages to NPM'); }; From ba635c63d03e9d6c3a5ab8d205fc68159efe2db6 Mon Sep 17 00:00:00 2001 From: Brian Vaughn Date: Thu, 2 Nov 2017 21:47:24 -0700 Subject: [PATCH 5/6] Release script also updates @next tag when publishing @latest --- .../publish-commands/publish-to-npm.js | 34 ++++++++++++------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/scripts/release/publish-commands/publish-to-npm.js b/scripts/release/publish-commands/publish-to-npm.js index cc4f7cb6b007..34237765f7cd 100644 --- a/scripts/release/publish-commands/publish-to-npm.js +++ b/scripts/release/publish-commands/publish-to-npm.js @@ -11,13 +11,24 @@ const {projects} = require('../config'); const push = async ({cwd, dry, version}) => { const errors = []; - const tag = semver.prerelease(version) ? 'next' : 'latest'; + const isPrerelease = semver.prerelease(version); + const tag = isPrerelease ? 'next' : 'latest'; const publishProject = async project => { try { const path = join(cwd, 'build', 'packages', project); await execUnlessDry(`npm publish --tag ${tag}`, {cwd: path, dry}); + const packagePath = join( + cwd, + 'build', + 'packages', + project, + 'package.json' + ); + const packageJSON = await readJson(packagePath); + const packageVersion = packageJSON.version; + if (!dry) { const status = JSON.parse( await execRead(`npm info ${project} dist-tags --json`) @@ -26,21 +37,20 @@ const push = async ({cwd, dry, version}) => { // Compare remote version to package.json version, // To better handle the case of pre-release versions. - const packagePath = join( - cwd, - 'build', - 'packages', - project, - 'package.json' - ); - const packageJSON = await readJson(packagePath); - - if (remoteVersion !== packageJSON.version) { + if (remoteVersion !== packageVersion) { throw Error( - chalk`Publised version {yellow.bold ${packageJSON.version}} for ` + + chalk`Publised version {yellow.bold ${packageVersion}} for ` + `{bold ${project}} but NPM shows {yellow.bold ${remoteVersion}}` ); } + + // If we've just published a stable release, + // Update the @next tag to also point to it (so @next doens't lag behind). + if (!isPrerelease) { + await execUnlessDry( + `npm dist-tag add ${project}@${packageVersion} next` + ); + } } } catch (error) { errors.push(error.message); From 2ec4d61e5b7256699ab257f3e192d9051dc54bf6 Mon Sep 17 00:00:00 2001 From: Brian Vaughn Date: Fri, 3 Nov 2017 13:03:30 -0700 Subject: [PATCH 6/6] Fixed a typo. Improved inline comment. --- scripts/release/build-commands/print-post-build-summary.js | 4 ++-- scripts/release/build-commands/update-package-versions.js | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/scripts/release/build-commands/print-post-build-summary.js b/scripts/release/build-commands/print-post-build-summary.js index 5ca50907ed07..a9c660d0c58b 100644 --- a/scripts/release/build-commands/print-post-build-summary.js +++ b/scripts/release/build-commands/print-post-build-summary.js @@ -20,7 +20,7 @@ module.exports = ({cwd, dry, path, version}) => { (dry ? ' --dry' : ''); const packagingFixturesPath = join(cwd, 'fixtures/packaging'); - const standaloneFiturePath = join( + const standaloneFixturePath = join( cwd, 'fixtures/packaging/babel-standalone/dev.html' ); @@ -40,7 +40,7 @@ module.exports = ({cwd, dry, path, version}) => { {bold.underline Step 2: Smoke test the packages} - 1. Open {yellow.bold ${standaloneFiturePath}} in the browser. + 1. Open {yellow.bold ${standaloneFixturePath}} in the browser. 2. It should say {italic "Hello world!"} 3. Next go to {yellow.bold ${packagingFixturesPath}} and run {bold node build-all.js} 4. Install the "serve" module ({bold npm install -g serve}) diff --git a/scripts/release/build-commands/update-package-versions.js b/scripts/release/build-commands/update-package-versions.js index d707c9d288b1..be297ac6fbf1 100644 --- a/scripts/release/build-commands/update-package-versions.js +++ b/scripts/release/build-commands/update-package-versions.js @@ -32,9 +32,10 @@ const update = async ({cwd, dry, version}) => { const path = join(cwd, 'packages', project, 'package.json'); const json = await readJson(path); - // Unstable packages (eg version < 1.0) are treated differently. - // In order to simplify DX for the release engineer, - // These packages are auto-incremented by a minor version number. + // Unstable packages (eg version < 1.0) are treated specially: + // Rather than use the release version (eg 16.1.0)- + // We just auto-increment the minor version (eg 0.1.0 -> 0.2.0). + // If we're doing a prerelease, we also append the suffix (eg 0.2.0-beta). if (semver.lt(json.version, '1.0.0')) { const prerelease = semver.prerelease(version); let suffix = '';