Add removeGitTags script that can be run after a failed Lerna publish

This commit is contained in:
Fabio Berger
2018-04-19 11:40:22 +09:00
parent 62fcb51e1a
commit 7dd3b2d38b
4 changed files with 105 additions and 1 deletions

View File

@@ -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",

View File

@@ -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',
};

View File

@@ -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);
});

View File

@@ -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<LernaPackage[]> {
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<UpdatedPackage[]> {
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;
},
};