Merge pull request #514 from 0xProject/publishImprovements

Add Doc Page Check To Publish Flow
This commit is contained in:
Fabio Berger 2018-04-11 18:55:59 +09:00 committed by GitHub
commit c44f9e56ad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 199 additions and 30 deletions

View File

@ -18,6 +18,7 @@
"lerna:rebuild": "run-s lerna:clean lerna:build",
"lerna:publish": "run-s lerna:install lerna:rebuild script:publish",
"lerna:publish:dry": "run-s lerna:install lerna:rebuild script:publish:dry",
"lerna:stage_docs": "lerna run docs:stage",
"script:publish": "node ./packages/monorepo-scripts/lib/publish.js",
"script:publish:dry": "IS_DRY_RUN=true yarn script:publish"
},

View File

@ -29,6 +29,7 @@
"@0xproject/tslint-config": "0.4.13",
"@types/glob": "^5.0.33",
"@types/node": "^8.0.53",
"@types/opn": "^5.1.0",
"@types/rimraf": "^2.0.2",
"depcheck": "^0.6.9",
"lerna-get-packages": "^1.0.0",
@ -45,7 +46,9 @@
"glob": "^7.1.2",
"lodash": "^4.17.4",
"moment": "2.21.0",
"opn": "^5.3.0",
"promisify-child-process": "^1.0.5",
"prompt": "^1.0.0",
"publish-release": "0xproject/publish-release",
"rimraf": "^2.6.2",
"semver-diff": "^2.1.0",

View File

@ -2,4 +2,5 @@ import * as path from 'path';
export const constants = {
monorepoRootPath: path.join(__dirname, '../../..'),
stagingWebsite: 'http://staging-0xproject.s3-website-us-east-1.amazonaws.com',
};

View File

