From 03545b06e112e0a727024a73813594407730732d Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Fri, 17 May 2019 12:20:36 +0100 Subject: [PATCH 01/23] Bootstrap an automation tool --- bin/commander.js | 65 +++++++++ package-lock.json | 352 ++++++++++++++++++++++++++++++++++++++++++---- package.json | 3 + 3 files changed, 396 insertions(+), 24 deletions(-) create mode 100755 bin/commander.js diff --git a/bin/commander.js b/bin/commander.js new file mode 100755 index 0000000000000..b0d106974ad8d --- /dev/null +++ b/bin/commander.js @@ -0,0 +1,65 @@ +#!/usr/bin/env node + +/* eslint-disable no-console */ + +const path = require( 'path' ); +const program = require( 'commander' ); +const inquirer = require( 'inquirer' ); +const semver = require( 'semver' ); +const chalk = require( 'chalk' ); +const fs = require( 'fs' ); + +// Common info +const rootFolder = path.resolve( __dirname, '../' ); +const packageJsonPath = rootFolder + '/package.json'; +const packageLockPath = rootFolder + '/package-lock.json'; +const pluginFilePath = rootFolder + '/gutenberg.php'; +const packageJson = require( packageJsonPath ); +const packageLock = require( packageLockPath ); + +// UI +const error = chalk.bold.red; +const success = chalk.bold.green; + +program + .command( 'release-plugin-rc' ) + .action( async () => { + // Choosing the right version + const parsedVersion = semver.parse( packageJson.version ); + let nextVersion; + if ( parsedVersion.prerelease && parsedVersion.prerelease[ 0 ] === 'rc' ) { + nextVersion = semver.inc( packageJson.version, 'prerelease', 'rc' ); + } else if ( parsedVersion.minor === 9 ) { + nextVersion = ( parsedVersion.major + 1 ) + '.0.0-rc.1'; + } else { + nextVersion = parsedVersion.major + '.' + ( parsedVersion.minor + 1 ) + '.0-rc.1'; + } + const { acceptVersion } = await inquirer.prompt( [ { + type: 'confirm', + name: 'acceptVersion', + message: 'The RC Version to be applied is ' + success( nextVersion ) + '. Is this correct?', + default: true, + } ] ); + if ( ! acceptVersion ) { + console.log( error( 'Aborting' ) ); + process.exit( 1 ); + } + + // Bumping the version in the different files (package.json, package-lock.json, gutenberg.php) + const newPackageJson = { + ...packageJson, + version: nextVersion, + }; + await fs.writeFileSync( packageJsonPath, JSON.stringify( newPackageJson, null, '\t' ) + '\n' ); + const newPackageLock = { + ...packageLock, + version: nextVersion, + }; + await fs.writeFileSync( packageLockPath, JSON.stringify( newPackageLock, null, '\t' ) + '\n' ); + const content = await fs.readFileSync( pluginFilePath, 'utf8' ); + await fs.writeFileSync( pluginFilePath, content.replace( ' * Version: ' + packageJson.version, ' * Version: ' + nextVersion ) ); + + console.log( success( 'The version has been updated, commit the diff.' ) ); + } ); + +program.parse( process.argv ); diff --git a/package-lock.json b/package-lock.json index 5f830dff76a57..5cf7f565ca776 100644 --- a/package-lock.json +++ b/package-lock.json @@ -64,6 +64,12 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", "dev": true + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true } } }, @@ -840,6 +846,12 @@ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.127.tgz", "integrity": "sha512-1o25iFRf/dbgauTWalEzmD1EmRN3a2CzP/K7UVpYLEBduk96LF0FyUdCcf4Ry2mAWJ1VxyblFjC93q6qlLwA2A==", "dev": true + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true } } }, @@ -1211,6 +1223,14 @@ "p-map": "^1.2.0", "pacote": "^9.5.0", "semver": "^5.5.0" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } } }, "@lerna/batch-packages": { @@ -1254,6 +1274,14 @@ "p-waterfall": "^1.0.0", "read-package-tree": "^5.1.6", "semver": "^5.5.0" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } } }, "@lerna/changed": { @@ -1301,6 +1329,14 @@ "semver": "^5.5.0", "shebang-command": "^1.2.0", "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } } }, "execa": { @@ -1384,6 +1420,14 @@ "semver": "^5.5.0", "shebang-command": "^1.2.0", "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } } }, "execa": { @@ -1586,6 +1630,14 @@ "semver": "^5.5.0", "shebang-command": "^1.2.0", "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } } }, "execa": { @@ -1666,6 +1718,12 @@ "end-of-stream": "^1.1.0", "once": "^1.3.1" } + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true } } }, @@ -1707,6 +1765,12 @@ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + }, "whatwg-url": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.0.0.tgz", @@ -1874,6 +1938,14 @@ "requires": { "@lerna/child-process": "3.13.0", "semver": "^5.5.0" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } } }, "@lerna/import": { @@ -2143,6 +2215,14 @@ "@lerna/validation-error": "3.13.0", "npm-package-arg": "^6.1.0", "semver": "^5.5.0" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } } }, "@lerna/project": { @@ -2283,6 +2363,14 @@ "p-reduce": "^1.0.0", "pacote": "^9.5.0", "semver": "^5.5.0" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } } }, "@lerna/pulse-till-done": { @@ -2426,6 +2514,14 @@ "semver": "^5.5.0", "slash": "^1.0.0", "temp-write": "^3.4.0" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } } }, "@lerna/write-log-file": { @@ -4908,6 +5004,14 @@ "dev": true, "requires": { "semver": "^5.3.0" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } } } } @@ -5214,6 +5318,12 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true } } }, @@ -6252,10 +6362,9 @@ "dev": true }, "commander": { - "version": "2.16.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.16.0.tgz", - "integrity": "sha512-sVXqklSaotK9at437sFlFpyOcJonxe0yST/AG9DkQKUdIE6IqGIMv4SfAQSKaJbSdVEJYItASCrBiVQHq1HQew==", - "dev": true + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", + "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==" }, "commondir": { "version": "1.0.1", @@ -6647,6 +6756,12 @@ "read-pkg": "^3.0.0" } }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + }, "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -10601,6 +10716,12 @@ "read-pkg": "^3.0.0" } }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + }, "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -11283,42 +11404,76 @@ "semver": "2.x || 3.x || 4 || 5", "validate-npm-package-license": "^3.0.1", "validate-npm-package-name": "^3.0.0" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } } }, "inquirer": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.2.1.tgz", - "integrity": "sha512-088kl3DRT2dLU5riVMKKr1DlImd6X7smDhpXUCkJDCKvTEJeRiXh0G132HG9u5a+6Ylw9plFRY7RuTnwohYSpg==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.3.1.tgz", + "integrity": "sha512-MmL624rfkFt4TG9y/Jvmt8vdmOo836U7Y0Hxr2aFk3RelZEGX4Igk0KabWrcaaZaTv9uzglOqWh1Vly+FAWAXA==", "dev": true, "requires": { - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.0", + "ansi-escapes": "^3.2.0", + "chalk": "^2.4.2", "cli-cursor": "^2.1.0", "cli-width": "^2.0.0", - "external-editor": "^3.0.0", + "external-editor": "^3.0.3", "figures": "^2.0.0", - "lodash": "^4.17.10", + "lodash": "^4.17.11", "mute-stream": "0.0.7", "run-async": "^2.2.0", - "rxjs": "^6.1.0", + "rxjs": "^6.4.0", "string-width": "^2.1.0", - "strip-ansi": "^5.0.0", + "strip-ansi": "^5.1.0", "through": "^2.3.6" }, "dependencies": { + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true + }, "ansi-regex": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.0.0.tgz", - "integrity": "sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "rxjs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz", + "integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, "strip-ansi": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.0.0.tgz", - "integrity": "sha512-Uu7gQyZI7J7gn5qLn1Np3G9vcYGTVqB+lFTytnDJv83dd8T22aGH451P3jueT2/QemInJDfxHB5Tde5OzgG1Ow==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "requires": { - "ansi-regex": "^4.0.0" + "ansi-regex": "^4.1.0" } } } @@ -11892,6 +12047,14 @@ "@babel/types": "^7.0.0", "istanbul-lib-coverage": "^2.0.3", "semver": "^5.5.0" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } } } } @@ -11924,6 +12087,14 @@ "@babel/types": "^7.0.0", "istanbul-lib-coverage": "^2.0.3", "semver": "^5.5.0" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } } }, "istanbul-lib-report": { @@ -12026,6 +12197,14 @@ "semver": "^5.5.0", "shebang-command": "^1.2.0", "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } } }, "execa": { @@ -12257,6 +12436,14 @@ "semver": "^5.5.0", "shebang-command": "^1.2.0", "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } } }, "execa": { @@ -12759,6 +12946,14 @@ "semver": "^5.5.0", "shebang-command": "^1.2.0", "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } } }, "execa": { @@ -12975,6 +13170,14 @@ "natural-compare": "^1.4.0", "pretty-format": "^24.7.0", "semver": "^5.5.0" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } } }, "jest-util": { @@ -13556,6 +13759,14 @@ "semver": "^5.5.0", "shebang-command": "^1.2.0", "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } } }, "execa": { @@ -14751,6 +14962,14 @@ "railroad-diagrams": "^1.0.0", "randexp": "0.4.6", "semver": "^5.4.1" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } } }, "negotiator": { @@ -14892,6 +15111,14 @@ "semver": "^5.5.0", "shellwords": "^0.1.1", "which": "^1.3.0" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } } }, "node-releases": { @@ -14901,6 +15128,14 @@ "dev": true, "requires": { "semver": "^5.3.0" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } } }, "node-sass": { @@ -15202,6 +15437,14 @@ "is-builtin-module": "^1.0.0", "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } } }, "normalize-path": { @@ -15271,6 +15514,14 @@ "osenv": "^0.1.5", "semver": "^5.5.0", "validate-npm-package-name": "^3.0.0" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } } }, "npm-package-json-lint": { @@ -15385,6 +15636,14 @@ "figgy-pudding": "^3.5.1", "npm-package-arg": "^6.0.0", "semver": "^5.4.1" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } } }, "npm-registry-fetch": { @@ -16321,6 +16580,12 @@ "integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==", "dev": true }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -17080,6 +17345,14 @@ "resolve": "^1.3.2", "semver": "^5.4.1", "source-map": "^0.5.0" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } } }, "@babel/generator": { @@ -18820,6 +19093,14 @@ "semver": "^5.5.0", "shebang-command": "^1.2.0", "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } } }, "execa": { @@ -19438,6 +19719,14 @@ "semver": "^5.5.0", "shebang-command": "^1.2.0", "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } } }, "execa": { @@ -19692,10 +19981,9 @@ "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=" }, "semver": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", - "dev": true + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.0.0.tgz", + "integrity": "sha512-0UewU+9rFapKFnlbirLi3byoOuhrSsli/z/ihNnvM24vgF+8sNBiI1LZPBSH9wJKUwaUbw+s3hToDLCXkrghrQ==" }, "semver-compare": { "version": "1.0.0", @@ -22544,6 +22832,14 @@ "semver": "^5.5.0", "shebang-command": "^1.2.0", "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } } }, "execa": { @@ -23309,6 +23605,14 @@ "semver": "^5.5.0", "shebang-command": "^1.2.0", "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } } }, "execa": { diff --git a/package.json b/package.json index 7986263f49cfe..85e0f9f96d9e7 100644 --- a/package.json +++ b/package.json @@ -82,6 +82,7 @@ "benchmark": "2.1.4", "browserslist": "4.4.1", "chalk": "2.4.1", + "commander": "2.20.0", "concurrently": "3.5.0", "copy-webpack-plugin": "4.5.2", "core-js": "3.0.1", @@ -96,6 +97,7 @@ "fbjs": "0.8.17", "glob": "7.1.2", "husky": "0.14.3", + "inquirer": "6.3.1", "is-equal-shallow": "0.1.3", "jsdom": "11.12.0", "lerna": "3.13.2", @@ -115,6 +117,7 @@ "rimraf": "2.6.2", "rtlcss": "2.4.0", "sass-loader": "6.0.7", + "semver": "6.0.0", "shallow-equal": "1.0.0", "shallow-equals": "1.0.0", "shallowequal": "1.1.0", From 831f54e1b8e3a476cb6319b3c460d5c66bf81afe Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Fri, 17 May 2019 13:04:17 +0100 Subject: [PATCH 02/23] Checking the current branch --- bin/commander.js | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/bin/commander.js b/bin/commander.js index b0d106974ad8d..06c81c78be6cd 100755 --- a/bin/commander.js +++ b/bin/commander.js @@ -2,12 +2,14 @@ /* eslint-disable no-console */ +// Dependencies const path = require( 'path' ); const program = require( 'commander' ); const inquirer = require( 'inquirer' ); const semver = require( 'semver' ); const chalk = require( 'chalk' ); const fs = require( 'fs' ); +const SimpleGit = require( 'simple-git/promise' ); // Common info const rootFolder = path.resolve( __dirname, '../' ); @@ -16,20 +18,38 @@ const packageLockPath = rootFolder + '/package-lock.json'; const pluginFilePath = rootFolder + '/gutenberg.php'; const packageJson = require( packageJsonPath ); const packageLock = require( packageLockPath ); +const simpleGit = SimpleGit( rootFolder ); // UI const error = chalk.bold.red; +const warning = chalk.bold.keyword( 'orange' ); const success = chalk.bold.green; program .command( 'release-plugin-rc' ) + .alias( 'rc' ) + .description( 'Release an RC version of the plugin (supports only rc.1 for now)' ) .action( async () => { - // Choosing the right version + // Check the current branch and if the versions + const status = await simpleGit.status(); const parsedVersion = semver.parse( packageJson.version ); + if ( status.current !== 'master' ) { + const { acceptBranch } = await inquirer.prompt( [ { + type: 'confirm', + name: 'acceptBranch', + message: 'Releasing plugin RC versions usually happens from the ' + warning( 'master' ) + ' branch. Do you want to continue from the current branch?', + default: false, + } ] ); + + if ( ! acceptBranch ) { + console.log( error( 'Aborting' ) ); + process.exit( 1 ); + } + } + + // Choosing the right version let nextVersion; - if ( parsedVersion.prerelease && parsedVersion.prerelease[ 0 ] === 'rc' ) { - nextVersion = semver.inc( packageJson.version, 'prerelease', 'rc' ); - } else if ( parsedVersion.minor === 9 ) { + if ( parsedVersion.minor === 9 ) { nextVersion = ( parsedVersion.major + 1 ) + '.0.0-rc.1'; } else { nextVersion = parsedVersion.major + '.' + ( parsedVersion.minor + 1 ) + '.0-rc.1'; @@ -59,7 +79,7 @@ program const content = await fs.readFileSync( pluginFilePath, 'utf8' ); await fs.writeFileSync( pluginFilePath, content.replace( ' * Version: ' + packageJson.version, ' * Version: ' + nextVersion ) ); - console.log( success( 'The version has been updated, commit the diff.' ) ); + console.log( success( 'The version has been updated, commit the diff to the release branch.' ) ); } ); program.parse( process.argv ); From efd69498060f594bbc52eb4c4c46a238e8621285 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Fri, 17 May 2019 13:14:54 +0100 Subject: [PATCH 03/23] Check uncommited local changes --- bin/commander.js | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/bin/commander.js b/bin/commander.js index 06c81c78be6cd..a2a50be7f4689 100755 --- a/bin/commander.js +++ b/bin/commander.js @@ -31,9 +31,9 @@ program .description( 'Release an RC version of the plugin (supports only rc.1 for now)' ) .action( async () => { // Check the current branch and if the versions - const status = await simpleGit.status(); + const gitStatus = await simpleGit.status(); const parsedVersion = semver.parse( packageJson.version ); - if ( status.current !== 'master' ) { + if ( gitStatus.current !== 'master' ) { const { acceptBranch } = await inquirer.prompt( [ { type: 'confirm', name: 'acceptBranch', @@ -46,6 +46,19 @@ program process.exit( 1 ); } } + if ( gitStatus.files.length ) { + const { acceptLocalChanges } = await inquirer.prompt( [ { + type: 'confirm', + name: 'acceptLocalChanges', + message: 'Your working tree is dirty. Do you want to continue? (some changes might be inadvertantly commited)', + default: false, + } ] ); + + if ( ! acceptLocalChanges ) { + console.log( error( 'Aborting' ) ); + process.exit( 1 ); + } + } // Choosing the right version let nextVersion; From 628c417db62110749075578b6fe225b1a407f8a6 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Fri, 17 May 2019 13:42:20 +0100 Subject: [PATCH 04/23] Add the creation of the release branch and the version bump commit --- bin/commander.js | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/bin/commander.js b/bin/commander.js index a2a50be7f4689..3aa295f3f04db 100755 --- a/bin/commander.js +++ b/bin/commander.js @@ -62,15 +62,18 @@ program // Choosing the right version let nextVersion; + let releaseBranch; if ( parsedVersion.minor === 9 ) { nextVersion = ( parsedVersion.major + 1 ) + '.0.0-rc.1'; + releaseBranch = 'release/' + ( parsedVersion.major + 1 ) + '.0'; } else { nextVersion = parsedVersion.major + '.' + ( parsedVersion.minor + 1 ) + '.0-rc.1'; + releaseBranch = 'release/' + parsedVersion.major + '.' + ( parsedVersion.minor + 1 ); } const { acceptVersion } = await inquirer.prompt( [ { type: 'confirm', name: 'acceptVersion', - message: 'The RC Version to be applied is ' + success( nextVersion ) + '. Is this correct?', + message: 'The RC Version to be applied is ' + success( nextVersion ) + '. Proceed with the creation of the release branch?', default: true, } ] ); if ( ! acceptVersion ) { @@ -78,6 +81,10 @@ program process.exit( 1 ); } + // Creating the release branch + await simpleGit.checkoutLocalBranch( releaseBranch ); + console.log( '>> The local release branch "' + success( releaseBranch ) + '" has been successfully created.' ); + // Bumping the version in the different files (package.json, package-lock.json, gutenberg.php) const newPackageJson = { ...packageJson, @@ -91,8 +98,27 @@ program await fs.writeFileSync( packageLockPath, JSON.stringify( newPackageLock, null, '\t' ) + '\n' ); const content = await fs.readFileSync( pluginFilePath, 'utf8' ); await fs.writeFileSync( pluginFilePath, content.replace( ' * Version: ' + packageJson.version, ' * Version: ' + nextVersion ) ); + console.log( '>> The plugin version has been updated successfully.' ); + + // Commit the version bump + const { acceptDiff } = await inquirer.prompt( [ { + type: 'confirm', + name: 'acceptDiff', + message: 'Please check the diff. Proceed with the version bump commit?', + default: true, + } ] ); + if ( ! acceptDiff ) { + console.log( error( 'Aborting. Make sure to remove the local release branch' ) ); + process.exit( 1 ); + } + await simpleGit.add( [ + packageJsonPath, + packageLockPath, + pluginFilePath, + ] ); + const { commit } = await simpleGit.commit( 'Bump plugin version to ' + nextVersion ); - console.log( success( 'The version has been updated, commit the diff to the release branch.' ) ); + console.log( '>> The plugin version bump was commited succesfully. Please push the release branch to the repository and cherry-pick the ' + success( commit ) + ' commit to the master branch.' ); } ); program.parse( process.argv ); From 24abc67d7192dd3c71d578d180ea340b5eb01fa1 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Fri, 17 May 2019 14:37:29 +0100 Subject: [PATCH 05/23] Adding simple git dependency --- bin/commander.js | 8 ++++---- package-lock.json | 12 +++++++----- package.json | 1 + 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/bin/commander.js b/bin/commander.js index 3aa295f3f04db..74ceeb0e04ca6 100755 --- a/bin/commander.js +++ b/bin/commander.js @@ -90,14 +90,14 @@ program ...packageJson, version: nextVersion, }; - await fs.writeFileSync( packageJsonPath, JSON.stringify( newPackageJson, null, '\t' ) + '\n' ); + fs.writeFileSync( packageJsonPath, JSON.stringify( newPackageJson, null, '\t' ) + '\n' ); const newPackageLock = { ...packageLock, version: nextVersion, }; - await fs.writeFileSync( packageLockPath, JSON.stringify( newPackageLock, null, '\t' ) + '\n' ); - const content = await fs.readFileSync( pluginFilePath, 'utf8' ); - await fs.writeFileSync( pluginFilePath, content.replace( ' * Version: ' + packageJson.version, ' * Version: ' + nextVersion ) ); + fs.writeFileSync( packageLockPath, JSON.stringify( newPackageLock, null, '\t' ) + '\n' ); + const content = fs.readFileSync( pluginFilePath, 'utf8' ); + fs.writeFileSync( pluginFilePath, content.replace( ' * Version: ' + packageJson.version, ' * Version: ' + nextVersion ) ); console.log( '>> The plugin version has been updated successfully.' ); // Commit the version bump diff --git a/package-lock.json b/package-lock.json index 5cf7f565ca776..56213d3fe64b1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6364,7 +6364,8 @@ "commander": { "version": "2.20.0", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", - "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==" + "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", + "dev": true }, "commondir": { "version": "1.0.1", @@ -19983,7 +19984,8 @@ "semver": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.0.0.tgz", - "integrity": "sha512-0UewU+9rFapKFnlbirLi3byoOuhrSsli/z/ihNnvM24vgF+8sNBiI1LZPBSH9wJKUwaUbw+s3hToDLCXkrghrQ==" + "integrity": "sha512-0UewU+9rFapKFnlbirLi3byoOuhrSsli/z/ihNnvM24vgF+8sNBiI1LZPBSH9wJKUwaUbw+s3hToDLCXkrghrQ==", + "dev": true }, "semver-compare": { "version": "1.0.0", @@ -20188,9 +20190,9 @@ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" }, "simple-git": { - "version": "1.110.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-1.110.0.tgz", - "integrity": "sha512-UYY0rQkknk0P5eb+KW+03F4TevZ9ou0H+LoGaj7iiVgpnZH4wdj/HTViy/1tNNkmIPcmtxuBqXWiYt2YwlRKOQ==", + "version": "1.113.0", + "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-1.113.0.tgz", + "integrity": "sha512-i9WVsrK2u0G/cASI9nh7voxOk9mhanWY9eGtWBDSYql6m49Yk5/Fan6uZsDr/xmzv8n+eQ8ahKCoEr8cvU3h+g==", "dev": true, "requires": { "debug": "^4.0.1" diff --git a/package.json b/package.json index 85e0f9f96d9e7..cd650afadd647 100644 --- a/package.json +++ b/package.json @@ -121,6 +121,7 @@ "shallow-equal": "1.0.0", "shallow-equals": "1.0.0", "shallowequal": "1.1.0", + "simple-git": "1.113.0", "sprintf-js": "1.1.1", "stylelint-config-wordpress": "13.1.0", "uuid": "3.3.2", From 9a56a01bb8092cfcd53672b9cfcd8eb226a4cbd7 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Fri, 17 May 2019 14:49:33 +0100 Subject: [PATCH 06/23] Clean the working tree --- bin/commander.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/bin/commander.js b/bin/commander.js index 74ceeb0e04ca6..629e64b360728 100755 --- a/bin/commander.js +++ b/bin/commander.js @@ -30,6 +30,8 @@ program .alias( 'rc' ) .description( 'Release an RC version of the plugin (supports only rc.1 for now)' ) .action( async () => { + console.log( '>> 💃 Time to release Gutenberg 🕺' ); + // Check the current branch and if the versions const gitStatus = await simpleGit.status(); const parsedVersion = semver.parse( packageJson.version ); @@ -50,7 +52,7 @@ program const { acceptLocalChanges } = await inquirer.prompt( [ { type: 'confirm', name: 'acceptLocalChanges', - message: 'Your working tree is dirty. Do you want to continue? (some changes might be inadvertantly commited)', + message: 'Your working tree is dirty. Do you want to continue? (you may loose uncommited changes).', default: false, } ] ); @@ -60,6 +62,17 @@ program } } + // Cleaning the repository + const { skipCleaning } = await inquirer.prompt( [ { + type: 'confirm', + name: 'skipCleaning', + message: 'Your working tree is going to be cleaned. Uncommited changes will be lost. Do you want to skip?', + default: false, + } ] ); + if ( ! skipCleaning ) { + await simpleGit.clean( 'xfd' ); + } + // Choosing the right version let nextVersion; let releaseBranch; From 9180cf2c6d9051df77c45151fbd97c2602ea4270 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Fri, 17 May 2019 15:27:21 +0100 Subject: [PATCH 07/23] Support building the plugin zip --- bin/build-plugin-zip.sh | 66 +++++++++++++++++++++-------------------- bin/commander.js | 26 ++++++++++++++-- 2 files changed, 57 insertions(+), 35 deletions(-) diff --git a/bin/build-plugin-zip.sh b/bin/build-plugin-zip.sh index 7e76a2032228c..bcd431a3c62ac 100755 --- a/bin/build-plugin-zip.sh +++ b/bin/build-plugin-zip.sh @@ -28,40 +28,42 @@ warning () { status "💃 Time to release Gutenberg 🕺" -# Make sure there are no changes in the working tree. Release builds should be -# traceable to a particular commit and reliably reproducible. (This is not -# totally true at the moment because we download nightly vendor scripts). -changed= -if ! git diff --exit-code > /dev/null; then - changed="file(s) modified" -elif ! git diff --cached --exit-code > /dev/null; then - changed="file(s) staged" -fi -if [ ! -z "$changed" ]; then - git status - error "ERROR: Cannot build plugin zip with dirty working tree. ☝️ - Commit your changes and try again." - exit 1 -fi - -# Do a dry run of the repository reset. Prompting the user for a list of all -# files that will be removed should prevent them from losing important files! -status "Resetting the repository to pristine condition. ✨" -to_clean=$(git clean -xdf --dry-run) -if [ ! -z "$to_clean" ]; then - echo $to_clean - warning "🚨 About to delete everything above! Is this okay? 🚨" - echo -n "[y]es/[N]o: " - read answer - if [ "$answer" != "${answer#[Yy]}" ]; then - # Remove ignored files to reset repository to pristine condition. Previous - # test ensures that changed files abort the plugin build. - status "Cleaning working directory... 🛀" - git clean -xdf - else - error "Fair enough; aborting. Tidy up your repo and try again. 🙂" +if [ -z "$NO_CHECKS" ]; then + # Make sure there are no changes in the working tree. Release builds should be + # traceable to a particular commit and reliably reproducible. (This is not + # totally true at the moment because we download nightly vendor scripts). + changed= + if ! git diff --exit-code > /dev/null; then + changed="file(s) modified" + elif ! git diff --cached --exit-code > /dev/null; then + changed="file(s) staged" + fi + if [ ! -z "$changed" ]; then + git status + error "ERROR: Cannot build plugin zip with dirty working tree. ☝️ + Commit your changes and try again." exit 1 fi + + # Do a dry run of the repository reset. Prompting the user for a list of all + # files that will be removed should prevent them from losing important files! + status "Resetting the repository to pristine condition. ✨" + to_clean=$(git clean -xdf --dry-run) + if [ ! -z "$to_clean" ]; then + echo $to_clean + warning "🚨 About to delete everything above! Is this okay? 🚨" + echo -n "[y]es/[N]o: " + read answer + if [ "$answer" != "${answer#[Yy]}" ]; then + # Remove ignored files to reset repository to pristine condition. Previous + # test ensures that changed files abort the plugin build. + status "Cleaning working directory... 🛀" + git clean -xdf + else + error "Fair enough; aborting. Tidy up your repo and try again. 🙂" + exit 1 + fi + fi fi # Download all vendor scripts diff --git a/bin/commander.js b/bin/commander.js index 629e64b360728..d0d32663c4b0e 100755 --- a/bin/commander.js +++ b/bin/commander.js @@ -10,6 +10,7 @@ const semver = require( 'semver' ); const chalk = require( 'chalk' ); const fs = require( 'fs' ); const SimpleGit = require( 'simple-git/promise' ); +const childProcess = require( 'child_process' ); // Common info const rootFolder = path.resolve( __dirname, '../' ); @@ -90,7 +91,7 @@ program default: true, } ] ); if ( ! acceptVersion ) { - console.log( error( 'Aborting' ) ); + console.log( error( 'Aborting.' ) ); process.exit( 1 ); } @@ -121,7 +122,7 @@ program default: true, } ] ); if ( ! acceptDiff ) { - console.log( error( 'Aborting. Make sure to remove the local release branch' ) ); + console.log( error( 'Aborting. Make sure to remove the local release branch.' ) ); process.exit( 1 ); } await simpleGit.add( [ @@ -130,8 +131,27 @@ program pluginFilePath, ] ); const { commit } = await simpleGit.commit( 'Bump plugin version to ' + nextVersion ); - console.log( '>> The plugin version bump was commited succesfully. Please push the release branch to the repository and cherry-pick the ' + success( commit ) + ' commit to the master branch.' ); + + const { acceptBuildZip } = await inquirer.prompt( [ { + type: 'confirm', + name: 'acceptBuildZip', + message: 'Proceed and build the plugin zip?', + default: true, + } ] ); + if ( ! acceptBuildZip ) { + console.log( error( 'Aborting. Make sure to remove the local release branch.' ) ); + process.exit( 1 ); + } + childProcess.execSync( '/bin/bash bin/build-plugin-zip.sh', { + cwd: rootFolder, + env: { + NO_CHECKS: true, + PATH: process.env.PATH, + }, + stdio: [ 'inherit', 'ignore', 'inherit' ], + } ); + console.log( '>> The plugin zip was built succesfully 🎉. Path: ' + success( rootFolder + 'gutenberg.zip' ) ); } ); program.parse( process.argv ); From 4c3b5eeb5d35a53afb26254aada312e4e195b152 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Fri, 17 May 2019 15:30:36 +0100 Subject: [PATCH 08/23] Support building the zip --- bin/commander.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/commander.js b/bin/commander.js index d0d32663c4b0e..c1cc271d9d0d6 100755 --- a/bin/commander.js +++ b/bin/commander.js @@ -136,7 +136,7 @@ program const { acceptBuildZip } = await inquirer.prompt( [ { type: 'confirm', name: 'acceptBuildZip', - message: 'Proceed and build the plugin zip?', + message: 'Proceed and build the plugin zip? (It takes a few minutes)', default: true, } ] ); if ( ! acceptBuildZip ) { @@ -151,7 +151,7 @@ program }, stdio: [ 'inherit', 'ignore', 'inherit' ], } ); - console.log( '>> The plugin zip was built succesfully 🎉. Path: ' + success( rootFolder + 'gutenberg.zip' ) ); + console.log( '>> The plugin zip was built succesfully 🎉. Path: ' + success( rootFolder + '/gutenberg.zip' ) ); } ); program.parse( process.argv ); From e4a344b7375aa7e7728b1703c72b9fdad638c287 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Sat, 18 May 2019 10:19:14 +0100 Subject: [PATCH 09/23] Adding a welcome message --- bin/commander.js | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/bin/commander.js b/bin/commander.js index c1cc271d9d0d6..a58cb0307a1be 100755 --- a/bin/commander.js +++ b/bin/commander.js @@ -31,7 +31,24 @@ program .alias( 'rc' ) .description( 'Release an RC version of the plugin (supports only rc.1 for now)' ) .action( async () => { - console.log( '>> 💃 Time to release Gutenberg 🕺' ); + console.log( + chalk.bold( '💃 Time to release Gutenberg 🕺\n\n' ), + 'Welcome! This tool is going to help you release a new RC version of the Gutenberg Plugin.\n', + 'It goes throught different steps : creating the release branch, bumping the plugin version, tagging and creating the github release, building the zip...\n', + 'To perform a release you\'ll have to be a member of the Gutenberg Core Team.\n' + ); + + const { isReady } = await inquirer.prompt( [ { + type: 'confirm', + name: 'isReady', + message: 'Ready go go?', + default: true, + } ] ); + + if ( ! isReady ) { + console.log( error( 'Aborting' ) ); + process.exit( 1 ); + } // Check the current branch and if the versions const gitStatus = await simpleGit.status(); From 4fd4090a49d5df8c786f60f5333d97437e74f6db Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Sat, 18 May 2019 10:40:54 +0100 Subject: [PATCH 10/23] Consistency for the confirmation messages --- bin/commander.js | 111 ++++++++++++++++++++--------------------------- 1 file changed, 47 insertions(+), 64 deletions(-) diff --git a/bin/commander.js b/bin/commander.js index a58cb0307a1be..bf6bf77e4e588 100755 --- a/bin/commander.js +++ b/bin/commander.js @@ -26,6 +26,29 @@ const error = chalk.bold.red; const warning = chalk.bold.keyword( 'orange' ); const success = chalk.bold.green; +// Utils + +/** + * Asks the user for a confirmation to continue or abort otherwise + * + * @param {string} message Confirmation message + * @param {boolean} isDefault Default reply + * @param {string} abortMessage Abort message + */ +const askForConfirmationToContinue = async ( message, isDefault = true, abortMessage = 'Aborting.' ) => { + const { isReady } = await inquirer.prompt( [ { + type: 'confirm', + name: 'isReady', + default: isDefault, + message, + } ] ); + + if ( ! isReady ) { + console.log( error( '\n' + abortMessage ) ); + process.exit( 1 ); + } +}; + program .command( 'release-plugin-rc' ) .alias( 'rc' ) @@ -38,46 +61,23 @@ program 'To perform a release you\'ll have to be a member of the Gutenberg Core Team.\n' ); - const { isReady } = await inquirer.prompt( [ { - type: 'confirm', - name: 'isReady', - message: 'Ready go go?', - default: true, - } ] ); - - if ( ! isReady ) { - console.log( error( 'Aborting' ) ); - process.exit( 1 ); - } + await askForConfirmationToContinue( 'Ready go go? ' ); // Check the current branch and if the versions const gitStatus = await simpleGit.status(); const parsedVersion = semver.parse( packageJson.version ); if ( gitStatus.current !== 'master' ) { - const { acceptBranch } = await inquirer.prompt( [ { - type: 'confirm', - name: 'acceptBranch', - message: 'Releasing plugin RC versions usually happens from the ' + warning( 'master' ) + ' branch. Do you want to continue from the current branch?', - default: false, - } ] ); - - if ( ! acceptBranch ) { - console.log( error( 'Aborting' ) ); - process.exit( 1 ); - } + await askForConfirmationToContinue( + 'Releasing plugin RC versions usually happens from the ' + warning( 'master' ) + ' branch. Do you want to continue from the current branch?', + false, + ); } + if ( gitStatus.files.length ) { - const { acceptLocalChanges } = await inquirer.prompt( [ { - type: 'confirm', - name: 'acceptLocalChanges', - message: 'Your working tree is dirty. Do you want to continue? (you may loose uncommited changes).', - default: false, - } ] ); - - if ( ! acceptLocalChanges ) { - console.log( error( 'Aborting' ) ); - process.exit( 1 ); - } + await askForConfirmationToContinue( + 'Your working tree is dirty. Do you want to continue? (you may loose uncommited changes).', + false, + ); } // Cleaning the repository @@ -101,20 +101,13 @@ program nextVersion = parsedVersion.major + '.' + ( parsedVersion.minor + 1 ) + '.0-rc.1'; releaseBranch = 'release/' + parsedVersion.major + '.' + ( parsedVersion.minor + 1 ); } - const { acceptVersion } = await inquirer.prompt( [ { - type: 'confirm', - name: 'acceptVersion', - message: 'The RC Version to be applied is ' + success( nextVersion ) + '. Proceed with the creation of the release branch?', - default: true, - } ] ); - if ( ! acceptVersion ) { - console.log( error( 'Aborting.' ) ); - process.exit( 1 ); - } + await askForConfirmationToContinue( + 'The RC Version to be applied is ' + success( nextVersion ) + '. Proceed with the creation of the release branch?' + ); // Creating the release branch await simpleGit.checkoutLocalBranch( releaseBranch ); - console.log( '>> The local release branch "' + success( releaseBranch ) + '" has been successfully created.' ); + console.log( '>> The local release branch ' + success( releaseBranch ) + ' has been successfully created.' ); // Bumping the version in the different files (package.json, package-lock.json, gutenberg.php) const newPackageJson = { @@ -132,16 +125,11 @@ program console.log( '>> The plugin version has been updated successfully.' ); // Commit the version bump - const { acceptDiff } = await inquirer.prompt( [ { - type: 'confirm', - name: 'acceptDiff', - message: 'Please check the diff. Proceed with the version bump commit?', - default: true, - } ] ); - if ( ! acceptDiff ) { - console.log( error( 'Aborting. Make sure to remove the local release branch.' ) ); - process.exit( 1 ); - } + await askForConfirmationToContinue( + 'Please check the diff. Proceed with the version bump commit?', + true, + 'Aborting. Make sure to remove the local release branch.' + ); await simpleGit.add( [ packageJsonPath, packageLockPath, @@ -150,16 +138,11 @@ program const { commit } = await simpleGit.commit( 'Bump plugin version to ' + nextVersion ); console.log( '>> The plugin version bump was commited succesfully. Please push the release branch to the repository and cherry-pick the ' + success( commit ) + ' commit to the master branch.' ); - const { acceptBuildZip } = await inquirer.prompt( [ { - type: 'confirm', - name: 'acceptBuildZip', - message: 'Proceed and build the plugin zip? (It takes a few minutes)', - default: true, - } ] ); - if ( ! acceptBuildZip ) { - console.log( error( 'Aborting. Make sure to remove the local release branch.' ) ); - process.exit( 1 ); - } + await askForConfirmationToContinue( + 'Proceed and build the plugin zip? (It takes a few minutes)', + true, + 'Aborting. Make sure to remove the local release branch.' + ); childProcess.execSync( '/bin/bash bin/build-plugin-zip.sh', { cwd: rootFolder, env: { From 8c689a7d3555b91c0794dc255fb1c4ceda8e7a88 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Sat, 18 May 2019 11:09:19 +0100 Subject: [PATCH 11/23] Better error handling --- bin/commander.js | 213 ++++++++++++++++++++++++++++------------------- 1 file changed, 127 insertions(+), 86 deletions(-) diff --git a/bin/commander.js b/bin/commander.js index bf6bf77e4e588..6e4789dbca999 100755 --- a/bin/commander.js +++ b/bin/commander.js @@ -31,9 +31,9 @@ const success = chalk.bold.green; /** * Asks the user for a confirmation to continue or abort otherwise * - * @param {string} message Confirmation message - * @param {boolean} isDefault Default reply - * @param {string} abortMessage Abort message + * @param {string} message Confirmation message. + * @param {boolean} isDefault Default reply. + * @param {string} abortMessage Abort message. */ const askForConfirmationToContinue = async ( message, isDefault = true, abortMessage = 'Aborting.' ) => { const { isReady } = await inquirer.prompt( [ { @@ -49,6 +49,27 @@ const askForConfirmationToContinue = async ( message, isDefault = true, abortMes } }; +/** + * Common logic wrapping a step in the process. + * + * @param {string} name Step name. + * @param {string} abortMessage Abort message. + * @param {function} handler Step logic. + */ +const runStep = async ( name, abortMessage, handler ) => { + try { + await handler(); + } catch ( exception ) { + console.log( + error( 'The following error happened during the step: ' ) + warning( name ) + '\n\n', + exception, + error( '\n' + abortMessage ) + ); + + process.exit( 1 ); + } +}; + program .command( 'release-plugin-rc' ) .alias( 'rc' ) @@ -61,97 +82,117 @@ program 'To perform a release you\'ll have to be a member of the Gutenberg Core Team.\n' ); - await askForConfirmationToContinue( 'Ready go go? ' ); - - // Check the current branch and if the versions - const gitStatus = await simpleGit.status(); - const parsedVersion = semver.parse( packageJson.version ); - if ( gitStatus.current !== 'master' ) { - await askForConfirmationToContinue( - 'Releasing plugin RC versions usually happens from the ' + warning( 'master' ) + ' branch. Do you want to continue from the current branch?', - false, - ); - } - - if ( gitStatus.files.length ) { - await askForConfirmationToContinue( - 'Your working tree is dirty. Do you want to continue? (you may loose uncommited changes).', - false, - ); - } + // This is a variable that contains the abort message shown when the script is aborted. + let abortMessage = 'Aborting!'; + + // Initial checks + await runStep( 'Initial checks', abortMessage, async () => { + await askForConfirmationToContinue( 'Ready go go? ' ); + // Check the current branch and if the versions + const gitStatus = await simpleGit.status(); + if ( gitStatus.current !== 'master' ) { + await askForConfirmationToContinue( + 'Releasing plugin RC versions usually happens from the ' + warning( 'master' ) + ' branch. Do you want to continue from the current branch?', + false, + abortMessage + ); + } + + if ( gitStatus.files.length ) { + await askForConfirmationToContinue( + 'Your working tree is dirty. Do you want to continue? (you may loose uncommited changes).', + false, + abortMessage + ); + } + } ); // Cleaning the repository - const { skipCleaning } = await inquirer.prompt( [ { - type: 'confirm', - name: 'skipCleaning', - message: 'Your working tree is going to be cleaned. Uncommited changes will be lost. Do you want to skip?', - default: false, - } ] ); - if ( ! skipCleaning ) { - await simpleGit.clean( 'xfd' ); - } - - // Choosing the right version + await runStep( 'Cleaning the repository', abortMessage, async () => { + const { skipCleaning } = await inquirer.prompt( [ { + type: 'confirm', + name: 'skipCleaning', + message: 'Your working tree is going to be cleaned. Uncommited changes will be lost. Do you want to skip?', + default: false, + } ] ); + if ( ! skipCleaning ) { + await simpleGit.clean( 'xfd' ); + } + } ); + + // Creating the release branch let nextVersion; let releaseBranch; - if ( parsedVersion.minor === 9 ) { - nextVersion = ( parsedVersion.major + 1 ) + '.0.0-rc.1'; - releaseBranch = 'release/' + ( parsedVersion.major + 1 ) + '.0'; - } else { - nextVersion = parsedVersion.major + '.' + ( parsedVersion.minor + 1 ) + '.0-rc.1'; - releaseBranch = 'release/' + parsedVersion.major + '.' + ( parsedVersion.minor + 1 ); - } - await askForConfirmationToContinue( - 'The RC Version to be applied is ' + success( nextVersion ) + '. Proceed with the creation of the release branch?' - ); + await runStep( 'Creating the release branch', abortMessage, async () => { + const parsedVersion = semver.parse( packageJson.version ); + if ( parsedVersion.minor === 9 ) { + nextVersion = ( parsedVersion.major + 1 ) + '.0.0-rc.1'; + releaseBranch = 'release/' + ( parsedVersion.major + 1 ) + '.0'; + } else { + nextVersion = parsedVersion.major + '.' + ( parsedVersion.minor + 1 ) + '.0-rc.1'; + releaseBranch = 'release/' + parsedVersion.major + '.' + ( parsedVersion.minor + 1 ); + } + await askForConfirmationToContinue( + 'The RC Version to be applied is ' + success( nextVersion ) + '. Proceed with the creation of the release branch?', + true, + abortMessage + ); - // Creating the release branch - await simpleGit.checkoutLocalBranch( releaseBranch ); - console.log( '>> The local release branch ' + success( releaseBranch ) + ' has been successfully created.' ); + // Creating the release branch + await simpleGit.checkoutLocalBranch( releaseBranch ); + console.log( '>> The local release branch ' + success( releaseBranch ) + ' has been successfully created.' ); + } ); + abortMessage = 'Aborting. Make sure to remove the local release branch.'; // Bumping the version in the different files (package.json, package-lock.json, gutenberg.php) - const newPackageJson = { - ...packageJson, - version: nextVersion, - }; - fs.writeFileSync( packageJsonPath, JSON.stringify( newPackageJson, null, '\t' ) + '\n' ); - const newPackageLock = { - ...packageLock, - version: nextVersion, - }; - fs.writeFileSync( packageLockPath, JSON.stringify( newPackageLock, null, '\t' ) + '\n' ); - const content = fs.readFileSync( pluginFilePath, 'utf8' ); - fs.writeFileSync( pluginFilePath, content.replace( ' * Version: ' + packageJson.version, ' * Version: ' + nextVersion ) ); - console.log( '>> The plugin version has been updated successfully.' ); - - // Commit the version bump - await askForConfirmationToContinue( - 'Please check the diff. Proceed with the version bump commit?', - true, - 'Aborting. Make sure to remove the local release branch.' - ); - await simpleGit.add( [ - packageJsonPath, - packageLockPath, - pluginFilePath, - ] ); - const { commit } = await simpleGit.commit( 'Bump plugin version to ' + nextVersion ); - console.log( '>> The plugin version bump was commited succesfully. Please push the release branch to the repository and cherry-pick the ' + success( commit ) + ' commit to the master branch.' ); - - await askForConfirmationToContinue( - 'Proceed and build the plugin zip? (It takes a few minutes)', - true, - 'Aborting. Make sure to remove the local release branch.' - ); - childProcess.execSync( '/bin/bash bin/build-plugin-zip.sh', { - cwd: rootFolder, - env: { - NO_CHECKS: true, - PATH: process.env.PATH, - }, - stdio: [ 'inherit', 'ignore', 'inherit' ], + await runStep( 'Updating the plugin version', abortMessage, async () => { + const newPackageJson = { + ...packageJson, + version: nextVersion, + }; + fs.writeFileSync( packageJsonPath, JSON.stringify( newPackageJson, null, '\t' ) + '\n' ); + const newPackageLock = { + ...packageLock, + version: nextVersion, + }; + fs.writeFileSync( packageLockPath, JSON.stringify( newPackageLock, null, '\t' ) + '\n' ); + const content = fs.readFileSync( pluginFilePath, 'utf8' ); + fs.writeFileSync( pluginFilePath, content.replace( ' * Version: ' + packageJson.version, ' * Version: ' + nextVersion ) ); + console.log( '>> The plugin version has been updated successfully.' ); + + // Commit the version bump + await askForConfirmationToContinue( + 'Please check the diff. Proceed with the version bump commit?', + true, + abortMessage + ); + await simpleGit.add( [ + packageJsonPath, + packageLockPath, + pluginFilePath, + ] ); + const { commit } = await simpleGit.commit( 'Bump plugin version to ' + nextVersion ); + console.log( '>> The plugin version bump was commited succesfully. Please push the release branch to the repository and cherry-pick the ' + success( commit ) + ' commit to the master branch.' ); + } ); + + // Plugin ZIP creation + await runStep( 'Plugin ZIP creation', abortMessage, async () => { + await askForConfirmationToContinue( + 'Proceed and build the plugin zip? (It takes a few minutes)', + true, + abortMessage + ); + childProcess.execSync( '/bin/bash bin/build-plugin-zip.sh', { + cwd: rootFolder, + env: { + NO_CHECKS: true, + PATH: process.env.PATH, + }, + stdio: [ 'inherit', 'ignore', 'inherit' ], + } ); + + console.log( '>> The plugin zip was built succesfully 🎉. Path: ' + success( rootFolder + '/gutenberg.zip' ) ); } ); - console.log( '>> The plugin zip was built succesfully 🎉. Path: ' + success( rootFolder + '/gutenberg.zip' ) ); } ); program.parse( process.argv ); From 180207c6602a92ed869da7d8325c716ee059d561 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Sat, 18 May 2019 11:14:49 +0100 Subject: [PATCH 12/23] Creating the release tag --- bin/commander.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/bin/commander.js b/bin/commander.js index 6e4789dbca999..4e43ae8cb70fb 100755 --- a/bin/commander.js +++ b/bin/commander.js @@ -175,6 +175,19 @@ program console.log( '>> The plugin version bump was commited succesfully. Please push the release branch to the repository and cherry-pick the ' + success( commit ) + ' commit to the master branch.' ); } ); + // Creating the release tag + await runStep( 'Creating the release tag', abortMessage, async () => { + // Commit the version bump + await askForConfirmationToContinue( + 'Proceed with the creation of the release tag?', + true, + abortMessage + ); + await simpleGit.addTag( 'v' + nextVersion ); + console.log( '>> The ' + success( 'v' + nextVersion ) + ' tag was created succesfully.' ); + } ); + abortMessage = 'Aborting. Make sure to remove the local release branch and the local release tag.'; + // Plugin ZIP creation await runStep( 'Plugin ZIP creation', abortMessage, async () => { await askForConfirmationToContinue( From ba3f0d916f150a98a40e5caa691a969575c23554 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Sat, 18 May 2019 13:18:02 +0100 Subject: [PATCH 13/23] Add the GitHub release and the remote branch/tag --- bin/commander.js | 132 +++++++++++++++++++++++++++++++++++++++------- package-lock.json | 108 +++++++++++++++++++++++++------------ package.json | 1 + 3 files changed, 188 insertions(+), 53 deletions(-) diff --git a/bin/commander.js b/bin/commander.js index 4e43ae8cb70fb..89dabe45b7f7e 100755 --- a/bin/commander.js +++ b/bin/commander.js @@ -11,6 +11,7 @@ const chalk = require( 'chalk' ); const fs = require( 'fs' ); const SimpleGit = require( 'simple-git/promise' ); const childProcess = require( 'child_process' ); +const Octokit = require( '@octokit/rest' ); // Common info const rootFolder = path.resolve( __dirname, '../' ); @@ -20,6 +21,9 @@ const pluginFilePath = rootFolder + '/gutenberg.php'; const packageJson = require( packageJsonPath ); const packageLock = require( packageLockPath ); const simpleGit = SimpleGit( rootFolder ); +const gutenbergZipPath = rootFolder + '/gutenberg.zip'; +const gitRemote = 'origin'; +const repoOwner = 'WordPress'; // UI const error = chalk.bold.red; @@ -61,9 +65,9 @@ const runStep = async ( name, abortMessage, handler ) => { await handler(); } catch ( exception ) { console.log( - error( 'The following error happened during the step: ' ) + warning( name ) + '\n\n', + error( 'The following error happened during the "' + warning( name ) + '" step:' ) + '\n\n', exception, - error( '\n' + abortMessage ) + error( '\n\n' + abortMessage ) ); process.exit( 1 ); @@ -112,7 +116,7 @@ program const { skipCleaning } = await inquirer.prompt( [ { type: 'confirm', name: 'skipCleaning', - message: 'Your working tree is going to be cleaned. Uncommited changes will be lost. Do you want to skip?', + message: 'Your working tree is going to be cleaned. Uncommited changes will be lost. Do you want to skip this step?', default: false, } ] ); if ( ! skipCleaning ) { @@ -122,15 +126,18 @@ program // Creating the release branch let nextVersion; + let nextVersionLabel; let releaseBranch; await runStep( 'Creating the release branch', abortMessage, async () => { const parsedVersion = semver.parse( packageJson.version ); if ( parsedVersion.minor === 9 ) { nextVersion = ( parsedVersion.major + 1 ) + '.0.0-rc.1'; releaseBranch = 'release/' + ( parsedVersion.major + 1 ) + '.0'; + nextVersionLabel = ( parsedVersion.major + 1 ) + '.0.0 RC1'; } else { nextVersion = parsedVersion.major + '.' + ( parsedVersion.minor + 1 ) + '.0-rc.1'; releaseBranch = 'release/' + parsedVersion.major + '.' + ( parsedVersion.minor + 1 ); + nextVersionLabel = parsedVersion.major + '.' + ( parsedVersion.minor + 1 ) + '.0 RC1'; } await askForConfirmationToContinue( 'The RC Version to be applied is ' + success( nextVersion ) + '. Proceed with the creation of the release branch?', @@ -145,6 +152,7 @@ program abortMessage = 'Aborting. Make sure to remove the local release branch.'; // Bumping the version in the different files (package.json, package-lock.json, gutenberg.php) + let commitHash; await runStep( 'Updating the plugin version', abortMessage, async () => { const newPackageJson = { ...packageJson, @@ -171,23 +179,11 @@ program packageLockPath, pluginFilePath, ] ); - const { commit } = await simpleGit.commit( 'Bump plugin version to ' + nextVersion ); - console.log( '>> The plugin version bump was commited succesfully. Please push the release branch to the repository and cherry-pick the ' + success( commit ) + ' commit to the master branch.' ); + const commitData = await simpleGit.commit( 'Bump plugin version to ' + nextVersion ); + commitHash = commitData.commit; + console.log( '>> The plugin version bump has been commited succesfully.' ); } ); - // Creating the release tag - await runStep( 'Creating the release tag', abortMessage, async () => { - // Commit the version bump - await askForConfirmationToContinue( - 'Proceed with the creation of the release tag?', - true, - abortMessage - ); - await simpleGit.addTag( 'v' + nextVersion ); - console.log( '>> The ' + success( 'v' + nextVersion ) + ' tag was created succesfully.' ); - } ); - abortMessage = 'Aborting. Make sure to remove the local release branch and the local release tag.'; - // Plugin ZIP creation await runStep( 'Plugin ZIP creation', abortMessage, async () => { await askForConfirmationToContinue( @@ -204,8 +200,106 @@ program stdio: [ 'inherit', 'ignore', 'inherit' ], } ); - console.log( '>> The plugin zip was built succesfully 🎉. Path: ' + success( rootFolder + '/gutenberg.zip' ) ); + console.log( '>> The plugin zip has been built succesfully. Path: ' + success( gutenbergZipPath ) ); + } ); + + // Creating the git tag + await runStep( 'Creating the git tag', abortMessage, async () => { + await askForConfirmationToContinue( + 'Proceed with the creation of the git tag?', + true, + abortMessage + ); + await simpleGit.addTag( 'v' + nextVersion ); + console.log( '>> The ' + success( 'v' + nextVersion ) + ' tag has been created succesfully.' ); + } ); + abortMessage = 'Aborting. Make sure to remove the local release branch and the local git tag.'; + + await runStep( 'Pushing the release branch and the tag', abortMessage, async () => { + await askForConfirmationToContinue( + 'The release branch and the tag are going to be pushed to the remote repository. Continue?', + true, + abortMessage + ); + await simpleGit.push( gitRemote, releaseBranch ); + await simpleGit.pushTags( gitRemote ); } ); + abortMessage = 'Aborting. Make sure to remove the local and remote release branches and tags.'; + + // Creating the GitHub Release + let octokit; + let release; + await runStep( 'Creating the Github release', abortMessage, async () => { + await askForConfirmationToContinue( + 'Proceed with the creation of the Github release?', + true, + abortMessage + ); + const { changelog } = await inquirer.prompt( [ { + type: 'editor', + name: 'changelog', + message: 'Please provide the CHANGELOG of the release (markdown)', + } ] ); + + const { token } = await inquirer.prompt( [ { + type: 'input', + name: 'token', + message: 'Please provide a Github personal authentication token. (Navigate to ' + success( 'https://github.com/settings/tokens' ) + ' to create one with admin:org, repo and write:packages rights)', + } ] ); + + octokit = new Octokit( { + auth: token, + } ); + + const releaseData = await octokit.repos.createRelease( { + owner: repoOwner, + repo: 'gutenberg', + tag_name: 'v' + nextVersion, + name: nextVersionLabel, + body: changelog, + prerelease: true, + } ); + release = releaseData.data; + + console.log( '>> The Github release has been created succesfully.' ); + } ); + abortMessage = 'Aborting. Make sure to remove the local and remote releases branches and tags and the Github release.'; + + // Uploading the Gutenberg Zip to the release + await runStep( 'Uploading the plugin zip', abortMessage, async () => { + const filestats = fs.statSync( gutenbergZipPath ); + await octokit.repos.uploadReleaseAsset( { + url: release.upload_url, + headers: { + 'content-length': filestats.size, + 'content-type': 'application/zip', + }, + name: 'gutenberg.zip', + file: fs.createReadStream( gutenbergZipPath ), + } ); + console.log( '>> The plugin zip has been succesfully uploaded.' ); + } ); + abortMessage = 'Aborting. Make sure to manually cherry-pick the ' + success( commitHash ) + ' commit to the master branch.'; + + // Cherry-picking the bump commit into master + await runStep( 'Cherry-picking the bump commit into master', abortMessage, async () => { + await askForConfirmationToContinue( + 'The plugin RC is now released. Proceed with the version bump in the master branch?', + true, + 'test' + ); + await simpleGit.fetch(); + await simpleGit.checkout( 'master' ); + await simpleGit.pull( gitRemote, 'master' ); + await simpleGit.raw( [ 'cherry-pick', commitHash ] ); + await simpleGit.push( gitRemote, 'master' ); + } ); + + console.log( + '\n>> 🎉 The Gutenberg ' + success( nextVersionLabel ) + ' has been successfully released.\n', + 'You can access the Github release here: ' + success( release.html_url ) + '\n', + 'Thanks for performing the release!' + ); } ); program.parse( process.argv ); diff --git a/package-lock.json b/package-lock.json index 56213d3fe64b1..534bf25c0805f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2551,14 +2551,14 @@ "dev": true }, "@octokit/endpoint": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-4.0.0.tgz", - "integrity": "sha512-b8sptNUekjREtCTJFpOfSIL4SKh65WaakcyxWzRcSPOk5RxkZJ/S8884NGZFxZ+jCB2rDURU66pSHn14cVgWVg==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-5.1.2.tgz", + "integrity": "sha512-bBGGmcRFq1x0jrB29G/9KjYmO3cdHfk3476B2JOHRvLsNw1Pn3l+ZvbiqtcO9qAS4Ti+zFedLB84ziHZRZclQA==", "dev": true, "requires": { "deepmerge": "3.2.0", - "is-plain-object": "^2.0.4", - "universal-user-agent": "^2.0.1", + "is-plain-object": "^3.0.0", + "universal-user-agent": "^2.1.0", "url-template": "^2.0.8" }, "dependencies": { @@ -2567,6 +2567,21 @@ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-3.2.0.tgz", "integrity": "sha512-6+LuZGU7QCNUnAJyX8cIrlzoEgggTM6B7mm+znKOX4t5ltluT9KLjN6g61ECMS0LTsLW7yDpNoxhix5FZcrIow==", "dev": true + }, + "is-plain-object": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.0.tgz", + "integrity": "sha512-tZIpofR+P05k8Aocp7UI/2UTa9lTJSebCXpFFoR9aibpokDj/uXBsJ8luUu0tTVYKkMU6URDUuOfJZ7koewXvg==", + "dev": true, + "requires": { + "isobject": "^4.0.0" + } + }, + "isobject": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz", + "integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==", + "dev": true } } }, @@ -2577,38 +2592,65 @@ "dev": true }, "@octokit/request": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-3.0.0.tgz", - "integrity": "sha512-DZqmbm66tq+a9FtcKrn0sjrUpi0UaZ9QPUCxxyk/4CJ2rseTMpAWRf6gCwOSUCzZcx/4XVIsDk+kz5BVdaeenA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-4.1.0.tgz", + "integrity": "sha512-RvpQAba4i+BNH0z8i0gPRc1ShlHidj4puQjI/Tno6s+Q3/Mzb0XRSHJiOhpeFrZ22V7Mwjq1E7QS27P5CgpWYA==", "dev": true, "requires": { - "@octokit/endpoint": "^4.0.0", - "deprecation": "^1.0.1", - "is-plain-object": "^2.0.4", + "@octokit/endpoint": "^5.1.0", + "@octokit/request-error": "^1.0.1", + "deprecation": "^2.0.0", + "is-plain-object": "^3.0.0", "node-fetch": "^2.3.0", "once": "^1.4.0", - "universal-user-agent": "^2.0.1" + "universal-user-agent": "^2.1.0" }, "dependencies": { + "is-plain-object": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.0.tgz", + "integrity": "sha512-tZIpofR+P05k8Aocp7UI/2UTa9lTJSebCXpFFoR9aibpokDj/uXBsJ8luUu0tTVYKkMU6URDUuOfJZ7koewXvg==", + "dev": true, + "requires": { + "isobject": "^4.0.0" + } + }, + "isobject": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz", + "integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==", + "dev": true + }, "node-fetch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.3.0.tgz", - "integrity": "sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", + "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==", "dev": true } } }, + "@octokit/request-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-1.0.2.tgz", + "integrity": "sha512-T9swMS/Vc4QlfWrvyeSyp/GjhXtYaBzCcibjGywV4k4D2qVrQKfEMPy8OxMDEj7zkIIdpHwqdpVbKCvnUPqkXw==", + "dev": true, + "requires": { + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, "@octokit/rest": { - "version": "16.24.1", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-16.24.1.tgz", - "integrity": "sha512-V2GVL+cfuwNTcZ9qtBMOR9pIftWo1AiZIiGvWNmTcIQG5mkj83ZXC+g3w5g0cVXt7Hi+mSOrD2bZ7HJOuouUNg==", + "version": "16.26.0", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-16.26.0.tgz", + "integrity": "sha512-NBpzre44ZAQWZhlH+zUYTgqI0pHN+c9rNj4d+pCydGEiKTGc1HKmoTghEUyr9GxazDyoAvmpx9nL0I7QS1Olvg==", "dev": true, "requires": { - "@octokit/request": "3.0.0", + "@octokit/request": "^4.0.1", + "@octokit/request-error": "^1.0.2", "atob-lite": "^2.0.0", "before-after-hook": "^1.4.0", "btoa-lite": "^1.0.0", - "deprecation": "^1.0.1", + "deprecation": "^2.0.0", "lodash.get": "^4.4.2", "lodash.set": "^4.3.2", "lodash.uniq": "^4.5.0", @@ -7931,9 +7973,9 @@ "dev": true }, "deprecation": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-1.0.1.tgz", - "integrity": "sha512-ccVHpE72+tcIKaGMql33x5MAjKQIZrk+3x2GbJ7TeraUCZWHoT+KSZpoC+JQFsUBlSTXUrBaGiF0j6zVTepPLg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.0.0.tgz", + "integrity": "sha512-lbQN037mB3VfA2JFuguM5GCJ+zPinMeCrFe+AfSZ6eqrnJA/Fs+EYMnd6Nb2mn9lf2jO9xwEd9o9lic+D4vkcw==", "dev": true }, "des.js": { @@ -22329,9 +22371,9 @@ } }, "universal-user-agent": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-2.0.3.tgz", - "integrity": "sha512-eRHEHhChCBHrZsA4WEhdgiOKgdvgrMIHwnwnqD0r5C6AO8kwKcG7qSku3iXdhvHL3YvsS9ZkSGN8h/hIpoFC8g==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-2.1.0.tgz", + "integrity": "sha512-8itiX7G05Tu3mGDTdNY2fB4KJ8MgZLS54RdG6PkkfwMAavrXu1mV/lls/GABx9O3Rw4PnTtasxrvbMQoBYY92Q==", "dev": true, "requires": { "os-name": "^3.0.0" @@ -23607,14 +23649,6 @@ "semver": "^5.5.0", "shebang-command": "^1.2.0", "which": "^1.2.9" - }, - "dependencies": { - "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", - "dev": true - } } }, "execa": { @@ -23650,6 +23684,12 @@ "end-of-stream": "^1.1.0", "once": "^1.3.1" } + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true } } }, diff --git a/package.json b/package.json index cd650afadd647..e48a3ff8a0273 100644 --- a/package.json +++ b/package.json @@ -61,6 +61,7 @@ "@babel/plugin-syntax-jsx": "7.2.0", "@babel/runtime-corejs3": "7.4.4", "@babel/traverse": "7.4.4", + "@octokit/rest": "16.26.0", "@wordpress/babel-plugin-import-jsx-pragma": "file:packages/babel-plugin-import-jsx-pragma", "@wordpress/babel-plugin-makepot": "file:packages/babel-plugin-makepot", "@wordpress/babel-preset-default": "file:packages/babel-preset-default", From 581960ca4f558dce159bd7b3e9c1c719c2298398 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Sat, 18 May 2019 18:47:40 +0100 Subject: [PATCH 14/23] Update the release CLI to use a separate repo clone --- bin/commander.js | 85 ++++++++++---------------- package-lock.json | 152 +++++++++++++++++++++++++++++++++++++++++++++- package.json | 1 + 3 files changed, 182 insertions(+), 56 deletions(-) diff --git a/bin/commander.js b/bin/commander.js index 89dabe45b7f7e..b92d18e9b97b1 100755 --- a/bin/commander.js +++ b/bin/commander.js @@ -8,22 +8,21 @@ const program = require( 'commander' ); const inquirer = require( 'inquirer' ); const semver = require( 'semver' ); const chalk = require( 'chalk' ); -const fs = require( 'fs' ); +const fs = require( 'fs-extra' ); const SimpleGit = require( 'simple-git/promise' ); const childProcess = require( 'child_process' ); const Octokit = require( '@octokit/rest' ); +const os = require( 'os' ); +const uuid = require( 'uuid/v4' ); // Common info -const rootFolder = path.resolve( __dirname, '../' ); -const packageJsonPath = rootFolder + '/package.json'; -const packageLockPath = rootFolder + '/package-lock.json'; -const pluginFilePath = rootFolder + '/gutenberg.php'; -const packageJson = require( packageJsonPath ); -const packageLock = require( packageLockPath ); -const simpleGit = SimpleGit( rootFolder ); -const gutenbergZipPath = rootFolder + '/gutenberg.zip'; -const gitRemote = 'origin'; +const workingDirectoryPath = path.join( os.tmpdir(), uuid() ); +const packageJsonPath = workingDirectoryPath + '/package.json'; +const packageLockPath = workingDirectoryPath + '/package-lock.json'; +const pluginFilePath = workingDirectoryPath + '/gutenberg.php'; +const gutenbergZipPath = workingDirectoryPath + '/gutenberg.zip'; const repoOwner = 'WordPress'; +const repoURL = 'git@github.com:' + repoOwner + '/gutenberg.git'; // UI const error = chalk.bold.red; @@ -88,46 +87,23 @@ program // This is a variable that contains the abort message shown when the script is aborted. let abortMessage = 'Aborting!'; + await askForConfirmationToContinue( 'Ready go go? ' ); - // Initial checks - await runStep( 'Initial checks', abortMessage, async () => { - await askForConfirmationToContinue( 'Ready go go? ' ); - // Check the current branch and if the versions - const gitStatus = await simpleGit.status(); - if ( gitStatus.current !== 'master' ) { - await askForConfirmationToContinue( - 'Releasing plugin RC versions usually happens from the ' + warning( 'master' ) + ' branch. Do you want to continue from the current branch?', - false, - abortMessage - ); - } - - if ( gitStatus.files.length ) { - await askForConfirmationToContinue( - 'Your working tree is dirty. Do you want to continue? (you may loose uncommited changes).', - false, - abortMessage - ); - } - } ); - - // Cleaning the repository - await runStep( 'Cleaning the repository', abortMessage, async () => { - const { skipCleaning } = await inquirer.prompt( [ { - type: 'confirm', - name: 'skipCleaning', - message: 'Your working tree is going to be cleaned. Uncommited changes will be lost. Do you want to skip this step?', - default: false, - } ] ); - if ( ! skipCleaning ) { - await simpleGit.clean( 'xfd' ); - } + // Cloning the repository + await runStep( 'Cloning the repository', abortMessage, async () => { + console.log( '>> Cloning the repository' ); + const simpleGit = SimpleGit(); + await simpleGit.clone( repoURL, workingDirectoryPath ); + console.log( '>> The gutenberg repository has been successfully cloned in the following temporary folder: ' + success( workingDirectoryPath ) ); } ); // Creating the release branch + const simpleGit = SimpleGit( workingDirectoryPath ); let nextVersion; let nextVersionLabel; let releaseBranch; + const packageJson = require( packageJsonPath ); + const packageLock = require( packageLockPath ); await runStep( 'Creating the release branch', abortMessage, async () => { const parsedVersion = semver.parse( packageJson.version ); if ( parsedVersion.minor === 9 ) { @@ -149,7 +125,6 @@ program await simpleGit.checkoutLocalBranch( releaseBranch ); console.log( '>> The local release branch ' + success( releaseBranch ) + ' has been successfully created.' ); } ); - abortMessage = 'Aborting. Make sure to remove the local release branch.'; // Bumping the version in the different files (package.json, package-lock.json, gutenberg.php) let commitHash; @@ -192,7 +167,7 @@ program abortMessage ); childProcess.execSync( '/bin/bash bin/build-plugin-zip.sh', { - cwd: rootFolder, + cwd: workingDirectoryPath, env: { NO_CHECKS: true, PATH: process.env.PATH, @@ -213,7 +188,6 @@ program await simpleGit.addTag( 'v' + nextVersion ); console.log( '>> The ' + success( 'v' + nextVersion ) + ' tag has been created succesfully.' ); } ); - abortMessage = 'Aborting. Make sure to remove the local release branch and the local git tag.'; await runStep( 'Pushing the release branch and the tag', abortMessage, async () => { await askForConfirmationToContinue( @@ -221,10 +195,10 @@ program true, abortMessage ); - await simpleGit.push( gitRemote, releaseBranch ); - await simpleGit.pushTags( gitRemote ); + await simpleGit.push( 'origin', releaseBranch ); + await simpleGit.pushTags( 'origin' ); } ); - abortMessage = 'Aborting. Make sure to remove the local and remote release branches and tags.'; + abortMessage = 'Aborting! Make sure to remove remote release branch and tag.'; // Creating the GitHub Release let octokit; @@ -263,7 +237,7 @@ program console.log( '>> The Github release has been created succesfully.' ); } ); - abortMessage = 'Aborting. Make sure to remove the local and remote releases branches and tags and the Github release.'; + abortMessage = 'Aborting! Make sure to remove the remote release branch, the git tag and the Github release.'; // Uploading the Gutenberg Zip to the release await runStep( 'Uploading the plugin zip', abortMessage, async () => { @@ -279,7 +253,7 @@ program } ); console.log( '>> The plugin zip has been succesfully uploaded.' ); } ); - abortMessage = 'Aborting. Make sure to manually cherry-pick the ' + success( commitHash ) + ' commit to the master branch.'; + abortMessage = 'Aborting! Make sure to manually cherry-pick the ' + success( commitHash ) + ' commit to the master branch.'; // Cherry-picking the bump commit into master await runStep( 'Cherry-picking the bump commit into master', abortMessage, async () => { @@ -290,9 +264,14 @@ program ); await simpleGit.fetch(); await simpleGit.checkout( 'master' ); - await simpleGit.pull( gitRemote, 'master' ); + await simpleGit.pull( 'origin', 'master' ); await simpleGit.raw( [ 'cherry-pick', commitHash ] ); - await simpleGit.push( gitRemote, 'master' ); + await simpleGit.push( 'origin', 'master' ); + } ); + + abortMessage = 'Aborting! The release is finished though.'; + await runStep( 'Cleaning the temporary folder', abortMessage, async () => { + await fs.remove( workingDirectoryPath ); } ); console.log( diff --git a/package-lock.json b/package-lock.json index 534bf25c0805f..195c8c4ae5fab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1694,6 +1694,17 @@ "semver": "^5.5.0" }, "dependencies": { + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, "get-stream": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", @@ -1759,6 +1770,17 @@ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", @@ -1793,6 +1815,19 @@ "cmd-shim": "^2.0.2", "fs-extra": "^7.0.0", "npmlog": "^4.1.2" + }, + "dependencies": { + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + } } }, "@lerna/describe-ref": { @@ -1879,6 +1914,17 @@ "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==", "dev": true }, + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, "ssri": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", @@ -1962,6 +2008,19 @@ "dedent": "^0.7.0", "fs-extra": "^7.0.0", "p-map-series": "^1.0.0" + }, + "dependencies": { + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + } } }, "@lerna/init": { @@ -1975,6 +2034,19 @@ "fs-extra": "^7.0.0", "p-map": "^1.2.0", "write-json-file": "^2.3.0" + }, + "dependencies": { + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + } } }, "@lerna/link": { @@ -2068,6 +2140,19 @@ "npmlog": "^4.1.2", "signal-exit": "^3.0.2", "write-pkg": "^3.1.0" + }, + "dependencies": { + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + } } }, "@lerna/npm-publish": { @@ -2086,6 +2171,17 @@ "read-package-json": "^2.0.13" }, "dependencies": { + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", @@ -2365,6 +2461,17 @@ "semver": "^5.5.0" }, "dependencies": { + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, "semver": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", @@ -2391,6 +2498,19 @@ "fs-extra": "^7.0.0", "npmlog": "^4.1.2", "read-cmd-shim": "^1.0.1" + }, + "dependencies": { + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + } } }, "@lerna/rimraf-dir": { @@ -2454,6 +2574,19 @@ "@lerna/package": "3.13.0", "fs-extra": "^7.0.0", "p-map": "^1.2.0" + }, + "dependencies": { + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + } } }, "@lerna/symlink-dependencies": { @@ -2469,6 +2602,19 @@ "p-finally": "^1.0.0", "p-map": "^1.2.0", "p-map-series": "^1.0.0" + }, + "dependencies": { + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + } } }, "@lerna/timer": { @@ -9730,9 +9876,9 @@ "dev": true }, "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.0.1.tgz", + "integrity": "sha512-W+XLrggcDzlle47X/XnS7FXrXu9sDo+Ze9zpndeBxdgv88FHLm1HtmkhEwavruS6koanBjp098rUpHs65EmG7A==", "dev": true, "requires": { "graceful-fs": "^4.1.2", diff --git a/package.json b/package.json index e48a3ff8a0273..9f1f8531e8656 100644 --- a/package.json +++ b/package.json @@ -96,6 +96,7 @@ "eslint-plugin-jest": "21.5.0", "espree": "4.0.0", "fbjs": "0.8.17", + "fs-extra": "8.0.1", "glob": "7.1.2", "husky": "0.14.3", "inquirer": "6.3.1", From d20945d81ddc1b61b381a23121c5d27e098fe5a6 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Sat, 18 May 2019 20:57:42 +0100 Subject: [PATCH 15/23] Small optimizations --- bin/commander.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bin/commander.js b/bin/commander.js index b92d18e9b97b1..ff647f728add0 100755 --- a/bin/commander.js +++ b/bin/commander.js @@ -93,7 +93,7 @@ program await runStep( 'Cloning the repository', abortMessage, async () => { console.log( '>> Cloning the repository' ); const simpleGit = SimpleGit(); - await simpleGit.clone( repoURL, workingDirectoryPath ); + await simpleGit.clone( repoURL, workingDirectoryPath, [ '--depth=1' ] ); console.log( '>> The gutenberg repository has been successfully cloned in the following temporary folder: ' + success( workingDirectoryPath ) ); } ); @@ -264,6 +264,7 @@ program ); await simpleGit.fetch(); await simpleGit.checkout( 'master' ); + await simpleGit.reset( 'hard' ); await simpleGit.pull( 'origin', 'master' ); await simpleGit.raw( [ 'cherry-pick', commitHash ] ); await simpleGit.push( 'origin', 'master' ); From 1c216354cbb01783a3e7a12940a64b9abae8c723 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Thu, 23 May 2019 23:08:38 +0100 Subject: [PATCH 16/23] Fix typo Co-Authored-By: Andrew Duthie --- bin/commander.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/commander.js b/bin/commander.js index ff647f728add0..0c97e45f07303 100755 --- a/bin/commander.js +++ b/bin/commander.js @@ -87,7 +87,7 @@ program // This is a variable that contains the abort message shown when the script is aborted. let abortMessage = 'Aborting!'; - await askForConfirmationToContinue( 'Ready go go? ' ); + await askForConfirmationToContinue( 'Ready to go? ' ); // Cloning the repository await runStep( 'Cloning the repository', abortMessage, async () => { From 9c3f8e5df4f6ee682bd6e2c26e619e70e25d0eac Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Thu, 23 May 2019 23:10:24 +0100 Subject: [PATCH 17/23] Fix typo Co-Authored-By: Andrew Duthie --- bin/commander.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/commander.js b/bin/commander.js index 0c97e45f07303..951bff7b87ba6 100755 --- a/bin/commander.js +++ b/bin/commander.js @@ -205,7 +205,7 @@ program let release; await runStep( 'Creating the Github release', abortMessage, async () => { await askForConfirmationToContinue( - 'Proceed with the creation of the Github release?', + 'Proceed with the creation of the GitHub release?', true, abortMessage ); From f74b3d7ce2542e9b8756a28c7de9d0ed47ebd80e Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Thu, 23 May 2019 23:11:03 +0100 Subject: [PATCH 18/23] Improve the token message Co-Authored-By: Andrew Duthie --- bin/commander.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/commander.js b/bin/commander.js index 951bff7b87ba6..0c53c8393e819 100755 --- a/bin/commander.js +++ b/bin/commander.js @@ -218,7 +218,7 @@ program const { token } = await inquirer.prompt( [ { type: 'input', name: 'token', - message: 'Please provide a Github personal authentication token. (Navigate to ' + success( 'https://github.com/settings/tokens' ) + ' to create one with admin:org, repo and write:packages rights)', + message: 'Please provide a GitHub personal authentication token. Navigate to ' + success( 'https://github.com/settings/tokens/new?scopes=repo,admin:org,write:packages' ) + ' to create one.', } ] ); octokit = new Octokit( { From 950d17a935f6725a5ac7444f3437a0cdd66e0b29 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Thu, 23 May 2019 23:14:16 +0100 Subject: [PATCH 19/23] Fix Typo Co-Authored-By: Andrew Duthie --- bin/commander.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/commander.js b/bin/commander.js index 0c53c8393e819..2b0375263597f 100755 --- a/bin/commander.js +++ b/bin/commander.js @@ -237,7 +237,7 @@ program console.log( '>> The Github release has been created succesfully.' ); } ); - abortMessage = 'Aborting! Make sure to remove the remote release branch, the git tag and the Github release.'; + abortMessage = 'Aborting! Make sure to remove the remote release branch, the git tag and the GitHub release.'; // Uploading the Gutenberg Zip to the release await runStep( 'Uploading the plugin zip', abortMessage, async () => { From 2c6f3c148bd85d696af88c29a63c096c696b693c Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Thu, 23 May 2019 23:14:41 +0100 Subject: [PATCH 20/23] Fix typo Co-Authored-By: Andrew Duthie --- bin/commander.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/commander.js b/bin/commander.js index 2b0375263597f..b1e7b3d6c0733 100755 --- a/bin/commander.js +++ b/bin/commander.js @@ -235,7 +235,7 @@ program } ); release = releaseData.data; - console.log( '>> The Github release has been created succesfully.' ); + console.log( '>> The GitHub release has been created succesfully.' ); } ); abortMessage = 'Aborting! Make sure to remove the remote release branch, the git tag and the GitHub release.'; From fd6a196b8e3b21dc68e5ce187e3d444fa38ac696 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Thu, 23 May 2019 23:16:22 +0100 Subject: [PATCH 21/23] Fix typo Co-Authored-By: Andrew Duthie --- bin/commander.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/commander.js b/bin/commander.js index b1e7b3d6c0733..91231453f0f9e 100755 --- a/bin/commander.js +++ b/bin/commander.js @@ -203,7 +203,7 @@ program // Creating the GitHub Release let octokit; let release; - await runStep( 'Creating the Github release', abortMessage, async () => { + await runStep( 'Creating the GitHub release', abortMessage, async () => { await askForConfirmationToContinue( 'Proceed with the creation of the GitHub release?', true, From 6649f26436acaaa330b7b9f0917d0f39bca8d731 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Fri, 24 May 2019 08:53:14 +0100 Subject: [PATCH 22/23] Reorganize the file and add comments --- bin/commander.js | 400 ++++++++++++++++++++++++----------------------- 1 file changed, 204 insertions(+), 196 deletions(-) diff --git a/bin/commander.js b/bin/commander.js index 91231453f0f9e..5057c1ce33699 100755 --- a/bin/commander.js +++ b/bin/commander.js @@ -38,7 +38,7 @@ const success = chalk.bold.green; * @param {boolean} isDefault Default reply. * @param {string} abortMessage Abort message. */ -const askForConfirmationToContinue = async ( message, isDefault = true, abortMessage = 'Aborting.' ) => { +async function askForConfirmationToContinue( message, isDefault = true, abortMessage = 'Aborting.' ) { const { isReady } = await inquirer.prompt( [ { type: 'confirm', name: 'isReady', @@ -50,7 +50,7 @@ const askForConfirmationToContinue = async ( message, isDefault = true, abortMes console.log( error( '\n' + abortMessage ) ); process.exit( 1 ); } -}; +} /** * Common logic wrapping a step in the process. @@ -59,7 +59,7 @@ const askForConfirmationToContinue = async ( message, isDefault = true, abortMes * @param {string} abortMessage Abort message. * @param {function} handler Step logic. */ -const runStep = async ( name, abortMessage, handler ) => { +async function runStep( name, abortMessage, handler ) { try { await handler(); } catch ( exception ) { @@ -71,215 +71,223 @@ const runStep = async ( name, abortMessage, handler ) => { process.exit( 1 ); } -}; +} -program - .command( 'release-plugin-rc' ) - .alias( 'rc' ) - .description( 'Release an RC version of the plugin (supports only rc.1 for now)' ) - .action( async () => { - console.log( - chalk.bold( '💃 Time to release Gutenberg 🕺\n\n' ), - 'Welcome! This tool is going to help you release a new RC version of the Gutenberg Plugin.\n', - 'It goes throught different steps : creating the release branch, bumping the plugin version, tagging and creating the github release, building the zip...\n', - 'To perform a release you\'ll have to be a member of the Gutenberg Core Team.\n' - ); +/** + * Command used to release an RC version of the plugin + */ +async function releasePluginRC() { + console.log( + chalk.bold( '💃 Time to release Gutenberg 🕺\n\n' ), + 'Welcome! This tool is going to help you release a new RC version of the Gutenberg Plugin.\n', + 'It goes throught different steps : creating the release branch, bumping the plugin version, tagging and creating the github release, building the zip...\n', + 'To perform a release you\'ll have to be a member of the Gutenberg Core Team.\n' + ); - // This is a variable that contains the abort message shown when the script is aborted. - let abortMessage = 'Aborting!'; - await askForConfirmationToContinue( 'Ready to go? ' ); + // This is a variable that contains the abort message shown when the script is aborted. + let abortMessage = 'Aborting!'; + await askForConfirmationToContinue( 'Ready to go? ' ); - // Cloning the repository - await runStep( 'Cloning the repository', abortMessage, async () => { - console.log( '>> Cloning the repository' ); - const simpleGit = SimpleGit(); - await simpleGit.clone( repoURL, workingDirectoryPath, [ '--depth=1' ] ); - console.log( '>> The gutenberg repository has been successfully cloned in the following temporary folder: ' + success( workingDirectoryPath ) ); - } ); + // Cloning the repository + await runStep( 'Cloning the repository', abortMessage, async () => { + console.log( '>> Cloning the repository' ); + const simpleGit = SimpleGit(); + await simpleGit.clone( repoURL, workingDirectoryPath, [ '--depth=1' ] ); + console.log( '>> The gutenberg repository has been successfully cloned in the following temporary folder: ' + success( workingDirectoryPath ) ); + } ); + + // Creating the release branch + const simpleGit = SimpleGit( workingDirectoryPath ); + let nextVersion; + let nextVersionLabel; + let releaseBranch; + const packageJson = require( packageJsonPath ); + const packageLock = require( packageLockPath ); + await runStep( 'Creating the release branch', abortMessage, async () => { + const parsedVersion = semver.parse( packageJson.version ); + + // Follow the WordPress version guidelines to compute the version to be used + // By default, increase the "minor" number but if we reach 9, bump to the next major. + if ( parsedVersion.minor === 9 ) { + nextVersion = ( parsedVersion.major + 1 ) + '.0.0-rc.1'; + releaseBranch = 'release/' + ( parsedVersion.major + 1 ) + '.0'; + nextVersionLabel = ( parsedVersion.major + 1 ) + '.0.0 RC1'; + } else { + nextVersion = parsedVersion.major + '.' + ( parsedVersion.minor + 1 ) + '.0-rc.1'; + releaseBranch = 'release/' + parsedVersion.major + '.' + ( parsedVersion.minor + 1 ); + nextVersionLabel = parsedVersion.major + '.' + ( parsedVersion.minor + 1 ) + '.0 RC1'; + } + await askForConfirmationToContinue( + 'The RC Version to be applied is ' + success( nextVersion ) + '. Proceed with the creation of the release branch?', + true, + abortMessage + ); // Creating the release branch - const simpleGit = SimpleGit( workingDirectoryPath ); - let nextVersion; - let nextVersionLabel; - let releaseBranch; - const packageJson = require( packageJsonPath ); - const packageLock = require( packageLockPath ); - await runStep( 'Creating the release branch', abortMessage, async () => { - const parsedVersion = semver.parse( packageJson.version ); - if ( parsedVersion.minor === 9 ) { - nextVersion = ( parsedVersion.major + 1 ) + '.0.0-rc.1'; - releaseBranch = 'release/' + ( parsedVersion.major + 1 ) + '.0'; - nextVersionLabel = ( parsedVersion.major + 1 ) + '.0.0 RC1'; - } else { - nextVersion = parsedVersion.major + '.' + ( parsedVersion.minor + 1 ) + '.0-rc.1'; - releaseBranch = 'release/' + parsedVersion.major + '.' + ( parsedVersion.minor + 1 ); - nextVersionLabel = parsedVersion.major + '.' + ( parsedVersion.minor + 1 ) + '.0 RC1'; - } - await askForConfirmationToContinue( - 'The RC Version to be applied is ' + success( nextVersion ) + '. Proceed with the creation of the release branch?', - true, - abortMessage - ); - - // Creating the release branch - await simpleGit.checkoutLocalBranch( releaseBranch ); - console.log( '>> The local release branch ' + success( releaseBranch ) + ' has been successfully created.' ); - } ); + await simpleGit.checkoutLocalBranch( releaseBranch ); + console.log( '>> The local release branch ' + success( releaseBranch ) + ' has been successfully created.' ); + } ); - // Bumping the version in the different files (package.json, package-lock.json, gutenberg.php) - let commitHash; - await runStep( 'Updating the plugin version', abortMessage, async () => { - const newPackageJson = { - ...packageJson, - version: nextVersion, - }; - fs.writeFileSync( packageJsonPath, JSON.stringify( newPackageJson, null, '\t' ) + '\n' ); - const newPackageLock = { - ...packageLock, - version: nextVersion, - }; - fs.writeFileSync( packageLockPath, JSON.stringify( newPackageLock, null, '\t' ) + '\n' ); - const content = fs.readFileSync( pluginFilePath, 'utf8' ); - fs.writeFileSync( pluginFilePath, content.replace( ' * Version: ' + packageJson.version, ' * Version: ' + nextVersion ) ); - console.log( '>> The plugin version has been updated successfully.' ); - - // Commit the version bump - await askForConfirmationToContinue( - 'Please check the diff. Proceed with the version bump commit?', - true, - abortMessage - ); - await simpleGit.add( [ - packageJsonPath, - packageLockPath, - pluginFilePath, - ] ); - const commitData = await simpleGit.commit( 'Bump plugin version to ' + nextVersion ); - commitHash = commitData.commit; - console.log( '>> The plugin version bump has been commited succesfully.' ); - } ); + // Bumping the version in the different files (package.json, package-lock.json, gutenberg.php) + let commitHash; + await runStep( 'Updating the plugin version', abortMessage, async () => { + const newPackageJson = { + ...packageJson, + version: nextVersion, + }; + fs.writeFileSync( packageJsonPath, JSON.stringify( newPackageJson, null, '\t' ) + '\n' ); + const newPackageLock = { + ...packageLock, + version: nextVersion, + }; + fs.writeFileSync( packageLockPath, JSON.stringify( newPackageLock, null, '\t' ) + '\n' ); + const content = fs.readFileSync( pluginFilePath, 'utf8' ); + fs.writeFileSync( pluginFilePath, content.replace( ' * Version: ' + packageJson.version, ' * Version: ' + nextVersion ) ); + console.log( '>> The plugin version has been updated successfully.' ); - // Plugin ZIP creation - await runStep( 'Plugin ZIP creation', abortMessage, async () => { - await askForConfirmationToContinue( - 'Proceed and build the plugin zip? (It takes a few minutes)', - true, - abortMessage - ); - childProcess.execSync( '/bin/bash bin/build-plugin-zip.sh', { - cwd: workingDirectoryPath, - env: { - NO_CHECKS: true, - PATH: process.env.PATH, - }, - stdio: [ 'inherit', 'ignore', 'inherit' ], - } ); - - console.log( '>> The plugin zip has been built succesfully. Path: ' + success( gutenbergZipPath ) ); - } ); + // Commit the version bump + await askForConfirmationToContinue( + 'Please check the diff. Proceed with the version bump commit?', + true, + abortMessage + ); + await simpleGit.add( [ + packageJsonPath, + packageLockPath, + pluginFilePath, + ] ); + const commitData = await simpleGit.commit( 'Bump plugin version to ' + nextVersion ); + commitHash = commitData.commit; + console.log( '>> The plugin version bump has been commited succesfully.' ); + } ); - // Creating the git tag - await runStep( 'Creating the git tag', abortMessage, async () => { - await askForConfirmationToContinue( - 'Proceed with the creation of the git tag?', - true, - abortMessage - ); - await simpleGit.addTag( 'v' + nextVersion ); - console.log( '>> The ' + success( 'v' + nextVersion ) + ' tag has been created succesfully.' ); + // Plugin ZIP creation + await runStep( 'Plugin ZIP creation', abortMessage, async () => { + await askForConfirmationToContinue( + 'Proceed and build the plugin zip? (It takes a few minutes)', + true, + abortMessage + ); + childProcess.execSync( '/bin/bash bin/build-plugin-zip.sh', { + cwd: workingDirectoryPath, + env: { + NO_CHECKS: true, + PATH: process.env.PATH, + }, + stdio: [ 'inherit', 'ignore', 'inherit' ], } ); - await runStep( 'Pushing the release branch and the tag', abortMessage, async () => { - await askForConfirmationToContinue( - 'The release branch and the tag are going to be pushed to the remote repository. Continue?', - true, - abortMessage - ); - await simpleGit.push( 'origin', releaseBranch ); - await simpleGit.pushTags( 'origin' ); - } ); - abortMessage = 'Aborting! Make sure to remove remote release branch and tag.'; - - // Creating the GitHub Release - let octokit; - let release; - await runStep( 'Creating the GitHub release', abortMessage, async () => { - await askForConfirmationToContinue( - 'Proceed with the creation of the GitHub release?', - true, - abortMessage - ); - const { changelog } = await inquirer.prompt( [ { - type: 'editor', - name: 'changelog', - message: 'Please provide the CHANGELOG of the release (markdown)', - } ] ); - - const { token } = await inquirer.prompt( [ { - type: 'input', - name: 'token', - message: 'Please provide a GitHub personal authentication token. Navigate to ' + success( 'https://github.com/settings/tokens/new?scopes=repo,admin:org,write:packages' ) + ' to create one.', - } ] ); - - octokit = new Octokit( { - auth: token, - } ); - - const releaseData = await octokit.repos.createRelease( { - owner: repoOwner, - repo: 'gutenberg', - tag_name: 'v' + nextVersion, - name: nextVersionLabel, - body: changelog, - prerelease: true, - } ); - release = releaseData.data; - - console.log( '>> The GitHub release has been created succesfully.' ); - } ); - abortMessage = 'Aborting! Make sure to remove the remote release branch, the git tag and the GitHub release.'; - - // Uploading the Gutenberg Zip to the release - await runStep( 'Uploading the plugin zip', abortMessage, async () => { - const filestats = fs.statSync( gutenbergZipPath ); - await octokit.repos.uploadReleaseAsset( { - url: release.upload_url, - headers: { - 'content-length': filestats.size, - 'content-type': 'application/zip', - }, - name: 'gutenberg.zip', - file: fs.createReadStream( gutenbergZipPath ), - } ); - console.log( '>> The plugin zip has been succesfully uploaded.' ); + console.log( '>> The plugin zip has been built succesfully. Path: ' + success( gutenbergZipPath ) ); + } ); + + // Creating the git tag + await runStep( 'Creating the git tag', abortMessage, async () => { + await askForConfirmationToContinue( + 'Proceed with the creation of the git tag?', + true, + abortMessage + ); + await simpleGit.addTag( 'v' + nextVersion ); + console.log( '>> The ' + success( 'v' + nextVersion ) + ' tag has been created succesfully.' ); + } ); + + await runStep( 'Pushing the release branch and the tag', abortMessage, async () => { + await askForConfirmationToContinue( + 'The release branch and the tag are going to be pushed to the remote repository. Continue?', + true, + abortMessage + ); + await simpleGit.push( 'origin', releaseBranch ); + await simpleGit.pushTags( 'origin' ); + } ); + abortMessage = 'Aborting! Make sure to remove remote release branch and tag.'; + + // Creating the GitHub Release + let octokit; + let release; + await runStep( 'Creating the GitHub release', abortMessage, async () => { + await askForConfirmationToContinue( + 'Proceed with the creation of the GitHub release?', + true, + abortMessage + ); + const { changelog } = await inquirer.prompt( [ { + type: 'editor', + name: 'changelog', + message: 'Please provide the CHANGELOG of the release (markdown)', + } ] ); + + const { token } = await inquirer.prompt( [ { + type: 'input', + name: 'token', + message: 'Please provide a GitHub personal authentication token. Navigate to ' + success( 'https://github.com/settings/tokens/new?scopes=repo,admin:org,write:packages' ) + ' to create one.', + } ] ); + + octokit = new Octokit( { + auth: token, } ); - abortMessage = 'Aborting! Make sure to manually cherry-pick the ' + success( commitHash ) + ' commit to the master branch.'; - - // Cherry-picking the bump commit into master - await runStep( 'Cherry-picking the bump commit into master', abortMessage, async () => { - await askForConfirmationToContinue( - 'The plugin RC is now released. Proceed with the version bump in the master branch?', - true, - 'test' - ); - await simpleGit.fetch(); - await simpleGit.checkout( 'master' ); - await simpleGit.reset( 'hard' ); - await simpleGit.pull( 'origin', 'master' ); - await simpleGit.raw( [ 'cherry-pick', commitHash ] ); - await simpleGit.push( 'origin', 'master' ); + + const releaseData = await octokit.repos.createRelease( { + owner: repoOwner, + repo: 'gutenberg', + tag_name: 'v' + nextVersion, + name: nextVersionLabel, + body: changelog, + prerelease: true, } ); + release = releaseData.data; - abortMessage = 'Aborting! The release is finished though.'; - await runStep( 'Cleaning the temporary folder', abortMessage, async () => { - await fs.remove( workingDirectoryPath ); + console.log( '>> The GitHub release has been created succesfully.' ); + } ); + abortMessage = 'Aborting! Make sure to remove the remote release branch, the git tag and the GitHub release.'; + + // Uploading the Gutenberg Zip to the release + await runStep( 'Uploading the plugin zip', abortMessage, async () => { + const filestats = fs.statSync( gutenbergZipPath ); + await octokit.repos.uploadReleaseAsset( { + url: release.upload_url, + headers: { + 'content-length': filestats.size, + 'content-type': 'application/zip', + }, + name: 'gutenberg.zip', + file: fs.createReadStream( gutenbergZipPath ), } ); + console.log( '>> The plugin zip has been succesfully uploaded.' ); + } ); + abortMessage = 'Aborting! Make sure to manually cherry-pick the ' + success( commitHash ) + ' commit to the master branch.'; - console.log( - '\n>> 🎉 The Gutenberg ' + success( nextVersionLabel ) + ' has been successfully released.\n', - 'You can access the Github release here: ' + success( release.html_url ) + '\n', - 'Thanks for performing the release!' + // Cherry-picking the bump commit into master + await runStep( 'Cherry-picking the bump commit into master', abortMessage, async () => { + await askForConfirmationToContinue( + 'The plugin RC is now released. Proceed with the version bump in the master branch?', + true, + 'test' ); + await simpleGit.fetch(); + await simpleGit.checkout( 'master' ); + await simpleGit.reset( 'hard' ); + await simpleGit.pull( 'origin', 'master' ); + await simpleGit.raw( [ 'cherry-pick', commitHash ] ); + await simpleGit.push( 'origin', 'master' ); } ); + abortMessage = 'Aborting! The release is finished though.'; + await runStep( 'Cleaning the temporary folder', abortMessage, async () => { + await fs.remove( workingDirectoryPath ); + } ); + + console.log( + '\n>> 🎉 The Gutenberg ' + success( nextVersionLabel ) + ' has been successfully released.\n', + 'You can access the Github release here: ' + success( release.html_url ) + '\n', + 'Thanks for performing the release!' + ); +} + +program + .command( 'release-plugin-rc' ) + .alias( 'rc' ) + .description( 'Release an RC version of the plugin (supports only rc.1 for now)' ) + .action( releasePluginRC ); + program.parse( process.argv ); From 65a76741444f0f4a10914e543f15b51382829b0e Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Fri, 24 May 2019 08:55:09 +0100 Subject: [PATCH 23/23] Fix debug artifact --- bin/commander.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/commander.js b/bin/commander.js index 5057c1ce33699..087dcdf0540ac 100755 --- a/bin/commander.js +++ b/bin/commander.js @@ -262,7 +262,7 @@ async function releasePluginRC() { await askForConfirmationToContinue( 'The plugin RC is now released. Proceed with the version bump in the master branch?', true, - 'test' + abortMessage ); await simpleGit.fetch(); await simpleGit.checkout( 'master' );