From 7dd3b2d38b4e4ee2f1daa24c90f503b2e7ad0422 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 19 Apr 2018 11:40:22 +0900 Subject: Add removeGitTags script that can be run after a failed Lerna publish --- packages/monorepo-scripts/package.json | 4 +- packages/monorepo-scripts/src/constants.ts | 1 + packages/monorepo-scripts/src/remove_tags.ts | 56 ++++++++++++++++++++++++++++ packages/monorepo-scripts/src/utils.ts | 45 ++++++++++++++++++++++ 4 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 packages/monorepo-scripts/src/remove_tags.ts (limited to 'packages/monorepo-scripts') diff --git a/packages/monorepo-scripts/package.json b/packages/monorepo-scripts/package.json index 8bf1d83e5..733a099d1 100644 --- a/packages/monorepo-scripts/package.json +++ b/packages/monorepo-scripts/package.json @@ -11,9 +11,11 @@ "build": "tsc", "test:publish": "run-s build script:publish", "find_unused_deps": "run-s build script:find_unused_deps", + "remove_tags": "run-s build script:remove_tags", "script:deps_versions": "node ./lib/deps_versions.js", "script:publish": "IS_DRY_RUN=true node ./lib/publish.js", - "script:find_unused_deps": "node ./lib/find_unused_dependencies.js" + "script:find_unused_deps": "node ./lib/find_unused_dependencies.js", + "script:remove_tags": "node ./lib/remove_tags.js" }, "repository": { "type": "git", diff --git a/packages/monorepo-scripts/src/constants.ts b/packages/monorepo-scripts/src/constants.ts index 081a49332..e93b27820 100644 --- a/packages/monorepo-scripts/src/constants.ts +++ b/packages/monorepo-scripts/src/constants.ts @@ -3,4 +3,5 @@ import * as path from 'path'; export const constants = { monorepoRootPath: path.join(__dirname, '../../..'), stagingWebsite: 'http://staging-0xproject.s3-website-us-east-1.amazonaws.com', + lernaExecutable: './node_modules/lerna/bin/lerna.js', }; diff --git a/packages/monorepo-scripts/src/remove_tags.ts b/packages/monorepo-scripts/src/remove_tags.ts new file mode 100644 index 000000000..a91c6ec39 --- /dev/null +++ b/packages/monorepo-scripts/src/remove_tags.ts @@ -0,0 +1,56 @@ +#!/usr/bin/env node + +import lernaGetPackages = require('lerna-get-packages'); +import * as _ from 'lodash'; +import * as path from 'path'; +import { exec as execAsync } from 'promisify-child-process'; +import semverSort = require('semver-sort'); + +import { constants } from './constants'; +import { Changelog } from './types'; +import { utils } from './utils'; + +(async () => { + const shouldIncludePrivate = true; + const updatedPublicLernaPackages = await utils.getUpdatedLernaPackagesAsync(shouldIncludePrivate); + + for (const lernaPackage of updatedPublicLernaPackages) { + const packageName = lernaPackage.package.name; + const currentVersion = lernaPackage.package.version; + const changelogJSONPath = path.join(lernaPackage.location, 'CHANGELOG.json'); + const changelogJSONIfExists = utils.getChangelogJSONIfExists(changelogJSONPath); + + let latestChangelogVersion: string; + if (!_.isUndefined(changelogJSONIfExists)) { + let changelogs: Changelog[]; + try { + changelogs = JSON.parse(changelogJSONIfExists); + } catch (err) { + throw new Error( + `${lernaPackage.package.name}'s CHANGELOG.json contains invalid JSON. Please fix and try again.`, + ); + } + latestChangelogVersion = changelogs[0].version; + } else { + latestChangelogVersion = utils.getNextPatchVersion(currentVersion); + } + + const sortedVersions = semverSort.desc([latestChangelogVersion, currentVersion]); + if (sortedVersions[0] === latestChangelogVersion && latestChangelogVersion !== currentVersion) { + const tagName = `${packageName}@${latestChangelogVersion}`; + try { + await execAsync(`git tag -d ${tagName}`, { cwd: constants.monorepoRootPath }); + utils.log(`removed tag: ${tagName}`); + } catch (err) { + if (_.includes(err.message, 'not found')) { + utils.log(`Could not find tag: ${tagName}`); + } else { + throw err; + } + } + } + } +})().catch(err => { + utils.log(err); + process.exit(1); +}); diff --git a/packages/monorepo-scripts/src/utils.ts b/packages/monorepo-scripts/src/utils.ts index 9aa37e272..3a16bf91d 100644 --- a/packages/monorepo-scripts/src/utils.ts +++ b/packages/monorepo-scripts/src/utils.ts @@ -1,6 +1,11 @@ +import * as fs from 'fs'; +import lernaGetPackages = require('lerna-get-packages'); import * as _ from 'lodash'; import { exec as execAsync, spawn } from 'promisify-child-process'; +import { constants } from './constants'; +import { UpdatedPackage } from './types'; + export const utils = { log(...args: any[]): void { console.log(...args); // tslint:disable-line:no-console @@ -17,4 +22,44 @@ export const utils = { cwd, }); }, + async getUpdatedLernaPackagesAsync(shouldIncludePrivate: boolean): Promise { + const updatedPublicPackages = await this.getLernaUpdatedPackagesAsync(shouldIncludePrivate); + const updatedPackageNames = _.map(updatedPublicPackages, pkg => pkg.name); + + const allLernaPackages = lernaGetPackages(constants.monorepoRootPath); + const updatedPublicLernaPackages = _.filter(allLernaPackages, pkg => { + return _.includes(updatedPackageNames, pkg.package.name); + }); + return updatedPublicLernaPackages; + }, + async getLernaUpdatedPackagesAsync(shouldIncludePrivate: boolean): Promise { + const result = await execAsync(`${constants.lernaExecutable} updated --json`, { + cwd: constants.monorepoRootPath, + }); + const updatedPackages = JSON.parse(result.stdout); + if (!shouldIncludePrivate) { + const updatedPublicPackages = _.filter(updatedPackages, updatedPackage => !updatedPackage.private); + return updatedPublicPackages; + } + return updatedPackages; + }, + getChangelogJSONIfExists(changelogPath: string) { + let changelogJSON: string; + try { + changelogJSON = fs.readFileSync(changelogPath, 'utf-8'); + return changelogJSON; + } catch (err) { + return undefined; + } + }, + getChangelogJSONOrCreateIfMissing(changelogPath: string): string { + const changelogIfExists = this.getChangelogJSONIfExists(changelogPath); + if (_.isUndefined(changelogIfExists)) { + // If none exists, create new, empty one. + const emptyChangelogJSON = JSON.stringify([], null, 4); + fs.writeFileSync(changelogPath, emptyChangelogJSON); + return emptyChangelogJSON; + } + return changelogIfExists; + }, }; -- cgit