@ -3,6 +3,11 @@ declare module 'publish-release';
declare module 'es6-promisify';
declare module 'semver-diff';
declare module 'prompt' {
const start: () => void;
const get: (promptMessages: string[], callback: (err: Error, result: string) => void) => void;
}
// semver-sort declarations
declare module 'semver-sort' {
const desc: (versions: string[]) => string[];
@ -15,6 +20,7 @@ declare interface LernaPackage {
version: string;
name: string;
main?: string;
scripts?: { [command: string]: string };
config?: {
additionalTsTypings?: string[];
};

View File

@ -1,18 +1,23 @@
#!/usr/bin/env node
import * as promisify from 'es6-promisify';
import * as fs from 'fs';
import lernaGetPackages = require('lerna-get-packages');
import * as _ from 'lodash';
import * as moment from 'moment';
import opn = require('opn');
import * as path from 'path';
import { exec as execAsync, spawn } from 'promisify-child-process';
import * as prompt from 'prompt';
import semverDiff = require('semver-diff');
import semverSort = require('semver-sort');
import { constants } from './constants';
import { Changelog, Changes, SemVerIndex, UpdatedPackage } from './types';
import { Changelog, Changes, PackageToVersionChange, SemVerIndex, UpdatedPackage } from './types';
import { utils } from './utils';
const DOC_GEN_COMMAND = 'docs:json';
const NPM_NAMESPACE = '@0xproject/';
const IS_DRY_RUN = process.env.IS_DRY_RUN === 'true';
const TODAYS_TIMESTAMP = moment().unix();
const LERNA_EXECUTABLE = './node_modules/lerna/bin/lerna.js';
@ -21,8 +26,95 @@ const semverNameToIndex: { [semver: string]: number } = {
minor: SemVerIndex.Minor,
major: SemVerIndex.Major,
};
const packageNameToWebsitePath: { [name: string]: string } = {
'0x.js': '0xjs',
'web3-wrapper': 'web3_wrapper',
contracts: 'contracts',
connect: 'connect',
'json-schemas': 'json-schemas',
deployer: 'deployer',
'sol-cov': 'sol-cov',
subproviders: 'subproviders',
};
(async () => {
// Fetch public, updated Lerna packages
const updatedPublicLernaPackages = await getUpdatedPublicLernaPackagesAsync();
await confirmDocPagesRenderAsync(updatedPublicLernaPackages);
// Update CHANGELOGs
const updatedPublicLernaPackageNames = _.map(updatedPublicLernaPackages, pkg => pkg.package.name);
utils.log(`Will update CHANGELOGs and publish: \n${updatedPublicLernaPackageNames.join('\n')}\n`);
const packageToVersionChange = await updateChangeLogsAsync(updatedPublicLernaPackages);
// Push changelog changes to Github
if (!IS_DRY_RUN) {
await pushChangelogsToGithubAsync();
}
// Call LernaPublish
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);
process.exit(1);
});
async function confirmDocPagesRenderAsync(packages: LernaPackage[]) {
// push docs to staging
utils.log("Upload all docJson's to S3 staging...");
await execAsync(`yarn lerna:stage_docs`, { cwd: constants.monorepoRootPath });
// deploy website to staging
utils.log('Deploy website to staging...');
const pathToWebsite = `${constants.monorepoRootPath}/packages/website`;
await execAsync(`yarn deploy_staging`, { cwd: pathToWebsite });
const packagesWithDocs = _.filter(packages, pkg => {
const scriptsIfExists = pkg.package.scripts;
if (_.isUndefined(scriptsIfExists)) {
throw new Error('Found a public package without any scripts in package.json');
}
return !_.isUndefined(scriptsIfExists[DOC_GEN_COMMAND]);
});
_.each(packagesWithDocs, pkg => {
const name = pkg.package.name;
const nameWithoutPrefix = _.startsWith(name, NPM_NAMESPACE) ? name.split('@0xproject/')[1] : name;
const docSegmentIfExists = packageNameToWebsitePath[nameWithoutPrefix];
if (_.isUndefined(docSegmentIfExists)) {
throw new Error(
`Found package '${name}' with doc commands but no corresponding docSegment in monorepo_scripts
package.ts. Please add an entry for it and try again.`,
);
}
const link = `${constants.stagingWebsite}/docs/${docSegmentIfExists}`;
// tslint:disable-next-line:no-floating-promises
opn(link);
});
prompt.start();
const message = 'Do all the doc pages render properly? (yn)';
const result = await promisify(prompt.get)([message]);
const didConfirm = result[message] === 'y';
if (!didConfirm) {
utils.log('Publish process aborted.');
process.exit(0);
}
}
async function pushChangelogsToGithubAsync() {
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`);
}
async function getUpdatedPublicLernaPackagesAsync(): Promise<LernaPackage[]> {
const updatedPublicPackages = await getPublicLernaUpdatedPackagesAsync();
const updatedPackageNames = _.map(updatedPublicPackages, pkg => pkg.name);
@ -30,10 +122,11 @@ const semverNameToIndex: { [semver: string]: number } = {
const updatedPublicLernaPackages = _.filter(allLernaPackages, pkg => {
return _.includes(updatedPackageNames, pkg.package.name);
});
const updatedPublicLernaPackageNames = _.map(updatedPublicLernaPackages, pkg => pkg.package.name);
utils.log(`Will update CHANGELOGs and publish: \n${updatedPublicLernaPackageNames.join('\n')}\n`);
return updatedPublicLernaPackages;
}
const packageToVersionChange: { [name: string]: string } = {};
async function updateChangeLogsAsync(updatedPublicLernaPackages: LernaPackage[]): Promise<PackageToVersionChange> {
const packageToVersionChange: PackageToVersionChange = {};
for (const lernaPackage of updatedPublicLernaPackages) {
const packageName = lernaPackage.package.name;
const changelogJSONPath = path.join(lernaPackage.location, 'CHANGELOG.json');
@ -88,23 +181,8 @@ const semverNameToIndex: { [semver: string]: number } = {
utils.log(`${packageName}: Updated CHANGELOG.md`);
}
if (!IS_DRY_RUN) {
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`);
}
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);
process.exit(1);
});
return packageToVersionChange;
}
async function lernaPublishAsync(packageToVersionChange: { [name: string]: string }) {
// HACK: Lerna publish does not provide a way to specify multiple package versions via

View File

@ -21,3 +21,7 @@ export enum SemVerIndex {
Minor,
Major,
}
export interface PackageToVersionChange {
[name: string]: string;
}

View File

@ -6,7 +6,7 @@
"types": "lib/src/index.d.ts",
"scripts": {
"build:watch": "tsc -w",
"build": "tsc && copyfiles -u 2 './lib/monorepo_scripts/**/*' ./scripts",
"build": "tsc && copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts",
"clean": "shx rm -rf lib scripts",
"lint": "tslint --project . 'src/**/*.ts'",
"test": "run-s clean build run_mocha",

View File

@ -289,6 +289,12 @@
version "8.10.0"
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.0.tgz#f5d649cc49af8ed6507d15dc6e9b43fe8b927540"
"@types/opn@^5.1.0":
version "5.1.0"
resolved "https://registry.yarnpkg.com/@types/opn/-/opn-5.1.0.tgz#bff7bc371677f4bdbb37884400e03fd81f743927"
dependencies:
"@types/node" "*"
"@types/query-string@^5.0.1":
version "5.1.0"
resolved "https://registry.yarnpkg.com/@types/query-string/-/query-string-5.1.0.tgz#7f40cdea49ddafa0ea4f3db35fb6c24d3bfd4dcc"
@ -803,10 +809,14 @@ async@2.6.0, async@^2.0.1, async@^2.1.2, async@^2.4.0, async@^2.5.0:
dependencies:
lodash "^4.14.0"
async@^0.9.0:
async@^0.9.0, async@~0.9.0:
version "0.9.2"
resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d"
async@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/async/-/async-1.0.0.tgz#f8fc04ca3a13784ade9e1641af98578cfbd647a9"
async@~1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/async/-/async-1.2.1.tgz#a4816a17cd5ff516dfa2c7698a453369b9790de0"
@ -2220,6 +2230,10 @@ colormin@^1.0.5:
css-color-names "0.0.4"
has "^1.0.1"
colors@1.0.x:
version "1.0.3"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b"
colors@1.1.2, colors@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63"
@ -2810,6 +2824,10 @@ currently-unhandled@^0.4.1:
dependencies:
array-find-index "^1.0.1"
cycle@1.0.x:
version "1.0.3"
resolved "https://registry.yarnpkg.com/cycle/-/cycle-1.0.3.tgz#21e80b2be8580f98b468f379430662b046c34ad2"
cyclist@~0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640"
@ -2975,6 +2993,10 @@ deep-equal@^1.0.0, deep-equal@^1.0.1, deep-equal@~1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5"
deep-equal@~0.2.1:
version "0.2.2"
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-0.2.2.tgz#84b745896f34c684e98f2ce0e42abaf43bba017d"
deep-extend@~0.4.0:
version "0.4.2"
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f"
@ -3916,6 +3938,10 @@ extsprintf@^1.2.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
eyes@0.1.x:
version "0.1.8"
resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0"
fake-merkle-patricia-tree@^1.0.1, fake-merkle-patricia-tree@~1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/fake-merkle-patricia-tree/-/fake-merkle-patricia-tree-1.0.1.tgz#4b8c3acfb520afadf9860b1f14cd8ce3402cddd3"
@ -5103,6 +5129,10 @@ hyphenate-style-name@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.2.tgz#31160a36930adaf1fc04c6074f7eb41465d4ec4b"
i@0.3.x:
version "0.3.6"
resolved "https://registry.yarnpkg.com/i/-/i-0.3.6.tgz#d96c92732076f072711b6b10fd7d4f65ad8ee23d"
iconv-lite@0.4.19, iconv-lite@^0.4.17, iconv-lite@~0.4.13:
version "0.4.19"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b"
@ -5666,7 +5696,7 @@ isomorphic-fetch@^2.1.1, isomorphic-fetch@^2.2.0, isomorphic-fetch@^2.2.1:
node-fetch "^1.0.1"
whatwg-fetch ">=0.10.0"
isstream@~0.1.2:
isstream@0.1.x, isstream@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
@ -6840,7 +6870,7 @@ mkdirp-promise@^5.0.1:
dependencies:
mkdirp "*"
mkdirp@*, mkdirp@0.5.1, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1:
mkdirp@*, mkdirp@0.5.1, mkdirp@0.5.x, mkdirp@0.x.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
dependencies:
@ -6978,6 +7008,10 @@ natives@^1.1.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/natives/-/natives-1.1.2.tgz#4437ca1ed8a7f047531ccdfaf2792853df4efa1c"
ncp@1.0.x:
version "1.0.1"
resolved "https://registry.yarnpkg.com/ncp/-/ncp-1.0.1.tgz#d15367e5cb87432ba117d2bf80fdf45aecfb4246"
negotiator@0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9"
@ -7395,7 +7429,7 @@ opn@^4.0.0:
object-assign "^4.0.1"
pinkie-promise "^2.0.0"
opn@^5.1.0:
opn@^5.1.0, opn@^5.3.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/opn/-/opn-5.3.0.tgz#64871565c863875f052cfdf53d3e3cb5adb53b1c"
dependencies:
@ -7752,10 +7786,14 @@ pkg-dir@^2.0.0:
dependencies:
find-up "^2.1.0"
pkginfo@^0.3.0:
pkginfo@0.3.x, pkginfo@^0.3.0:
version "0.3.1"
resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.3.1.tgz#5b29f6a81f70717142e09e765bbeab97b4f81e21"
pkginfo@0.x.x:
version "0.4.1"
resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.4.1.tgz#b5418ef0439de5425fc4995042dced14fb2a84ff"
plur@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/plur/-/plur-2.1.2.tgz#7482452c1a0f508e3e344eaec312c91c29dc655a"
@ -8245,6 +8283,17 @@ promisify-child-process@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/promisify-child-process/-/promisify-child-process-1.0.5.tgz#817ad1aec92c013d83bb37e1f143e9b4033d9669"
prompt@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/prompt/-/prompt-1.0.0.tgz#8e57123c396ab988897fb327fd3aedc3e735e4fe"
dependencies:
colors "^1.1.2"
pkginfo "0.x.x"
read "1.0.x"
revalidator "0.1.x"
utile "0.3.x"
winston "2.1.x"
prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.6, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1:
version "15.6.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.1.tgz#36644453564255ddda391191fb3a125cbdf654ca"
@ -8717,7 +8766,7 @@ read-pkg@^3.0.0:
normalize-package-data "^2.3.2"
path-type "^3.0.0"
read@~1.0.5:
read@1.0.x, read@~1.0.5:
version "1.0.7"
resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4"
dependencies:
@ -9097,13 +9146,17 @@ ret@~0.1.10:
version "0.1.15"
resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc"
revalidator@0.1.x:
version "0.1.8"
resolved "https://registry.yarnpkg.com/revalidator/-/revalidator-0.1.8.tgz#fece61bfa0c1b52a206bd6b18198184bdd523a3b"
right-align@^0.1.1:
version "0.1.3"
resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef"
dependencies:
align-text "^0.1.1"
rimraf@2, rimraf@^2.2.8, rimraf@^2.5.1, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2:
rimraf@2, rimraf@2.x.x, rimraf@^2.2.8, rimraf@^2.5.1, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2:
version "2.6.2"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36"
dependencies:
@ -9815,7 +9868,7 @@ stack-trace@0.0.9:
version "0.0.9"
resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.9.tgz#a8f6eaeca90674c333e7c43953f275b451510695"
stack-trace@~0.0.9:
stack-trace@0.0.x, stack-trace@~0.0.9:
version "0.0.10"
resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0"
@ -10942,6 +10995,17 @@ util@0.10.3, util@^0.10.3:
dependencies:
inherits "2.0.1"
utile@0.3.x:
version "0.3.0"
resolved "https://registry.yarnpkg.com/utile/-/utile-0.3.0.tgz#1352c340eb820e4d8ddba039a4fbfaa32ed4ef3a"
dependencies:
async "~0.9.0"
deep-equal "~0.2.1"
i "0.3.x"
mkdirp "0.x.x"
ncp "1.0.x"
rimraf "2.x.x"
utils-merge@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
@ -11568,6 +11632,18 @@ window-size@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075"
winston@2.1.x:
version "2.1.1"
resolved "https://registry.yarnpkg.com/winston/-/winston-2.1.1.tgz#3c9349d196207fd1bdff9d4bc43ef72510e3a12e"
dependencies:
async "~1.0.0"
colors "1.0.x"
cycle "1.0.x"
eyes "0.1.x"
isstream "0.1.x"
pkginfo "0.3.x"
stack-trace "0.0.x"
word-wrap@1.2.3:
version "1.2.3"
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"