From 743c3dbe01b3ffaa1743c2907cbcab1d7ed78d72 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 29 Mar 2018 14:06:29 +0200 Subject: Generate CHANGELOG.json files and add convert_changelog script --- packages/monorepo-scripts/CHANGELOG.json | 12 ++++ packages/monorepo-scripts/package.json | 3 + .../monorepo-scripts/src/convert_changelogs.ts | 80 ++++++++++++++++++++++ packages/monorepo-scripts/src/types.ts | 17 +++++ 4 files changed, 112 insertions(+) create mode 100644 packages/monorepo-scripts/CHANGELOG.json create mode 100644 packages/monorepo-scripts/src/convert_changelogs.ts create mode 100644 packages/monorepo-scripts/src/types.ts (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/CHANGELOG.json b/packages/monorepo-scripts/CHANGELOG.json new file mode 100644 index 000000000..a8418d03f --- /dev/null +++ b/packages/monorepo-scripts/CHANGELOG.json @@ -0,0 +1,12 @@ +[ + { + "version": "0.1.13", + "changes": [ + { + "note": "Add postpublish utils" + } + ], + "timestamp": 1521327600, + "isPublished": true + } +] \ No newline at end of file diff --git a/packages/monorepo-scripts/package.json b/packages/monorepo-scripts/package.json index 5333e6cad..9dcb8ee14 100644 --- a/packages/monorepo-scripts/package.json +++ b/packages/monorepo-scripts/package.json @@ -7,6 +7,7 @@ "scripts": { "build:watch": "tsc -w", "deps_versions": "node ./lib/deps_versions.js", + "convert_changelogs": "yarn build; node ./lib/convert_changelogs.js", "lint": "tslint --project . 'src/**/*.ts'", "clean": "shx rm -rf lib", "build": "tsc" @@ -24,6 +25,7 @@ "devDependencies": { "@0xproject/tslint-config": "0.4.8", "@types/glob": "^5.0.33", + "@types/moment": "2.13.0", "@types/node": "^8.0.53", "@types/rimraf": "^2.0.2", "lerna-get-packages": "^1.0.0", @@ -37,6 +39,7 @@ "es6-promisify": "^5.0.0", "glob": "^7.1.2", "lodash": "^4.17.4", + "moment": "2.13.0", "promisify-child-process": "^1.0.5", "publish-release": "0xproject/publish-release", "rimraf": "^2.6.2", diff --git a/packages/monorepo-scripts/src/convert_changelogs.ts b/packages/monorepo-scripts/src/convert_changelogs.ts new file mode 100644 index 000000000..419f36ff4 --- /dev/null +++ b/packages/monorepo-scripts/src/convert_changelogs.ts @@ -0,0 +1,80 @@ +#!/usr/bin/env node + +import * as fs from 'fs'; +import lernaGetPackages = require('lerna-get-packages'); +import * as _ from 'lodash'; +import * as moment from 'moment'; +import * as path from 'path'; + +import { Changelog, Changes, UpdatedPackage } from './types'; +import { utils } from './utils'; + +const MONOREPO_ROOT_PATH = path.join(__dirname, '../../..'); + +(async () => { + const allLernaPackages = lernaGetPackages(MONOREPO_ROOT_PATH); + const publicLernaPackages = _.filter(allLernaPackages, pkg => !pkg.package.private); + _.each(publicLernaPackages, lernaPackage => { + const changelogMdIfExists = getChangelogMdIfExists(lernaPackage.package.name, lernaPackage.location); + if (_.isUndefined(changelogMdIfExists)) { + throw new Error(`${lernaPackage.package.name} should have CHANGELOG.md b/c it's public. Add one.`); + } + + const lines = (changelogMdIfExists as any).split('\n'); + const changelogs: Changelog[] = []; + let changelog: Changelog = { + version: '', + changes: [], + }; + for (const line of lines) { + if (_.startsWith(line, '## ')) { + const version = line.substr(4).split(' - ')[0]; + const dateStr = line.split('_')[1]; + let date; + if (!_.includes(dateStr, 'TBD')) { + date = moment(dateStr, 'MMMM D, YYYY'); + } + changelog = { + version, + changes: [], + }; + if (!_.isUndefined(date)) { + changelog.timestamp = date.unix(); + } + if (!_.includes(dateStr, 'TBD')) { + changelog.isPublished = true; + } + (changelogs as any).push(changelog); + } else if (_.includes(line, '* ')) { + const note = line.split('* ')[1].split(' (#')[0]; + const prChunk = line.split(' (#')[1]; + let pr; + if (!_.isUndefined(prChunk)) { + pr = prChunk.split(')')[0]; + } + const changes = { + note, + pr, + }; + changelog.changes.push(changes); + } + } + const changelogJson = JSON.stringify(changelogs, null, '\t'); + fs.writeFileSync(`${lernaPackage.location}/CHANGELOG.json`, changelogJson); + }); +})().catch(err => { + utils.log(err.stdout); + process.exit(1); +}); + +function getChangelogMdIfExists(packageName: string, location: string): string | undefined { + const changelogPath = path.join(location, 'CHANGELOG.md'); + let changelogMd: string; + try { + changelogMd = fs.readFileSync(changelogPath, 'utf-8'); + return changelogMd; + } catch (err) { + // If none exists, create new, empty one. + return undefined; + } +} diff --git a/packages/monorepo-scripts/src/types.ts b/packages/monorepo-scripts/src/types.ts new file mode 100644 index 000000000..045316ab5 --- /dev/null +++ b/packages/monorepo-scripts/src/types.ts @@ -0,0 +1,17 @@ +export interface UpdatedPackage { + name: string; + version: string; + private: boolean; +} + +export interface Changes { + note: string; + pr?: number; +} + +export interface Changelog { + timestamp?: number; + version: string; + changes: Changes[]; + isPublished?: boolean; +} -- cgit v1.2.3 From 397cd77ef91e88da4dd71908770659343f0b7c35 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 29 Mar 2018 15:02:46 +0200 Subject: Fix semver-sort version --- packages/monorepo-scripts/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/package.json b/packages/monorepo-scripts/package.json index 9dcb8ee14..4a2cf52e1 100644 --- a/packages/monorepo-scripts/package.json +++ b/packages/monorepo-scripts/package.json @@ -43,7 +43,7 @@ "promisify-child-process": "^1.0.5", "publish-release": "0xproject/publish-release", "rimraf": "^2.6.2", - "semver-sort": "^0.0.4" + "semver-sort": "0.0.4" }, "publishConfig": { "access": "public" -- cgit v1.2.3 From bd7b5c51b2be9140c9d5ba3ca208ba4231eca83c Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 29 Mar 2018 15:18:42 +0200 Subject: Add 0.x.x edgecase --- packages/monorepo-scripts/src/convert_changelogs.ts | 5 ++++- packages/monorepo-scripts/src/utils.ts | 9 +++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/convert_changelogs.ts b/packages/monorepo-scripts/src/convert_changelogs.ts index 419f36ff4..76ce50ced 100644 --- a/packages/monorepo-scripts/src/convert_changelogs.ts +++ b/packages/monorepo-scripts/src/convert_changelogs.ts @@ -28,7 +28,10 @@ const MONOREPO_ROOT_PATH = path.join(__dirname, '../../..'); }; for (const line of lines) { if (_.startsWith(line, '## ')) { - const version = line.substr(4).split(' - ')[0]; + let version = line.substr(4).split(' - ')[0]; + if (version === '0.x.x') { + version = utils.getNextPatchVersion(lernaPackage.package.version); + } const dateStr = line.split('_')[1]; let date; if (!_.includes(dateStr, 'TBD')) { diff --git a/packages/monorepo-scripts/src/utils.ts b/packages/monorepo-scripts/src/utils.ts index 5423cabd9..73f6260d3 100644 --- a/packages/monorepo-scripts/src/utils.ts +++ b/packages/monorepo-scripts/src/utils.ts @@ -1,5 +1,14 @@ +import * as _ from 'lodash'; + export const utils = { log(...args: any[]): void { console.log(...args); // tslint:disable-line:no-console }, + getNextPatchVersion(currentVersion: string): string { + const versionSegments = currentVersion.split('.'); + const patch = _.parseInt(_.last(versionSegments) as string); + const newPatch = patch + 1; + const newPatchVersion = `${versionSegments[0]}.${versionSegments[1]}.${newPatch}`; + return newPatchVersion; + }, }; -- cgit v1.2.3 From a6ae1efadb83366e6af89daa183adb51fdeea3b8 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 29 Mar 2018 15:26:47 +0200 Subject: Begin global pre-publishing script. Updates changelog.json files in packages to be published --- packages/monorepo-scripts/package.json | 1 + packages/monorepo-scripts/src/custom_prepublish.ts | 117 +++++++++++++++++++++ packages/monorepo-scripts/src/globals.d.ts | 1 + 3 files changed, 119 insertions(+) create mode 100644 packages/monorepo-scripts/src/custom_prepublish.ts (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/package.json b/packages/monorepo-scripts/package.json index 4a2cf52e1..09b7a340d 100644 --- a/packages/monorepo-scripts/package.json +++ b/packages/monorepo-scripts/package.json @@ -7,6 +7,7 @@ "scripts": { "build:watch": "tsc -w", "deps_versions": "node ./lib/deps_versions.js", + "publish:prepublish": "yarn build; node ./lib/custom_prepublish.js", "convert_changelogs": "yarn build; node ./lib/convert_changelogs.js", "lint": "tslint --project . 'src/**/*.ts'", "clean": "shx rm -rf lib", diff --git a/packages/monorepo-scripts/src/custom_prepublish.ts b/packages/monorepo-scripts/src/custom_prepublish.ts new file mode 100644 index 000000000..7f0e186bd --- /dev/null +++ b/packages/monorepo-scripts/src/custom_prepublish.ts @@ -0,0 +1,117 @@ +#!/usr/bin/env node + +import * as fs from 'fs'; +import lernaGetPackages = require('lerna-get-packages'); +import * as _ from 'lodash'; +import * as moment from 'moment'; +import * as path from 'path'; +import { exec as execAsync } from 'promisify-child-process'; +import semverSort = require('semver-sort'); + +import { Changelog, Changes, UpdatedPackage } from './types'; +import { utils } from './utils'; + +const MONOREPO_ROOT_PATH = path.join(__dirname, '../../..'); +const TODAYS_TIMESTAMP = moment().unix(); + +(async () => { + const updatedPublicPackages = await getPublicLernaUpdatedPackagesAsync(); + const updatedPackageNames = _.map(updatedPublicPackages, pkg => pkg.name); + + const allLernaPackages = lernaGetPackages(MONOREPO_ROOT_PATH); + const relevantLernaPackages = _.filter(allLernaPackages, pkg => { + return _.includes(updatedPackageNames, pkg.package.name); + }); + _.each(relevantLernaPackages, lernaPackage => { + const changelogJSONPath = path.join(lernaPackage.location, 'CHANGELOG.json'); + const changelogJSON = getChangelogJSONOrCreateIfMissing(lernaPackage.package.name, changelogJSONPath); + let changelogs: Changelog[]; + try { + changelogs = JSON.parse(changelogJSON); + } catch (err) { + throw new Error( + `${lernaPackage.package.name}'s CHANGELOG.json contains invalid JSON. Please fix and try again.`, + ); + } + + const currentVersion = lernaPackage.package.version; + const shouldAddNewEntry = shouldAddNewChangelogEntry(changelogs); + if (shouldAddNewEntry) { + // Create a new entry for a patch version with generic changelog entry. + const nextPatchVersion = utils.getNextPatchVersion(currentVersion); + const newChangelogEntry: Changelog = { + timestamp: TODAYS_TIMESTAMP, + version: nextPatchVersion, + changes: [ + { + note: 'Dependencies updated', + }, + ], + }; + changelogs = [newChangelogEntry, ...changelogs]; + } else { + // Update existing entry with timestamp + const lastEntry = changelogs[0]; + if (_.isUndefined(lastEntry.timestamp)) { + lastEntry.timestamp = TODAYS_TIMESTAMP; + } + // Check version number is correct. + const proposedNextVersion = lastEntry.version; + lastEntry.version = updateVersionNumberIfNeeded(currentVersion, proposedNextVersion); + changelogs[0] = lastEntry; + } + + // Save updated CHANGELOG.json + fs.writeFileSync(changelogJSONPath, JSON.stringify(changelogs, null, '\t')); + // Generate updated CHANGELOG.md + const changelogMd = generateChangelogMd(changelogs); + }); +})().catch(err => { + utils.log(err); + process.exit(1); +}); + +async function getPublicLernaUpdatedPackagesAsync(): Promise { + const result = await execAsync(`./node_modules/lerna/bin/lerna.js updated --json`, { cwd: MONOREPO_ROOT_PATH }); + const updatedPackages = JSON.parse(result.stdout); + const updatedPublicPackages = _.filter(updatedPackages, updatedPackage => !updatedPackage.private); + return updatedPublicPackages; +} + +function updateVersionNumberIfNeeded(currentVersion: string, proposedNextVersion: string) { + console.log('currentVersion', currentVersion); + console.log('proposedNextVersion', proposedNextVersion); + if (proposedNextVersion === currentVersion) { + return utils.getNextPatchVersion(currentVersion); + } + const sortedVersions = semverSort.desc([proposedNextVersion, currentVersion]); + if (sortedVersions[0] !== proposedNextVersion) { + return utils.getNextPatchVersion(currentVersion); + } + return proposedNextVersion; +} + +function getChangelogJSONOrCreateIfMissing(packageName: string, changelogPath: string): string { + let changelogJSON: string; + try { + changelogJSON = fs.readFileSync(changelogPath, 'utf-8'); + return changelogJSON; + } catch (err) { + // If none exists, create new, empty one. + const emptyChangelogJSON = JSON.stringify([]); + fs.writeFileSync(changelogPath, emptyChangelogJSON); + return emptyChangelogJSON; + } +} + +function shouldAddNewChangelogEntry(changelogs: Changelog[]): boolean { + if (_.isEmpty(changelogs)) { + return true; + } + const lastEntry = changelogs[0]; + return !!lastEntry.isPublished; +} + +function generateChangelogMd(changelogs: Changelog[]): string { + return ''; +} diff --git a/packages/monorepo-scripts/src/globals.d.ts b/packages/monorepo-scripts/src/globals.d.ts index 1d49559f2..90adc0b78 100644 --- a/packages/monorepo-scripts/src/globals.d.ts +++ b/packages/monorepo-scripts/src/globals.d.ts @@ -11,6 +11,7 @@ declare interface LernaPackage { location: string; package: { private?: boolean; + version: string; name: string; main?: string; config?: { -- cgit v1.2.3 From ac35d8127e1ee3dfaf8e1aa0e182279a9a58787e Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 29 Mar 2018 17:02:44 +0200 Subject: remove console.logs --- packages/monorepo-scripts/src/custom_prepublish.ts | 2 -- 1 file changed, 2 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/custom_prepublish.ts b/packages/monorepo-scripts/src/custom_prepublish.ts index 7f0e186bd..90db51465 100644 --- a/packages/monorepo-scripts/src/custom_prepublish.ts +++ b/packages/monorepo-scripts/src/custom_prepublish.ts @@ -79,8 +79,6 @@ async function getPublicLernaUpdatedPackagesAsync(): Promise { } function updateVersionNumberIfNeeded(currentVersion: string, proposedNextVersion: string) { - console.log('currentVersion', currentVersion); - console.log('proposedNextVersion', proposedNextVersion); if (proposedNextVersion === currentVersion) { return utils.getNextPatchVersion(currentVersion); } -- cgit v1.2.3 From 29aa09e448c7b379eeea680e2e7c89a4998b04b8 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 29 Mar 2018 17:41:39 +0200 Subject: Generate CHANGELOG.mds --- packages/monorepo-scripts/src/custom_prepublish.ts | 29 +++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/custom_prepublish.ts b/packages/monorepo-scripts/src/custom_prepublish.ts index 90db51465..b18389fcd 100644 --- a/packages/monorepo-scripts/src/custom_prepublish.ts +++ b/packages/monorepo-scripts/src/custom_prepublish.ts @@ -65,6 +65,8 @@ const TODAYS_TIMESTAMP = moment().unix(); fs.writeFileSync(changelogJSONPath, JSON.stringify(changelogs, null, '\t')); // Generate updated CHANGELOG.md const changelogMd = generateChangelogMd(changelogs); + const changelogMdPath = path.join(lernaPackage.location, 'CHANGELOG.md'); + fs.writeFileSync(changelogMdPath, changelogMd); }); })().catch(err => { utils.log(err); @@ -111,5 +113,30 @@ function shouldAddNewChangelogEntry(changelogs: Changelog[]): boolean { } function generateChangelogMd(changelogs: Changelog[]): string { - return ''; + let changelogMd = ` + +CHANGELOG + `; + + _.each(changelogs, changelog => { + const date = moment(changelog.timestamp, 'X').format('MMMM D, YYYY'); + const title = `\n## v${changelog.version} - _${date}_\n\n`; + changelogMd += title; + + let changes = ''; + _.each(changelog.changes, change => { + let line = ` * ${change.note}`; + if (!_.isUndefined(change.pr)) { + line += ` (#${change.pr})`; + } + line += '\n'; + changes += line; + }); + changelogMd += `${changes}`; + }); + + return changelogMd; } -- cgit v1.2.3 From 84b820abc62c0aabea974ab8ed22f3ada05240fb Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 29 Mar 2018 20:03:11 +0200 Subject: Show semver diff --- packages/monorepo-scripts/src/custom_prepublish.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/custom_prepublish.ts b/packages/monorepo-scripts/src/custom_prepublish.ts index b18389fcd..98ed3e8d3 100644 --- a/packages/monorepo-scripts/src/custom_prepublish.ts +++ b/packages/monorepo-scripts/src/custom_prepublish.ts @@ -6,6 +6,7 @@ import * as _ from 'lodash'; import * as moment from 'moment'; import * as path from 'path'; import { exec as execAsync } from 'promisify-child-process'; +import semverDiff = require('semver-diff'); import semverSort = require('semver-sort'); import { Changelog, Changes, UpdatedPackage } from './types'; @@ -22,7 +23,9 @@ const TODAYS_TIMESTAMP = moment().unix(); const relevantLernaPackages = _.filter(allLernaPackages, pkg => { return _.includes(updatedPackageNames, pkg.package.name); }); + const packageToVersionChange: { [name: string]: string } = {}; _.each(relevantLernaPackages, lernaPackage => { + const packageName = lernaPackage.package.name; const changelogJSONPath = path.join(lernaPackage.location, 'CHANGELOG.json'); const changelogJSON = getChangelogJSONOrCreateIfMissing(lernaPackage.package.name, changelogJSONPath); let changelogs: Changelog[]; @@ -49,6 +52,7 @@ const TODAYS_TIMESTAMP = moment().unix(); ], }; changelogs = [newChangelogEntry, ...changelogs]; + packageToVersionChange[packageName] = semverDiff(currentVersion, nextPatchVersion); } else { // Update existing entry with timestamp const lastEntry = changelogs[0]; @@ -59,6 +63,7 @@ const TODAYS_TIMESTAMP = moment().unix(); const proposedNextVersion = lastEntry.version; lastEntry.version = updateVersionNumberIfNeeded(currentVersion, proposedNextVersion); changelogs[0] = lastEntry; + packageToVersionChange[packageName] = semverDiff(currentVersion, lastEntry.version); } // Save updated CHANGELOG.json @@ -68,6 +73,11 @@ const TODAYS_TIMESTAMP = moment().unix(); const changelogMdPath = path.join(lernaPackage.location, 'CHANGELOG.md'); fs.writeFileSync(changelogMdPath, changelogMd); }); + utils.log(`All CHANGELOGS successfully updated. Please commit and push these changes to development.`); + utils.log(`New package versions are:`); + _.each(packageToVersionChange, (versionChange: string, pkgName: string) => { + utils.log(`${pkgName}: ${versionChange}`); + }); })().catch(err => { utils.log(err); process.exit(1); -- cgit v1.2.3 From c9df3887316bdc0f7b19c87df21d566047445728 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Fri, 30 Mar 2018 12:28:48 +0200 Subject: Add committing and pushing CHANGELOG changes to Github --- packages/monorepo-scripts/package.json | 1 + packages/monorepo-scripts/src/custom_prepublish.ts | 19 +++++++++++++------ packages/monorepo-scripts/src/globals.d.ts | 1 + 3 files changed, 15 insertions(+), 6 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/package.json b/packages/monorepo-scripts/package.json index 09b7a340d..e8c7974e3 100644 --- a/packages/monorepo-scripts/package.json +++ b/packages/monorepo-scripts/package.json @@ -44,6 +44,7 @@ "promisify-child-process": "^1.0.5", "publish-release": "0xproject/publish-release", "rimraf": "^2.6.2", + "semver-diff": "^2.1.0", "semver-sort": "0.0.4" }, "publishConfig": { diff --git a/packages/monorepo-scripts/src/custom_prepublish.ts b/packages/monorepo-scripts/src/custom_prepublish.ts index 98ed3e8d3..2e6b78a71 100644 --- a/packages/monorepo-scripts/src/custom_prepublish.ts +++ b/packages/monorepo-scripts/src/custom_prepublish.ts @@ -12,8 +12,10 @@ import semverSort = require('semver-sort'); import { Changelog, Changes, UpdatedPackage } from './types'; import { utils } from './utils'; +const IS_DRY_RUN = true; const MONOREPO_ROOT_PATH = path.join(__dirname, '../../..'); const TODAYS_TIMESTAMP = moment().unix(); +const LERNA_EXECUTABLE = './node_modules/lerna/bin/lerna.js'; (async () => { const updatedPublicPackages = await getPublicLernaUpdatedPackagesAsync(); @@ -73,18 +75,23 @@ const TODAYS_TIMESTAMP = moment().unix(); const changelogMdPath = path.join(lernaPackage.location, 'CHANGELOG.md'); fs.writeFileSync(changelogMdPath, changelogMd); }); - utils.log(`All CHANGELOGS successfully updated. Please commit and push these changes to development.`); - utils.log(`New package versions are:`); - _.each(packageToVersionChange, (versionChange: string, pkgName: string) => { - utils.log(`${pkgName}: ${versionChange}`); - }); + + if (!IS_DRY_RUN) { + await execAsync(`git add . --all`, { cwd: MONOREPO_ROOT_PATH }); + await execAsync(`git commit -m "Updated CHANGELOGS"`, { cwd: MONOREPO_ROOT_PATH }); + await execAsync(`git push`, { cwd: MONOREPO_ROOT_PATH }); + } + + // _.each(packageToVersionChange, (versionChange: string, pkgName: string) => { + // utils.log(`${pkgName}: ${versionChange}`); + // }); })().catch(err => { utils.log(err); process.exit(1); }); async function getPublicLernaUpdatedPackagesAsync(): Promise { - const result = await execAsync(`./node_modules/lerna/bin/lerna.js updated --json`, { cwd: MONOREPO_ROOT_PATH }); + const result = await execAsync(`${LERNA_EXECUTABLE} updated --json`, { cwd: MONOREPO_ROOT_PATH }); const updatedPackages = JSON.parse(result.stdout); const updatedPublicPackages = _.filter(updatedPackages, updatedPackage => !updatedPackage.private); return updatedPublicPackages; diff --git a/packages/monorepo-scripts/src/globals.d.ts b/packages/monorepo-scripts/src/globals.d.ts index 90adc0b78..c5898d0f5 100644 --- a/packages/monorepo-scripts/src/globals.d.ts +++ b/packages/monorepo-scripts/src/globals.d.ts @@ -1,6 +1,7 @@ declare module 'async-child-process'; declare module 'publish-release'; declare module 'es6-promisify'; +declare module 'semver-diff'; // semver-sort declarations declare module 'semver-sort' { -- cgit v1.2.3 From ef4919217079dae761db9394527172ed06c1d030 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Fri, 30 Mar 2018 12:43:03 +0200 Subject: Add check that timestamp has been set before generating MD version --- packages/monorepo-scripts/src/custom_prepublish.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/custom_prepublish.ts b/packages/monorepo-scripts/src/custom_prepublish.ts index 2e6b78a71..f49b67142 100644 --- a/packages/monorepo-scripts/src/custom_prepublish.ts +++ b/packages/monorepo-scripts/src/custom_prepublish.ts @@ -139,7 +139,12 @@ CHANGELOG `; _.each(changelogs, changelog => { - const date = moment(changelog.timestamp, 'X').format('MMMM D, YYYY'); + if (_.isUndefined(changelog.timestamp)) { + throw new Error( + 'All CHANGELOG.json entries must be updated to include a timestamp before generating their MD version', + ); + } + const date = moment(`${changelog.timestamp}`, 'X').format('MMMM D, YYYY'); const title = `\n## v${changelog.version} - _${date}_\n\n`; changelogMd += title; -- cgit v1.2.3 From 52243373233b90344c5cb791bc8999e5fbbc0859 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Fri, 30 Mar 2018 14:29:07 +0200 Subject: Call `lerna publish` and supply it with new package versions --- packages/monorepo-scripts/src/custom_prepublish.ts | 43 +++++++++++++++++++--- packages/monorepo-scripts/src/types.ts | 7 ++++ 2 files changed, 45 insertions(+), 5 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/custom_prepublish.ts b/packages/monorepo-scripts/src/custom_prepublish.ts index f49b67142..4265ee9e2 100644 --- a/packages/monorepo-scripts/src/custom_prepublish.ts +++ b/packages/monorepo-scripts/src/custom_prepublish.ts @@ -5,17 +5,22 @@ import lernaGetPackages = require('lerna-get-packages'); import * as _ from 'lodash'; import * as moment from 'moment'; import * as path from 'path'; -import { exec as execAsync } from 'promisify-child-process'; +import { exec as execAsync, spawn } from 'promisify-child-process'; import semverDiff = require('semver-diff'); import semverSort = require('semver-sort'); -import { Changelog, Changes, UpdatedPackage } from './types'; +import { Changelog, Changes, SemVerIndex, UpdatedPackage } from './types'; import { utils } from './utils'; const IS_DRY_RUN = true; const MONOREPO_ROOT_PATH = path.join(__dirname, '../../..'); const TODAYS_TIMESTAMP = moment().unix(); const LERNA_EXECUTABLE = './node_modules/lerna/bin/lerna.js'; +const semverNameToIndex: { [semver: string]: number } = { + patch: SemVerIndex.Patch, + minor: SemVerIndex.Minor, + major: SemVerIndex.Major, +}; (async () => { const updatedPublicPackages = await getPublicLernaUpdatedPackagesAsync(); @@ -25,6 +30,9 @@ const LERNA_EXECUTABLE = './node_modules/lerna/bin/lerna.js'; const relevantLernaPackages = _.filter(allLernaPackages, pkg => { return _.includes(updatedPackageNames, pkg.package.name); }); + const relevantPackageNames = _.map(relevantLernaPackages, pkg => pkg.package.name); + utils.log(`Will update CHANGELOGs and publish: \n${relevantPackageNames.join('\n')}\n`); + const packageToVersionChange: { [name: string]: string } = {}; _.each(relevantLernaPackages, lernaPackage => { const packageName = lernaPackage.package.name; @@ -70,26 +78,51 @@ const LERNA_EXECUTABLE = './node_modules/lerna/bin/lerna.js'; // Save updated CHANGELOG.json fs.writeFileSync(changelogJSONPath, JSON.stringify(changelogs, null, '\t')); + utils.log(`${packageName}: Updated CHANGELOG.json`); // Generate updated CHANGELOG.md const changelogMd = generateChangelogMd(changelogs); const changelogMdPath = path.join(lernaPackage.location, 'CHANGELOG.md'); fs.writeFileSync(changelogMdPath, changelogMd); + utils.log(`${packageName}: Updated CHANGELOG.md`); }); if (!IS_DRY_RUN) { await execAsync(`git add . --all`, { cwd: MONOREPO_ROOT_PATH }); await execAsync(`git commit -m "Updated CHANGELOGS"`, { cwd: MONOREPO_ROOT_PATH }); await execAsync(`git push`, { cwd: MONOREPO_ROOT_PATH }); + utils.log(`Pushed CHANGELOG updates to Github`); } - // _.each(packageToVersionChange, (versionChange: string, pkgName: string) => { - // utils.log(`${pkgName}: ${versionChange}`); - // }); + await lernaPublishAsync(packageToVersionChange); })().catch(err => { utils.log(err); process.exit(1); }); +async function lernaPublishAsync(packageToVersionChange: { [name: string]: string }) { + // HACK: Lerna publish does not provide a way to specify multiple package versions as + // flags so instead we need to interact with their interactive prompt interface. + const child = spawn('lerna', ['publish'], { cwd: MONOREPO_ROOT_PATH }); + child.stdout.on('data', (data: Buffer) => { + const output = data.toString('utf8'); + const isVersionPrompt = _.includes(output, 'Select a new version'); + if (isVersionPrompt) { + const outputStripLeft = output.split('new version for ')[1]; + const packageName = outputStripLeft.split(' ')[0]; + let versionChange = packageToVersionChange[packageName]; + const isPrivatePackage = _.isUndefined(versionChange); + if (isPrivatePackage) { + versionChange = 'patch'; // Always patch updates to private packages. + } + child.stdin.write(`${semverNameToIndex[versionChange]}\n`); + } + const isFinalPrompt = _.includes(output, 'Are you sure you want to publish the above changes?'); + if (isFinalPrompt && !IS_DRY_RUN) { + child.stdin.write(`y\n`); + } + }); +} + async function getPublicLernaUpdatedPackagesAsync(): Promise { const result = await execAsync(`${LERNA_EXECUTABLE} updated --json`, { cwd: MONOREPO_ROOT_PATH }); const updatedPackages = JSON.parse(result.stdout); diff --git a/packages/monorepo-scripts/src/types.ts b/packages/monorepo-scripts/src/types.ts index 045316ab5..7adec202f 100644 --- a/packages/monorepo-scripts/src/types.ts +++ b/packages/monorepo-scripts/src/types.ts @@ -15,3 +15,10 @@ export interface Changelog { changes: Changes[]; isPublished?: boolean; } + +export enum SemVerIndex { + Invalid, + Patch, + Minor, + Major, +} -- cgit v1.2.3 From d502f793032d71156739b07b8d322a058c4aba62 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Fri, 30 Mar 2018 14:29:30 +0200 Subject: Rename prepublish to publish now that it goes straight to actually publishing the packages --- packages/monorepo-scripts/package.json | 2 +- packages/monorepo-scripts/src/custom_prepublish.ts | 197 --------------------- packages/monorepo-scripts/src/publish.ts | 197 +++++++++++++++++++++ 3 files changed, 198 insertions(+), 198 deletions(-) delete mode 100644 packages/monorepo-scripts/src/custom_prepublish.ts create mode 100644 packages/monorepo-scripts/src/publish.ts (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/package.json b/packages/monorepo-scripts/package.json index e8c7974e3..7c87199fc 100644 --- a/packages/monorepo-scripts/package.json +++ b/packages/monorepo-scripts/package.json @@ -7,7 +7,7 @@ "scripts": { "build:watch": "tsc -w", "deps_versions": "node ./lib/deps_versions.js", - "publish:prepublish": "yarn build; node ./lib/custom_prepublish.js", + "publish": "yarn build; node ./lib/publish.js", "convert_changelogs": "yarn build; node ./lib/convert_changelogs.js", "lint": "tslint --project . 'src/**/*.ts'", "clean": "shx rm -rf lib", diff --git a/packages/monorepo-scripts/src/custom_prepublish.ts b/packages/monorepo-scripts/src/custom_prepublish.ts deleted file mode 100644 index 4265ee9e2..000000000 --- a/packages/monorepo-scripts/src/custom_prepublish.ts +++ /dev/null @@ -1,197 +0,0 @@ -#!/usr/bin/env node - -import * as fs from 'fs'; -import lernaGetPackages = require('lerna-get-packages'); -import * as _ from 'lodash'; -import * as moment from 'moment'; -import * as path from 'path'; -import { exec as execAsync, spawn } from 'promisify-child-process'; -import semverDiff = require('semver-diff'); -import semverSort = require('semver-sort'); - -import { Changelog, Changes, SemVerIndex, UpdatedPackage } from './types'; -import { utils } from './utils'; - -const IS_DRY_RUN = true; -const MONOREPO_ROOT_PATH = path.join(__dirname, '../../..'); -const TODAYS_TIMESTAMP = moment().unix(); -const LERNA_EXECUTABLE = './node_modules/lerna/bin/lerna.js'; -const semverNameToIndex: { [semver: string]: number } = { - patch: SemVerIndex.Patch, - minor: SemVerIndex.Minor, - major: SemVerIndex.Major, -}; - -(async () => { - const updatedPublicPackages = await getPublicLernaUpdatedPackagesAsync(); - const updatedPackageNames = _.map(updatedPublicPackages, pkg => pkg.name); - - const allLernaPackages = lernaGetPackages(MONOREPO_ROOT_PATH); - const relevantLernaPackages = _.filter(allLernaPackages, pkg => { - return _.includes(updatedPackageNames, pkg.package.name); - }); - const relevantPackageNames = _.map(relevantLernaPackages, pkg => pkg.package.name); - utils.log(`Will update CHANGELOGs and publish: \n${relevantPackageNames.join('\n')}\n`); - - const packageToVersionChange: { [name: string]: string } = {}; - _.each(relevantLernaPackages, lernaPackage => { - const packageName = lernaPackage.package.name; - const changelogJSONPath = path.join(lernaPackage.location, 'CHANGELOG.json'); - const changelogJSON = getChangelogJSONOrCreateIfMissing(lernaPackage.package.name, changelogJSONPath); - let changelogs: Changelog[]; - try { - changelogs = JSON.parse(changelogJSON); - } catch (err) { - throw new Error( - `${lernaPackage.package.name}'s CHANGELOG.json contains invalid JSON. Please fix and try again.`, - ); - } - - const currentVersion = lernaPackage.package.version; - const shouldAddNewEntry = shouldAddNewChangelogEntry(changelogs); - if (shouldAddNewEntry) { - // Create a new entry for a patch version with generic changelog entry. - const nextPatchVersion = utils.getNextPatchVersion(currentVersion); - const newChangelogEntry: Changelog = { - timestamp: TODAYS_TIMESTAMP, - version: nextPatchVersion, - changes: [ - { - note: 'Dependencies updated', - }, - ], - }; - changelogs = [newChangelogEntry, ...changelogs]; - packageToVersionChange[packageName] = semverDiff(currentVersion, nextPatchVersion); - } else { - // Update existing entry with timestamp - const lastEntry = changelogs[0]; - if (_.isUndefined(lastEntry.timestamp)) { - lastEntry.timestamp = TODAYS_TIMESTAMP; - } - // Check version number is correct. - const proposedNextVersion = lastEntry.version; - lastEntry.version = updateVersionNumberIfNeeded(currentVersion, proposedNextVersion); - changelogs[0] = lastEntry; - packageToVersionChange[packageName] = semverDiff(currentVersion, lastEntry.version); - } - - // Save updated CHANGELOG.json - fs.writeFileSync(changelogJSONPath, JSON.stringify(changelogs, null, '\t')); - utils.log(`${packageName}: Updated CHANGELOG.json`); - // Generate updated CHANGELOG.md - const changelogMd = generateChangelogMd(changelogs); - const changelogMdPath = path.join(lernaPackage.location, 'CHANGELOG.md'); - fs.writeFileSync(changelogMdPath, changelogMd); - utils.log(`${packageName}: Updated CHANGELOG.md`); - }); - - if (!IS_DRY_RUN) { - await execAsync(`git add . --all`, { cwd: MONOREPO_ROOT_PATH }); - await execAsync(`git commit -m "Updated CHANGELOGS"`, { cwd: MONOREPO_ROOT_PATH }); - await execAsync(`git push`, { cwd: MONOREPO_ROOT_PATH }); - utils.log(`Pushed CHANGELOG updates to Github`); - } - - await lernaPublishAsync(packageToVersionChange); -})().catch(err => { - utils.log(err); - process.exit(1); -}); - -async function lernaPublishAsync(packageToVersionChange: { [name: string]: string }) { - // HACK: Lerna publish does not provide a way to specify multiple package versions as - // flags so instead we need to interact with their interactive prompt interface. - const child = spawn('lerna', ['publish'], { cwd: MONOREPO_ROOT_PATH }); - child.stdout.on('data', (data: Buffer) => { - const output = data.toString('utf8'); - const isVersionPrompt = _.includes(output, 'Select a new version'); - if (isVersionPrompt) { - const outputStripLeft = output.split('new version for ')[1]; - const packageName = outputStripLeft.split(' ')[0]; - let versionChange = packageToVersionChange[packageName]; - const isPrivatePackage = _.isUndefined(versionChange); - if (isPrivatePackage) { - versionChange = 'patch'; // Always patch updates to private packages. - } - child.stdin.write(`${semverNameToIndex[versionChange]}\n`); - } - const isFinalPrompt = _.includes(output, 'Are you sure you want to publish the above changes?'); - if (isFinalPrompt && !IS_DRY_RUN) { - child.stdin.write(`y\n`); - } - }); -} - -async function getPublicLernaUpdatedPackagesAsync(): Promise { - const result = await execAsync(`${LERNA_EXECUTABLE} updated --json`, { cwd: MONOREPO_ROOT_PATH }); - const updatedPackages = JSON.parse(result.stdout); - const updatedPublicPackages = _.filter(updatedPackages, updatedPackage => !updatedPackage.private); - return updatedPublicPackages; -} - -function updateVersionNumberIfNeeded(currentVersion: string, proposedNextVersion: string) { - if (proposedNextVersion === currentVersion) { - return utils.getNextPatchVersion(currentVersion); - } - const sortedVersions = semverSort.desc([proposedNextVersion, currentVersion]); - if (sortedVersions[0] !== proposedNextVersion) { - return utils.getNextPatchVersion(currentVersion); - } - return proposedNextVersion; -} - -function getChangelogJSONOrCreateIfMissing(packageName: string, changelogPath: string): string { - let changelogJSON: string; - try { - changelogJSON = fs.readFileSync(changelogPath, 'utf-8'); - return changelogJSON; - } catch (err) { - // If none exists, create new, empty one. - const emptyChangelogJSON = JSON.stringify([]); - fs.writeFileSync(changelogPath, emptyChangelogJSON); - return emptyChangelogJSON; - } -} - -function shouldAddNewChangelogEntry(changelogs: Changelog[]): boolean { - if (_.isEmpty(changelogs)) { - return true; - } - const lastEntry = changelogs[0]; - return !!lastEntry.isPublished; -} - -function generateChangelogMd(changelogs: Changelog[]): string { - let changelogMd = ` - -CHANGELOG - `; - - _.each(changelogs, changelog => { - if (_.isUndefined(changelog.timestamp)) { - throw new Error( - 'All CHANGELOG.json entries must be updated to include a timestamp before generating their MD version', - ); - } - const date = moment(`${changelog.timestamp}`, 'X').format('MMMM D, YYYY'); - const title = `\n## v${changelog.version} - _${date}_\n\n`; - changelogMd += title; - - let changes = ''; - _.each(changelog.changes, change => { - let line = ` * ${change.note}`; - if (!_.isUndefined(change.pr)) { - line += ` (#${change.pr})`; - } - line += '\n'; - changes += line; - }); - changelogMd += `${changes}`; - }); - - return changelogMd; -} diff --git a/packages/monorepo-scripts/src/publish.ts b/packages/monorepo-scripts/src/publish.ts new file mode 100644 index 000000000..4265ee9e2 --- /dev/null +++ b/packages/monorepo-scripts/src/publish.ts @@ -0,0 +1,197 @@ +#!/usr/bin/env node + +import * as fs from 'fs'; +import lernaGetPackages = require('lerna-get-packages'); +import * as _ from 'lodash'; +import * as moment from 'moment'; +import * as path from 'path'; +import { exec as execAsync, spawn } from 'promisify-child-process'; +import semverDiff = require('semver-diff'); +import semverSort = require('semver-sort'); + +import { Changelog, Changes, SemVerIndex, UpdatedPackage } from './types'; +import { utils } from './utils'; + +const IS_DRY_RUN = true; +const MONOREPO_ROOT_PATH = path.join(__dirname, '../../..'); +const TODAYS_TIMESTAMP = moment().unix(); +const LERNA_EXECUTABLE = './node_modules/lerna/bin/lerna.js'; +const semverNameToIndex: { [semver: string]: number } = { + patch: SemVerIndex.Patch, + minor: SemVerIndex.Minor, + major: SemVerIndex.Major, +}; + +(async () => { + const updatedPublicPackages = await getPublicLernaUpdatedPackagesAsync(); + const updatedPackageNames = _.map(updatedPublicPackages, pkg => pkg.name); + + const allLernaPackages = lernaGetPackages(MONOREPO_ROOT_PATH); + const relevantLernaPackages = _.filter(allLernaPackages, pkg => { + return _.includes(updatedPackageNames, pkg.package.name); + }); + const relevantPackageNames = _.map(relevantLernaPackages, pkg => pkg.package.name); + utils.log(`Will update CHANGELOGs and publish: \n${relevantPackageNames.join('\n')}\n`); + + const packageToVersionChange: { [name: string]: string } = {}; + _.each(relevantLernaPackages, lernaPackage => { + const packageName = lernaPackage.package.name; + const changelogJSONPath = path.join(lernaPackage.location, 'CHANGELOG.json'); + const changelogJSON = getChangelogJSONOrCreateIfMissing(lernaPackage.package.name, changelogJSONPath); + let changelogs: Changelog[]; + try { + changelogs = JSON.parse(changelogJSON); + } catch (err) { + throw new Error( + `${lernaPackage.package.name}'s CHANGELOG.json contains invalid JSON. Please fix and try again.`, + ); + } + + const currentVersion = lernaPackage.package.version; + const shouldAddNewEntry = shouldAddNewChangelogEntry(changelogs); + if (shouldAddNewEntry) { + // Create a new entry for a patch version with generic changelog entry. + const nextPatchVersion = utils.getNextPatchVersion(currentVersion); + const newChangelogEntry: Changelog = { + timestamp: TODAYS_TIMESTAMP, + version: nextPatchVersion, + changes: [ + { + note: 'Dependencies updated', + }, + ], + }; + changelogs = [newChangelogEntry, ...changelogs]; + packageToVersionChange[packageName] = semverDiff(currentVersion, nextPatchVersion); + } else { + // Update existing entry with timestamp + const lastEntry = changelogs[0]; + if (_.isUndefined(lastEntry.timestamp)) { + lastEntry.timestamp = TODAYS_TIMESTAMP; + } + // Check version number is correct. + const proposedNextVersion = lastEntry.version; + lastEntry.version = updateVersionNumberIfNeeded(currentVersion, proposedNextVersion); + changelogs[0] = lastEntry; + packageToVersionChange[packageName] = semverDiff(currentVersion, lastEntry.version); + } + + // Save updated CHANGELOG.json + fs.writeFileSync(changelogJSONPath, JSON.stringify(changelogs, null, '\t')); + utils.log(`${packageName}: Updated CHANGELOG.json`); + // Generate updated CHANGELOG.md + const changelogMd = generateChangelogMd(changelogs); + const changelogMdPath = path.join(lernaPackage.location, 'CHANGELOG.md'); + fs.writeFileSync(changelogMdPath, changelogMd); + utils.log(`${packageName}: Updated CHANGELOG.md`); + }); + + if (!IS_DRY_RUN) { + await execAsync(`git add . --all`, { cwd: MONOREPO_ROOT_PATH }); + await execAsync(`git commit -m "Updated CHANGELOGS"`, { cwd: MONOREPO_ROOT_PATH }); + await execAsync(`git push`, { cwd: MONOREPO_ROOT_PATH }); + utils.log(`Pushed CHANGELOG updates to Github`); + } + + await lernaPublishAsync(packageToVersionChange); +})().catch(err => { + utils.log(err); + process.exit(1); +}); + +async function lernaPublishAsync(packageToVersionChange: { [name: string]: string }) { + // HACK: Lerna publish does not provide a way to specify multiple package versions as + // flags so instead we need to interact with their interactive prompt interface. + const child = spawn('lerna', ['publish'], { cwd: MONOREPO_ROOT_PATH }); + child.stdout.on('data', (data: Buffer) => { + const output = data.toString('utf8'); + const isVersionPrompt = _.includes(output, 'Select a new version'); + if (isVersionPrompt) { + const outputStripLeft = output.split('new version for ')[1]; + const packageName = outputStripLeft.split(' ')[0]; + let versionChange = packageToVersionChange[packageName]; + const isPrivatePackage = _.isUndefined(versionChange); + if (isPrivatePackage) { + versionChange = 'patch'; // Always patch updates to private packages. + } + child.stdin.write(`${semverNameToIndex[versionChange]}\n`); + } + const isFinalPrompt = _.includes(output, 'Are you sure you want to publish the above changes?'); + if (isFinalPrompt && !IS_DRY_RUN) { + child.stdin.write(`y\n`); + } + }); +} + +async function getPublicLernaUpdatedPackagesAsync(): Promise { + const result = await execAsync(`${LERNA_EXECUTABLE} updated --json`, { cwd: MONOREPO_ROOT_PATH }); + const updatedPackages = JSON.parse(result.stdout); + const updatedPublicPackages = _.filter(updatedPackages, updatedPackage => !updatedPackage.private); + return updatedPublicPackages; +} + +function updateVersionNumberIfNeeded(currentVersion: string, proposedNextVersion: string) { + if (proposedNextVersion === currentVersion) { + return utils.getNextPatchVersion(currentVersion); + } + const sortedVersions = semverSort.desc([proposedNextVersion, currentVersion]); + if (sortedVersions[0] !== proposedNextVersion) { + return utils.getNextPatchVersion(currentVersion); + } + return proposedNextVersion; +} + +function getChangelogJSONOrCreateIfMissing(packageName: string, changelogPath: string): string { + let changelogJSON: string; + try { + changelogJSON = fs.readFileSync(changelogPath, 'utf-8'); + return changelogJSON; + } catch (err) { + // If none exists, create new, empty one. + const emptyChangelogJSON = JSON.stringify([]); + fs.writeFileSync(changelogPath, emptyChangelogJSON); + return emptyChangelogJSON; + } +} + +function shouldAddNewChangelogEntry(changelogs: Changelog[]): boolean { + if (_.isEmpty(changelogs)) { + return true; + } + const lastEntry = changelogs[0]; + return !!lastEntry.isPublished; +} + +function generateChangelogMd(changelogs: Changelog[]): string { + let changelogMd = ` + +CHANGELOG + `; + + _.each(changelogs, changelog => { + if (_.isUndefined(changelog.timestamp)) { + throw new Error( + 'All CHANGELOG.json entries must be updated to include a timestamp before generating their MD version', + ); + } + const date = moment(`${changelog.timestamp}`, 'X').format('MMMM D, YYYY'); + const title = `\n## v${changelog.version} - _${date}_\n\n`; + changelogMd += title; + + let changes = ''; + _.each(changelog.changes, change => { + let line = ` * ${change.note}`; + if (!_.isUndefined(change.pr)) { + line += ` (#${change.pr})`; + } + line += '\n'; + changes += line; + }); + changelogMd += `${changes}`; + }); + + return changelogMd; +} -- cgit v1.2.3 From 9c856de49ce0871b2093df90ab46410e91381424 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Fri, 30 Mar 2018 14:45:39 +0200 Subject: Move monorepo root constant to constants file --- packages/monorepo-scripts/src/constants.ts | 5 +++++ packages/monorepo-scripts/src/publish.ts | 14 +++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) create mode 100644 packages/monorepo-scripts/src/constants.ts (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/constants.ts b/packages/monorepo-scripts/src/constants.ts new file mode 100644 index 000000000..74387a159 --- /dev/null +++ b/packages/monorepo-scripts/src/constants.ts @@ -0,0 +1,5 @@ +import * as path from 'path'; + +export const constants = { + monorepoRootPath: path.join(__dirname, '../../..'), +}; diff --git a/packages/monorepo-scripts/src/publish.ts b/packages/monorepo-scripts/src/publish.ts index 4265ee9e2..3de382c50 100644 --- a/packages/monorepo-scripts/src/publish.ts +++ b/packages/monorepo-scripts/src/publish.ts @@ -9,11 +9,11 @@ import { exec as execAsync, spawn } from 'promisify-child-process'; import semverDiff = require('semver-diff'); import semverSort = require('semver-sort'); +import { constants } from './constants'; import { Changelog, Changes, SemVerIndex, UpdatedPackage } from './types'; import { utils } from './utils'; const IS_DRY_RUN = true; -const MONOREPO_ROOT_PATH = path.join(__dirname, '../../..'); const TODAYS_TIMESTAMP = moment().unix(); const LERNA_EXECUTABLE = './node_modules/lerna/bin/lerna.js'; const semverNameToIndex: { [semver: string]: number } = { @@ -26,7 +26,7 @@ const semverNameToIndex: { [semver: string]: number } = { const updatedPublicPackages = await getPublicLernaUpdatedPackagesAsync(); const updatedPackageNames = _.map(updatedPublicPackages, pkg => pkg.name); - const allLernaPackages = lernaGetPackages(MONOREPO_ROOT_PATH); + const allLernaPackages = lernaGetPackages(constants.monorepoRootPath); const relevantLernaPackages = _.filter(allLernaPackages, pkg => { return _.includes(updatedPackageNames, pkg.package.name); }); @@ -87,9 +87,9 @@ const semverNameToIndex: { [semver: string]: number } = { }); if (!IS_DRY_RUN) { - await execAsync(`git add . --all`, { cwd: MONOREPO_ROOT_PATH }); - await execAsync(`git commit -m "Updated CHANGELOGS"`, { cwd: MONOREPO_ROOT_PATH }); - await execAsync(`git push`, { cwd: MONOREPO_ROOT_PATH }); + await execAsync(`git add . --all`, { cwd: constants.monorepoRootPath }); + await execAsync(`git commit -m "Updated CHANGELOGS"`, { cwd: constants.monorepoRootPath }); + await execAsync(`git push`, { cwd: constants.monorepoRootPath }); utils.log(`Pushed CHANGELOG updates to Github`); } @@ -102,7 +102,7 @@ const semverNameToIndex: { [semver: string]: number } = { async function lernaPublishAsync(packageToVersionChange: { [name: string]: string }) { // HACK: Lerna publish does not provide a way to specify multiple package versions as // flags so instead we need to interact with their interactive prompt interface. - const child = spawn('lerna', ['publish'], { cwd: MONOREPO_ROOT_PATH }); + const child = spawn('lerna', ['publish'], { cwd: constants.monorepoRootPath }); child.stdout.on('data', (data: Buffer) => { const output = data.toString('utf8'); const isVersionPrompt = _.includes(output, 'Select a new version'); @@ -124,7 +124,7 @@ async function lernaPublishAsync(packageToVersionChange: { [name: string]: strin } async function getPublicLernaUpdatedPackagesAsync(): Promise { - const result = await execAsync(`${LERNA_EXECUTABLE} updated --json`, { cwd: MONOREPO_ROOT_PATH }); + const result = await execAsync(`${LERNA_EXECUTABLE} updated --json`, { cwd: constants.monorepoRootPath }); const updatedPackages = JSON.parse(result.stdout); const updatedPublicPackages = _.filter(updatedPackages, updatedPackage => !updatedPackage.private); return updatedPublicPackages; -- cgit v1.2.3 From 95eb11405156a42ae734ed74945b44a9125d23b3 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Fri, 30 Mar 2018 14:46:15 +0200 Subject: rename variable called `path` to `includePath` to avoid conflict with `path` package --- packages/monorepo-scripts/src/postpublish_utils.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/postpublish_utils.ts b/packages/monorepo-scripts/src/postpublish_utils.ts index 898b00c47..c4f3135a5 100644 --- a/packages/monorepo-scripts/src/postpublish_utils.ts +++ b/packages/monorepo-scripts/src/postpublish_utils.ts @@ -122,14 +122,16 @@ export const postpublishUtils = { }, adjustFileIncludePaths(fileIncludes: string[], cwd: string): string[] { const fileIncludesAdjusted = _.map(fileIncludes, fileInclude => { - let path = _.startsWith(fileInclude, './') ? `${cwd}/${fileInclude.substr(2)}` : `${cwd}/${fileInclude}`; + let includePath = _.startsWith(fileInclude, './') + ? `${cwd}/${fileInclude.substr(2)}` + : `${cwd}/${fileInclude}`; // HACK: tsconfig.json needs wildcard directory endings as `/**/*` // but TypeDoc needs it as `/**` in order to pick up files at the root - if (_.endsWith(path, '/**/*')) { - path = path.slice(0, -2); + if (_.endsWith(includePath, '/**/*')) { + includePath = includePath.slice(0, -2); } - return path; + return includePath; }); return fileIncludesAdjusted; }, -- cgit v1.2.3 From 4bc6096ec0415a83446b274f249c57ceb4fe93a3 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Fri, 30 Mar 2018 14:48:20 +0200 Subject: Fetch Github release notes from CHANGELOG.json and update CHANGELOG once they've been successfully published to Github --- packages/monorepo-scripts/src/postpublish_utils.ts | 36 ++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/postpublish_utils.ts b/packages/monorepo-scripts/src/postpublish_utils.ts index c4f3135a5..fb1680afd 100644 --- a/packages/monorepo-scripts/src/postpublish_utils.ts +++ b/packages/monorepo-scripts/src/postpublish_utils.ts @@ -1,9 +1,12 @@ import { execAsync } from 'async-child-process'; import * as promisify from 'es6-promisify'; +import * as fs from 'fs'; import * as _ from 'lodash'; +import * as path from 'path'; import * as publishRelease from 'publish-release'; import semverSort = require('semver-sort'); +import { constants } from './constants'; import { utils } from './utils'; const publishReleaseAsync = promisify(publishRelease); @@ -88,23 +91,52 @@ export const postpublishUtils = { ); }, async publishReleaseNotesAsync(cwd: string, packageName: string, version: string, assets: string[]): Promise { + const notes = this.getReleaseNotes(packageName); const releaseName = this.getReleaseName(packageName, version); const tag = this.getTag(packageName, version); - utils.log('POSTPUBLISH: Releasing ', releaseName, '...'); const finalAssets = this.adjustAssetPaths(cwd, assets); + utils.log('POSTPUBLISH: Releasing ', releaseName, '...'); const result = await publishReleaseAsync({ token: githubPersonalAccessToken, owner: '0xProject', repo: '0x-monorepo', tag, name: releaseName, - notes: 'N/A', + notes, draft: false, prerelease: false, reuseRelease: true, reuseDraftOnly: false, assets, }); + this.updateChangelogIsPublished(packageName); + }, + getReleaseNotes(packageName: string) { + const changelogJSONPath = path.join(constants.monorepoRootPath, 'packages', packageName, 'CHANGELOG.json'); + const changelogJSON = fs.readFileSync(changelogJSONPath, 'utf-8'); + const changelogs = JSON.parse(changelogJSON); + const latestLog = changelogs[0]; + if (_.isUndefined(latestLog.isPublished)) { + let notes = ''; + _.each(latestLog.changes, change => { + notes = `* ${change.note}`; + if (change.pr) { + notes += ` (${change.pr})`; + } + notes += `\n`; + }); + return notes; + } + return 'N/A'; + }, + updateChangelogIsPublished(packageName: string) { + const changelogJSONPath = path.join(constants.monorepoRootPath, 'packages', packageName, 'CHANGELOG.json'); + const changelogJSON = fs.readFileSync(changelogJSONPath, 'utf-8'); + const changelogs = JSON.parse(changelogJSON); + const latestLog = changelogs[0]; + latestLog.isPublished = true; + changelogs[0] = latestLog; + fs.writeFileSync(changelogJSONPath, JSON.stringify(changelogs, null, '\t')); }, getTag(packageName: string, version: string) { return `${packageName}@${version}`; -- cgit v1.2.3 From ddb8e26becb3f8d5bd8426663dbdea2cf1bf484f Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Fri, 30 Mar 2018 15:07:24 +0200 Subject: Expose publish command from top-level dir --- packages/monorepo-scripts/src/publish.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/publish.ts b/packages/monorepo-scripts/src/publish.ts index 3de382c50..a05cf6d04 100644 --- a/packages/monorepo-scripts/src/publish.ts +++ b/packages/monorepo-scripts/src/publish.ts @@ -102,7 +102,9 @@ const semverNameToIndex: { [semver: string]: number } = { async function lernaPublishAsync(packageToVersionChange: { [name: string]: string }) { // HACK: Lerna publish does not provide a way to specify multiple package versions as // flags so instead we need to interact with their interactive prompt interface. - const child = spawn('lerna', ['publish'], { cwd: constants.monorepoRootPath }); + const child = spawn('lerna', ['publish', '--registry=https://registry.npmjs.org/'], { + cwd: constants.monorepoRootPath, + }); child.stdout.on('data', (data: Buffer) => { const output = data.toString('utf8'); const isVersionPrompt = _.includes(output, 'Select a new version'); -- cgit v1.2.3 From 08a69ebd6e9c04326836ab2ee486d1f1abe7c566 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Fri, 30 Mar 2018 15:27:47 +0200 Subject: Add more logging --- packages/monorepo-scripts/src/publish.ts | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/publish.ts b/packages/monorepo-scripts/src/publish.ts index a05cf6d04..8093cb66c 100644 --- a/packages/monorepo-scripts/src/publish.ts +++ b/packages/monorepo-scripts/src/publish.ts @@ -93,6 +93,11 @@ const semverNameToIndex: { [semver: string]: number } = { utils.log(`Pushed CHANGELOG updates to Github`); } + utils.log('Version updates to apply:'); + _.each(packageToVersionChange, (versionChange: string, packageName: string) => { + utils.log(`${packageName} -> ${versionChange}`); + }); + utils.log(`Calling 'lerna publish'...`); await lernaPublishAsync(packageToVersionChange); })().catch(err => { utils.log(err); @@ -121,6 +126,10 @@ async function lernaPublishAsync(packageToVersionChange: { [name: string]: strin const isFinalPrompt = _.includes(output, 'Are you sure you want to publish the above changes?'); if (isFinalPrompt && !IS_DRY_RUN) { child.stdin.write(`y\n`); + } else if (isFinalPrompt && IS_DRY_RUN) { + utils.log( + `Submitted all versions to Lerna but since this is a dry run, did not confirm. You need to CTRL-C to exit.`, + ); } }); } -- cgit v1.2.3 From f55a300f43da3e2460837aedfac9287f1342c46c Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Fri, 30 Mar 2018 15:28:08 +0200 Subject: Set IS_DRY_RUN to false --- packages/monorepo-scripts/src/publish.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/publish.ts b/packages/monorepo-scripts/src/publish.ts index 8093cb66c..905fee196 100644 --- a/packages/monorepo-scripts/src/publish.ts +++ b/packages/monorepo-scripts/src/publish.ts @@ -13,7 +13,7 @@ import { constants } from './constants'; import { Changelog, Changes, SemVerIndex, UpdatedPackage } from './types'; import { utils } from './utils'; -const IS_DRY_RUN = true; +const IS_DRY_RUN = false; const TODAYS_TIMESTAMP = moment().unix(); const LERNA_EXECUTABLE = './node_modules/lerna/bin/lerna.js'; const semverNameToIndex: { [semver: string]: number } = { -- cgit v1.2.3 From ddd3d284d94043b27977714d4f49353c01c40bd3 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Fri, 30 Mar 2018 15:48:39 +0200 Subject: Remove CHANGELOG.json files since will be generated on development --- packages/monorepo-scripts/CHANGELOG.json | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 packages/monorepo-scripts/CHANGELOG.json (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/CHANGELOG.json b/packages/monorepo-scripts/CHANGELOG.json deleted file mode 100644 index a8418d03f..000000000 --- a/packages/monorepo-scripts/CHANGELOG.json +++ /dev/null @@ -1,12 +0,0 @@ -[ - { - "version": "0.1.13", - "changes": [ - { - "note": "Add postpublish utils" - } - ], - "timestamp": 1521327600, - "isPublished": true - } -] \ No newline at end of file -- cgit v1.2.3 From 33ec9fdf47de4d8ab9d8ce43adedf4615dece4d9 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Fri, 30 Mar 2018 15:49:09 +0200 Subject: Fixes for clarity --- packages/monorepo-scripts/src/publish.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/publish.ts b/packages/monorepo-scripts/src/publish.ts index 905fee196..e2c0edff8 100644 --- a/packages/monorepo-scripts/src/publish.ts +++ b/packages/monorepo-scripts/src/publish.ts @@ -105,7 +105,7 @@ const semverNameToIndex: { [semver: string]: number } = { }); async function lernaPublishAsync(packageToVersionChange: { [name: string]: string }) { - // HACK: Lerna publish does not provide a way to specify multiple package versions as + // HACK: Lerna publish does not provide a way to specify multiple package versions via // flags so instead we need to interact with their interactive prompt interface. const child = spawn('lerna', ['publish', '--registry=https://registry.npmjs.org/'], { cwd: constants.monorepoRootPath, @@ -121,7 +121,8 @@ async function lernaPublishAsync(packageToVersionChange: { [name: string]: strin if (isPrivatePackage) { versionChange = 'patch'; // Always patch updates to private packages. } - child.stdin.write(`${semverNameToIndex[versionChange]}\n`); + const semVerIndex = semverNameToIndex[versionChange]; + child.stdin.write(`${semVerIndex}\n`); } const isFinalPrompt = _.includes(output, 'Are you sure you want to publish the above changes?'); if (isFinalPrompt && !IS_DRY_RUN) { -- cgit v1.2.3 From bf52ce7e725224de23c2a5318b8224cc92e5188a Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Mon, 2 Apr 2018 02:40:48 +0900 Subject: Add temp comment, clean up code --- .../monorepo-scripts/src/convert_changelogs.ts | 29 ++++++++++++++++------ 1 file changed, 21 insertions(+), 8 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/convert_changelogs.ts b/packages/monorepo-scripts/src/convert_changelogs.ts index 76ce50ced..7ba4c544e 100644 --- a/packages/monorepo-scripts/src/convert_changelogs.ts +++ b/packages/monorepo-scripts/src/convert_changelogs.ts @@ -1,4 +1,9 @@ #!/usr/bin/env node +/** + * TEMPORARY SCRIPT + * This script exists to migrate the legacy CHANGELOG.md to the canonical CHANGELOG.md + * TODO: Remove after migration is successful and committed. + */ import * as fs from 'fs'; import lernaGetPackages = require('lerna-get-packages'); @@ -6,13 +11,14 @@ import * as _ from 'lodash'; import * as moment from 'moment'; import * as path from 'path'; +import { constants } from './constants'; import { Changelog, Changes, UpdatedPackage } from './types'; import { utils } from './utils'; -const MONOREPO_ROOT_PATH = path.join(__dirname, '../../..'); +const HEADER_PRAGMA = '##'; (async () => { - const allLernaPackages = lernaGetPackages(MONOREPO_ROOT_PATH); + const allLernaPackages = lernaGetPackages(constants.monorepoRootPath); const publicLernaPackages = _.filter(allLernaPackages, pkg => !pkg.package.private); _.each(publicLernaPackages, lernaPackage => { const changelogMdIfExists = getChangelogMdIfExists(lernaPackage.package.name, lernaPackage.location); @@ -20,14 +26,20 @@ const MONOREPO_ROOT_PATH = path.join(__dirname, '../../..'); throw new Error(`${lernaPackage.package.name} should have CHANGELOG.md b/c it's public. Add one.`); } - const lines = (changelogMdIfExists as any).split('\n'); + const lines = (changelogMdIfExists as string).split('\n'); const changelogs: Changelog[] = []; let changelog: Changelog = { version: '', changes: [], }; + /** + * Example MD entry: + * ## v0.3.1 - _March 18, 2018_ + * + * * Add TS types for `yargs` (#400) + */ for (const line of lines) { - if (_.startsWith(line, '## ')) { + if (_.startsWith(line, `${HEADER_PRAGMA} `)) { let version = line.substr(4).split(' - ')[0]; if (version === '0.x.x') { version = utils.getNextPatchVersion(lernaPackage.package.version); @@ -47,7 +59,7 @@ const MONOREPO_ROOT_PATH = path.join(__dirname, '../../..'); if (!_.includes(dateStr, 'TBD')) { changelog.isPublished = true; } - (changelogs as any).push(changelog); + changelogs.push(changelog); } else if (_.includes(line, '* ')) { const note = line.split('* ')[1].split(' (#')[0]; const prChunk = line.split(' (#')[1]; @@ -55,10 +67,12 @@ const MONOREPO_ROOT_PATH = path.join(__dirname, '../../..'); if (!_.isUndefined(prChunk)) { pr = prChunk.split(')')[0]; } - const changes = { + const changes: Changes = { note, - pr, }; + if (!_.isUndefined(pr)) { + changes.pr = _.parseInt(pr); + } changelog.changes.push(changes); } } @@ -77,7 +91,6 @@ function getChangelogMdIfExists(packageName: string, location: string): string | changelogMd = fs.readFileSync(changelogPath, 'utf-8'); return changelogMd; } catch (err) { - // If none exists, create new, empty one. return undefined; } } -- cgit v1.2.3 From 0e33f45f3dbf7934692e3baa3daa90ddab0c184f Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Mon, 2 Apr 2018 04:10:18 +0900 Subject: Improve naming --- packages/monorepo-scripts/src/publish.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/publish.ts b/packages/monorepo-scripts/src/publish.ts index e2c0edff8..1821dad28 100644 --- a/packages/monorepo-scripts/src/publish.ts +++ b/packages/monorepo-scripts/src/publish.ts @@ -27,14 +27,14 @@ const semverNameToIndex: { [semver: string]: number } = { const updatedPackageNames = _.map(updatedPublicPackages, pkg => pkg.name); const allLernaPackages = lernaGetPackages(constants.monorepoRootPath); - const relevantLernaPackages = _.filter(allLernaPackages, pkg => { + const updatedPublicLernaPackages = _.filter(allLernaPackages, pkg => { return _.includes(updatedPackageNames, pkg.package.name); }); - const relevantPackageNames = _.map(relevantLernaPackages, pkg => pkg.package.name); + const relevantPackageNames = _.map(updatedPublicLernaPackages, pkg => pkg.package.name); utils.log(`Will update CHANGELOGs and publish: \n${relevantPackageNames.join('\n')}\n`); const packageToVersionChange: { [name: string]: string } = {}; - _.each(relevantLernaPackages, lernaPackage => { + _.each(updatedPublicLernaPackages, lernaPackage => { const packageName = lernaPackage.package.name; const changelogJSONPath = path.join(lernaPackage.location, 'CHANGELOG.json'); const changelogJSON = getChangelogJSONOrCreateIfMissing(lernaPackage.package.name, changelogJSONPath); -- cgit v1.2.3 From d187a31e3833f21c86da070bceb858813e4848e3 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Mon, 2 Apr 2018 05:10:27 +0900 Subject: Make dry-run configurable from top-level package.json --- packages/monorepo-scripts/src/publish.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/publish.ts b/packages/monorepo-scripts/src/publish.ts index 1821dad28..2f18f2a9c 100644 --- a/packages/monorepo-scripts/src/publish.ts +++ b/packages/monorepo-scripts/src/publish.ts @@ -13,7 +13,7 @@ import { constants } from './constants'; import { Changelog, Changes, SemVerIndex, UpdatedPackage } from './types'; import { utils } from './utils'; -const IS_DRY_RUN = false; +const IS_DRY_RUN = process.env.IS_DRY_RUN === 'false'; const TODAYS_TIMESTAMP = moment().unix(); const LERNA_EXECUTABLE = './node_modules/lerna/bin/lerna.js'; const semverNameToIndex: { [semver: string]: number } = { -- cgit v1.2.3 From 688f8615ffb817b6bead7d3ab18d355c484d812a Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Mon, 2 Apr 2018 05:12:03 +0900 Subject: Fix TSLint error --- packages/monorepo-scripts/src/convert_changelogs.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/convert_changelogs.ts b/packages/monorepo-scripts/src/convert_changelogs.ts index 7ba4c544e..c62cf844b 100644 --- a/packages/monorepo-scripts/src/convert_changelogs.ts +++ b/packages/monorepo-scripts/src/convert_changelogs.ts @@ -26,7 +26,7 @@ const HEADER_PRAGMA = '##'; throw new Error(`${lernaPackage.package.name} should have CHANGELOG.md b/c it's public. Add one.`); } - const lines = (changelogMdIfExists as string).split('\n'); + const lines = changelogMdIfExists.split('\n'); const changelogs: Changelog[] = []; let changelog: Changelog = { version: '', -- cgit v1.2.3 From cd23f220a0a3ebd79667a169923284102509400c Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Mon, 2 Apr 2018 08:51:10 +0900 Subject: Remove semi-colons from monorepo-scripts package.json --- packages/monorepo-scripts/README.md | 2 +- packages/monorepo-scripts/package.json | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/README.md b/packages/monorepo-scripts/README.md index ea1d43bd5..dbdfdf135 100644 --- a/packages/monorepo-scripts/README.md +++ b/packages/monorepo-scripts/README.md @@ -9,7 +9,7 @@ This repository contains a few helpful scripts for working with this mono repo. In order to reduce the size of this repo, we try and use the same versions of dependencies between packages. To make it easier to discover version discrepancies between packages, you can run: ```bash -yarn deps_versions +yarn scripts:deps_versions ``` This will list out any dependencies that differ in versions between packages. diff --git a/packages/monorepo-scripts/package.json b/packages/monorepo-scripts/package.json index 7c87199fc..3cef65b19 100644 --- a/packages/monorepo-scripts/package.json +++ b/packages/monorepo-scripts/package.json @@ -6,12 +6,14 @@ "types": "lib/index.d.ts", "scripts": { "build:watch": "tsc -w", - "deps_versions": "node ./lib/deps_versions.js", - "publish": "yarn build; node ./lib/publish.js", - "convert_changelogs": "yarn build; node ./lib/convert_changelogs.js", "lint": "tslint --project . 'src/**/*.ts'", "clean": "shx rm -rf lib", - "build": "tsc" + "build": "tsc", + "publish": "run-s build script:publish", + "convert_changelogs": "run-s build script:convert_changelogs", + "script:deps_versions": "node ./lib/deps_versions.js", + "script:publish": "node ./lib/publish.js", + "script:convert_changelogs": "node ./lib/convert_changelogs.js" }, "repository": { "type": "git", @@ -30,6 +32,7 @@ "@types/node": "^8.0.53", "@types/rimraf": "^2.0.2", "lerna-get-packages": "^1.0.0", + "npm-run-all": "^4.1.2", "shx": "^0.2.2", "tslint": "5.8.0", "typescript": "2.7.1" -- cgit v1.2.3 From 2a6a71ea6cd89d39142f51530d06e80ffc44e722 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Mon, 2 Apr 2018 15:49:48 +0900 Subject: Add prettier run on generated CHANGELOG.json and fix scripts --- packages/monorepo-scripts/package.json | 4 ++-- packages/monorepo-scripts/src/convert_changelogs.ts | 13 +++++++++---- packages/monorepo-scripts/src/publish.ts | 15 +++++++++------ 3 files changed, 20 insertions(+), 12 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/package.json b/packages/monorepo-scripts/package.json index 3cef65b19..0ce7c1339 100644 --- a/packages/monorepo-scripts/package.json +++ b/packages/monorepo-scripts/package.json @@ -9,10 +9,10 @@ "lint": "tslint --project . 'src/**/*.ts'", "clean": "shx rm -rf lib", "build": "tsc", - "publish": "run-s build script:publish", + "test:publish": "run-s build script:publish", "convert_changelogs": "run-s build script:convert_changelogs", "script:deps_versions": "node ./lib/deps_versions.js", - "script:publish": "node ./lib/publish.js", + "script:publish": "IS_DRY_RUN=true node ./lib/publish.js", "script:convert_changelogs": "node ./lib/convert_changelogs.js" }, "repository": { diff --git a/packages/monorepo-scripts/src/convert_changelogs.ts b/packages/monorepo-scripts/src/convert_changelogs.ts index c62cf844b..f4c4d51a2 100644 --- a/packages/monorepo-scripts/src/convert_changelogs.ts +++ b/packages/monorepo-scripts/src/convert_changelogs.ts @@ -10,6 +10,7 @@ import lernaGetPackages = require('lerna-get-packages'); import * as _ from 'lodash'; import * as moment from 'moment'; import * as path from 'path'; +import { exec as execAsync } from 'promisify-child-process'; import { constants } from './constants'; import { Changelog, Changes, UpdatedPackage } from './types'; @@ -20,7 +21,7 @@ const HEADER_PRAGMA = '##'; (async () => { const allLernaPackages = lernaGetPackages(constants.monorepoRootPath); const publicLernaPackages = _.filter(allLernaPackages, pkg => !pkg.package.private); - _.each(publicLernaPackages, lernaPackage => { + for (const lernaPackage of publicLernaPackages) { const changelogMdIfExists = getChangelogMdIfExists(lernaPackage.package.name, lernaPackage.location); if (_.isUndefined(changelogMdIfExists)) { throw new Error(`${lernaPackage.package.name} should have CHANGELOG.md b/c it's public. Add one.`); @@ -76,9 +77,13 @@ const HEADER_PRAGMA = '##'; changelog.changes.push(changes); } } - const changelogJson = JSON.stringify(changelogs, null, '\t'); - fs.writeFileSync(`${lernaPackage.location}/CHANGELOG.json`, changelogJson); - }); + const changelogJson = JSON.stringify(changelogs); + const changelogJsonPath = `${lernaPackage.location}/CHANGELOG.json`; + fs.writeFileSync(changelogJsonPath, changelogJson); + await execAsync(`prettier --write ${changelogJsonPath} --config .prettierrc`, { + cwd: constants.monorepoRootPath, + }); + } })().catch(err => { utils.log(err.stdout); process.exit(1); diff --git a/packages/monorepo-scripts/src/publish.ts b/packages/monorepo-scripts/src/publish.ts index 2f18f2a9c..2263e2f8c 100644 --- a/packages/monorepo-scripts/src/publish.ts +++ b/packages/monorepo-scripts/src/publish.ts @@ -13,7 +13,7 @@ import { constants } from './constants'; import { Changelog, Changes, SemVerIndex, UpdatedPackage } from './types'; import { utils } from './utils'; -const IS_DRY_RUN = process.env.IS_DRY_RUN === 'false'; +const IS_DRY_RUN = process.env.IS_DRY_RUN === 'true'; const TODAYS_TIMESTAMP = moment().unix(); const LERNA_EXECUTABLE = './node_modules/lerna/bin/lerna.js'; const semverNameToIndex: { [semver: string]: number } = { @@ -30,11 +30,11 @@ const semverNameToIndex: { [semver: string]: number } = { const updatedPublicLernaPackages = _.filter(allLernaPackages, pkg => { return _.includes(updatedPackageNames, pkg.package.name); }); - const relevantPackageNames = _.map(updatedPublicLernaPackages, pkg => pkg.package.name); - utils.log(`Will update CHANGELOGs and publish: \n${relevantPackageNames.join('\n')}\n`); + const updatedPublicLernaPackageNames = _.map(updatedPublicLernaPackages, pkg => pkg.package.name); + utils.log(`Will update CHANGELOGs and publish: \n${updatedPublicLernaPackageNames.join('\n')}\n`); const packageToVersionChange: { [name: string]: string } = {}; - _.each(updatedPublicLernaPackages, lernaPackage => { + for (const lernaPackage of updatedPublicLernaPackages) { const packageName = lernaPackage.package.name; const changelogJSONPath = path.join(lernaPackage.location, 'CHANGELOG.json'); const changelogJSON = getChangelogJSONOrCreateIfMissing(lernaPackage.package.name, changelogJSONPath); @@ -77,14 +77,17 @@ const semverNameToIndex: { [semver: string]: number } = { } // Save updated CHANGELOG.json - fs.writeFileSync(changelogJSONPath, JSON.stringify(changelogs, null, '\t')); + fs.writeFileSync(changelogJSONPath, JSON.stringify(changelogs)); + await execAsync(`prettier --write ${changelogJSONPath} --config .prettierrc`, { + cwd: constants.monorepoRootPath, + }); utils.log(`${packageName}: Updated CHANGELOG.json`); // Generate updated CHANGELOG.md const changelogMd = generateChangelogMd(changelogs); const changelogMdPath = path.join(lernaPackage.location, 'CHANGELOG.md'); fs.writeFileSync(changelogMdPath, changelogMd); utils.log(`${packageName}: Updated CHANGELOG.md`); - }); + } if (!IS_DRY_RUN) { await execAsync(`git add . --all`, { cwd: constants.monorepoRootPath }); -- cgit v1.2.3 From 3f230a8fdbca3728a4d6b1677d776b8e0dbbae6a Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Mon, 2 Apr 2018 15:53:31 +0900 Subject: Move prettify command to utils and also call it on CHANGELOG.md --- packages/monorepo-scripts/src/convert_changelogs.ts | 10 ++++------ packages/monorepo-scripts/src/publish.ts | 5 ++--- packages/monorepo-scripts/src/utils.ts | 6 ++++++ 3 files changed, 12 insertions(+), 9 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/convert_changelogs.ts b/packages/monorepo-scripts/src/convert_changelogs.ts index f4c4d51a2..71383ee7c 100644 --- a/packages/monorepo-scripts/src/convert_changelogs.ts +++ b/packages/monorepo-scripts/src/convert_changelogs.ts @@ -77,12 +77,10 @@ const HEADER_PRAGMA = '##'; changelog.changes.push(changes); } } - const changelogJson = JSON.stringify(changelogs); - const changelogJsonPath = `${lernaPackage.location}/CHANGELOG.json`; - fs.writeFileSync(changelogJsonPath, changelogJson); - await execAsync(`prettier --write ${changelogJsonPath} --config .prettierrc`, { - cwd: constants.monorepoRootPath, - }); + const changelogJSONPath = JSON.stringify(changelogs); + const changelogJSONPathPath = `${lernaPackage.location}/CHANGELOG.json`; + fs.writeFileSync(changelogJSONPathPath, changelogJSONPath); + await utils.prettifyAsync(changelogJSONPath, constants.monorepoRootPath); } })().catch(err => { utils.log(err.stdout); diff --git a/packages/monorepo-scripts/src/publish.ts b/packages/monorepo-scripts/src/publish.ts index 2263e2f8c..30e5bd0e1 100644 --- a/packages/monorepo-scripts/src/publish.ts +++ b/packages/monorepo-scripts/src/publish.ts @@ -78,14 +78,13 @@ const semverNameToIndex: { [semver: string]: number } = { // Save updated CHANGELOG.json fs.writeFileSync(changelogJSONPath, JSON.stringify(changelogs)); - await execAsync(`prettier --write ${changelogJSONPath} --config .prettierrc`, { - cwd: constants.monorepoRootPath, - }); + await utils.prettifyAsync(changelogJSONPath, constants.monorepoRootPath); utils.log(`${packageName}: Updated CHANGELOG.json`); // Generate updated CHANGELOG.md const changelogMd = generateChangelogMd(changelogs); const changelogMdPath = path.join(lernaPackage.location, 'CHANGELOG.md'); fs.writeFileSync(changelogMdPath, changelogMd); + await utils.prettifyAsync(changelogMdPath, constants.monorepoRootPath); utils.log(`${packageName}: Updated CHANGELOG.md`); } diff --git a/packages/monorepo-scripts/src/utils.ts b/packages/monorepo-scripts/src/utils.ts index 73f6260d3..9aa37e272 100644 --- a/packages/monorepo-scripts/src/utils.ts +++ b/packages/monorepo-scripts/src/utils.ts @@ -1,4 +1,5 @@ import * as _ from 'lodash'; +import { exec as execAsync, spawn } from 'promisify-child-process'; export const utils = { log(...args: any[]): void { @@ -11,4 +12,9 @@ export const utils = { const newPatchVersion = `${versionSegments[0]}.${versionSegments[1]}.${newPatch}`; return newPatchVersion; }, + async prettifyAsync(filePath: string, cwd: string) { + await execAsync(`prettier --write ${filePath} --config .prettierrc`, { + cwd, + }); + }, }; -- cgit v1.2.3 From 01c6fd92e8ebc93d333278a356a4a0fac26b58c2 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Mon, 2 Apr 2018 16:06:36 +0900 Subject: Update moment, no longer need separate moment types --- packages/monorepo-scripts/package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/package.json b/packages/monorepo-scripts/package.json index 0ce7c1339..ed263d5cb 100644 --- a/packages/monorepo-scripts/package.json +++ b/packages/monorepo-scripts/package.json @@ -28,7 +28,6 @@ "devDependencies": { "@0xproject/tslint-config": "0.4.8", "@types/glob": "^5.0.33", - "@types/moment": "2.13.0", "@types/node": "^8.0.53", "@types/rimraf": "^2.0.2", "lerna-get-packages": "^1.0.0", @@ -43,7 +42,7 @@ "es6-promisify": "^5.0.0", "glob": "^7.1.2", "lodash": "^4.17.4", - "moment": "2.13.0", + "moment": "2.21.0", "promisify-child-process": "^1.0.5", "publish-release": "0xproject/publish-release", "rimraf": "^2.6.2", -- cgit v1.2.3 From 76c5945017c945122c3e72bc7dcdf5dd048b4a22 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Mon, 2 Apr 2018 16:40:02 +0900 Subject: Default to 4sp --- packages/monorepo-scripts/src/convert_changelogs.ts | 2 +- packages/monorepo-scripts/src/publish.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/convert_changelogs.ts b/packages/monorepo-scripts/src/convert_changelogs.ts index 71383ee7c..c75abfc44 100644 --- a/packages/monorepo-scripts/src/convert_changelogs.ts +++ b/packages/monorepo-scripts/src/convert_changelogs.ts @@ -77,7 +77,7 @@ const HEADER_PRAGMA = '##'; changelog.changes.push(changes); } } - const changelogJSONPath = JSON.stringify(changelogs); + const changelogJSONPath = JSON.stringify(changelogs, null, 4); const changelogJSONPathPath = `${lernaPackage.location}/CHANGELOG.json`; fs.writeFileSync(changelogJSONPathPath, changelogJSONPath); await utils.prettifyAsync(changelogJSONPath, constants.monorepoRootPath); diff --git a/packages/monorepo-scripts/src/publish.ts b/packages/monorepo-scripts/src/publish.ts index 30e5bd0e1..240158c77 100644 --- a/packages/monorepo-scripts/src/publish.ts +++ b/packages/monorepo-scripts/src/publish.ts @@ -77,7 +77,7 @@ const semverNameToIndex: { [semver: string]: number } = { } // Save updated CHANGELOG.json - fs.writeFileSync(changelogJSONPath, JSON.stringify(changelogs)); + fs.writeFileSync(changelogJSONPath, JSON.stringify(changelogs, null, 4)); await utils.prettifyAsync(changelogJSONPath, constants.monorepoRootPath); utils.log(`${packageName}: Updated CHANGELOG.json`); // Generate updated CHANGELOG.md @@ -162,7 +162,7 @@ function getChangelogJSONOrCreateIfMissing(packageName: string, changelogPath: s return changelogJSON; } catch (err) { // If none exists, create new, empty one. - const emptyChangelogJSON = JSON.stringify([]); + const emptyChangelogJSON = JSON.stringify([], null, 4); fs.writeFileSync(changelogPath, emptyChangelogJSON); return emptyChangelogJSON; } -- cgit v1.2.3 From 723276ae3fe460ebb89b9b0948c3423e021e2cf9 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Mon, 2 Apr 2018 16:56:14 +0900 Subject: Fix hasty find/replace --- packages/monorepo-scripts/src/convert_changelogs.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/src/convert_changelogs.ts b/packages/monorepo-scripts/src/convert_changelogs.ts index c75abfc44..b5be14ed8 100644 --- a/packages/monorepo-scripts/src/convert_changelogs.ts +++ b/packages/monorepo-scripts/src/convert_changelogs.ts @@ -77,9 +77,9 @@ const HEADER_PRAGMA = '##'; changelog.changes.push(changes); } } - const changelogJSONPath = JSON.stringify(changelogs, null, 4); - const changelogJSONPathPath = `${lernaPackage.location}/CHANGELOG.json`; - fs.writeFileSync(changelogJSONPathPath, changelogJSONPath); + const changelogJSON = JSON.stringify(changelogs, null, 4); + const changelogJSONPath = `${lernaPackage.location}/CHANGELOG.json`; + fs.writeFileSync(changelogJSONPath, changelogJSON); await utils.prettifyAsync(changelogJSONPath, constants.monorepoRootPath); } })().catch(err => { -- cgit v1.2.3