From ef6aa9f41b9f21d033034c51e8880ec9d70b6b40 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Mon, 12 Mar 2018 22:13:24 +0100 Subject: Convert 0x.js scripts to TS, move the prepublishUtils script to `dev-utils` and also convert it to TS. --- packages/0x.js/monorepo_scripts/globals.d.ts | 12 ++++ packages/0x.js/monorepo_scripts/postpublish.ts | 44 +++++++++++++ packages/0x.js/monorepo_scripts/stagedocs.ts | 30 +++++++++ packages/0x.js/package.json | 3 +- packages/0x.js/tsconfig_monorepo.json | 9 +++ packages/dev-utils/CHANGELOG.md | 4 ++ packages/dev-utils/package.json | 2 + packages/dev-utils/src/globals.d.ts | 7 +++ packages/dev-utils/src/index.ts | 1 + packages/dev-utils/src/postpublish_utils.ts | 86 ++++++++++++++++++++++++++ packages/dev-utils/src/utils.ts | 5 ++ 11 files changed, 202 insertions(+), 1 deletion(-) create mode 100644 packages/0x.js/monorepo_scripts/globals.d.ts create mode 100644 packages/0x.js/monorepo_scripts/postpublish.ts create mode 100644 packages/0x.js/monorepo_scripts/stagedocs.ts create mode 100644 packages/0x.js/tsconfig_monorepo.json create mode 100644 packages/dev-utils/src/postpublish_utils.ts create mode 100644 packages/dev-utils/src/utils.ts (limited to 'packages') diff --git a/packages/0x.js/monorepo_scripts/globals.d.ts b/packages/0x.js/monorepo_scripts/globals.d.ts new file mode 100644 index 000000000..bbfbdaa6a --- /dev/null +++ b/packages/0x.js/monorepo_scripts/globals.d.ts @@ -0,0 +1,12 @@ +declare module 'async-child-process'; +declare module 'publish-release'; + +// semver-sort declarations +declare module 'semver-sort' { + const desc: (versions: string[]) => string[]; +} + +declare module '*.json' { + const value: any; + export default value; +} diff --git a/packages/0x.js/monorepo_scripts/postpublish.ts b/packages/0x.js/monorepo_scripts/postpublish.ts new file mode 100644 index 000000000..13ab013be --- /dev/null +++ b/packages/0x.js/monorepo_scripts/postpublish.ts @@ -0,0 +1,44 @@ +import { postpublishUtils } from '@0xproject/dev-utils'; +import { execAsync } from 'async-child-process'; +import * as _ from 'lodash'; + +import * as packageJSON from '../package.json'; +import * as tsConfig from '../tsconfig.json'; + +const cwd = `${__dirname}/..`; +const subPackageName = (packageJSON as any).name; +// Include any external packages that are part of the 0x.js public interface +// to this array so that TypeDoc picks it up and adds it to the Docs JSON +// So far, we only have @0xproject/types as part of 0x.js's public interface. +const fileIncludes = [...(tsConfig as any).include, '../types/src/index.ts']; +const fileIncludesAdjusted = postpublishUtils.adjustFileIncludePaths(fileIncludes, __dirname); +const projectFiles = fileIncludesAdjusted.join(' '); +const S3BucketPath = 's3://0xjs-docs-jsons/'; + +(async () => { + const tagAndVersion = await postpublishUtils.getLatestTagAndVersionAsync(subPackageName); + const tag = tagAndVersion.tag; + const version = tagAndVersion.version; + + const releaseName = postpublishUtils.getReleaseName(subPackageName, version); + const assets = [`${__dirname}/../_bundles/index.js`, `${__dirname}/../_bundles/index.min.js`]; + const release = await postpublishUtils.publishReleaseNotesAsync(tag, releaseName, assets); + + // tslint:disable-next-line:no-console + console.log('POSTPUBLISH: Release successful, generating docs...'); + const jsonFilePath = `${__dirname}/../${postpublishUtils.generatedDocsDirectoryName}/index.json`; + + const result = await execAsync(`JSON_FILE_PATH=${jsonFilePath} PROJECT_FILES="${projectFiles}" yarn docs:json`, { + cwd, + }); + if (!_.isEmpty(result.stderr)) { + throw new Error(result.stderr); + } + const fileName = `v${version}.json`; + // tslint:disable-next-line:no-console + console.log(`POSTPUBLISH: Doc generation successful, uploading docs... as ${fileName}`); + const s3Url = S3BucketPath + fileName; + return execAsync(`S3_URL=${s3Url} yarn upload_docs_json`, { + cwd, + }); +})().catch(console.error); diff --git a/packages/0x.js/monorepo_scripts/stagedocs.ts b/packages/0x.js/monorepo_scripts/stagedocs.ts new file mode 100644 index 000000000..a62d8a014 --- /dev/null +++ b/packages/0x.js/monorepo_scripts/stagedocs.ts @@ -0,0 +1,30 @@ +import { postpublishUtils } from '@0xproject/dev-utils'; +import { execAsync } from 'async-child-process'; +import * as _ from 'lodash'; + +import * as tsConfig from '../tsconfig.json'; + +const cwd = __dirname + '/..'; +const S3BucketPath = 's3://staging-0xjs-docs-jsons/'; +// Include any external packages that are part of the 0x.js public interface +// to this array so that TypeDoc picks it up and adds it to the Docs JSON +// So far, we only have @0xproject/types as part of 0x.js's public interface. +const fileIncludes = [...(tsConfig as any).include, '../types/src/index.ts']; +const fileIncludesAdjusted = postpublishUtils.adjustFileIncludePaths(fileIncludes, __dirname); +const projectFiles = fileIncludesAdjusted.join(' '); +const jsonFilePath = `${__dirname}/../${postpublishUtils.generatedDocsDirectoryName}/index.json`; +const version = process.env.DOCS_VERSION; + +(async () => { + const result = await execAsync(`JSON_FILE_PATH=${jsonFilePath} PROJECT_FILES="${projectFiles}" yarn docs:json`, { + cwd, + }); + if (!_.isEmpty(result.stderr)) { + throw new Error(result.stderr); + } + const fileName = `v${version}.json`; + const s3Url = S3BucketPath + fileName; + return execAsync(`S3_URL=${s3Url} yarn upload_docs_json`, { + cwd, + }); +})().catch(console.error); diff --git a/packages/0x.js/package.json b/packages/0x.js/package.json index 53ddfd258..54f9ba1ad 100644 --- a/packages/0x.js/package.json +++ b/packages/0x.js/package.json @@ -14,7 +14,7 @@ "scripts": { "build:watch": "tsc -w", "prebuild": "run-s clean generate_contract_wrappers", - "build": "run-p build:umd:prod build:commonjs; exit 0;", + "build": "run-p build:scripts build:umd:prod build:commonjs; exit 0;", "docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --json $JSON_FILE_PATH $PROJECT_FILES", "upload_docs_json": "aws s3 cp generated_docs/index.json $S3_URL --profile 0xproject --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --content-type application/json", "generate_contract_wrappers": "node ../abi-gen/lib/index.js --abis 'src/artifacts/@(Exchange|Token|TokenTransferProxy|EtherToken|TokenRegistry|DummyToken).json' --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/contract_wrappers/generated --backend ethers && prettier --write 'src/contract_wrappers/generated/**.ts'", @@ -27,6 +27,7 @@ "clean": "shx rm -rf _bundles lib test_temp", "build:umd:prod": "NODE_ENV=production webpack", "build:commonjs": "tsc && copyfiles -u 2 './src/artifacts/**/*.json' ./lib/src/artifacts;", + "build:scripts": "tsc --p ./tsconfig_monorepo.json", "test:commonjs": "run-s build:commonjs run_mocha", "run_mocha": "mocha lib/test/**/*_test.js --timeout 10000 --bail --exit" }, diff --git a/packages/0x.js/tsconfig_monorepo.json b/packages/0x.js/tsconfig_monorepo.json new file mode 100644 index 000000000..7e9609659 --- /dev/null +++ b/packages/0x.js/tsconfig_monorepo.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig", + "compilerOptions": { + "outDir": "scripts", + "noImplicitThis": false, + "rootDir": "./monorepo_scripts" + }, + "include": ["./monorepo_scripts/**/*", "../../node_modules/web3-typescript-typings/index.d.ts"] +} diff --git a/packages/dev-utils/CHANGELOG.md b/packages/dev-utils/CHANGELOG.md index ecc5546ae..6840a6a69 100644 --- a/packages/dev-utils/CHANGELOG.md +++ b/packages/dev-utils/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGELOG +## v0.2.1 - _TBD_ + + * Add postpublish utils + ## v0.2.0 - _February 16, 2018_ * Remove subproviders (#392) diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json index fbbcb182f..491ebd95f 100644 --- a/packages/dev-utils/package.json +++ b/packages/dev-utils/package.json @@ -43,7 +43,9 @@ "@0xproject/utils": "^0.4.1", "ethereumjs-util": "^5.1.2", "lodash": "^4.17.4", + "publish-release": "0xproject/publish-release", "request-promise-native": "^1.0.5", + "semver-sort": "^0.0.4", "web3": "^0.20.0", "web3-provider-engine": "^13.0.1" }, diff --git a/packages/dev-utils/src/globals.d.ts b/packages/dev-utils/src/globals.d.ts index 7b132ee28..9c8a1dc02 100644 --- a/packages/dev-utils/src/globals.d.ts +++ b/packages/dev-utils/src/globals.d.ts @@ -1,2 +1,9 @@ declare module 'web3-provider-engine'; declare module 'web3-provider-engine/subproviders/rpc'; +declare module 'async-child-process'; +declare module 'publish-release'; + +// semver-sort declarations +declare module 'semver-sort' { + const desc: (versions: string[]) => string[]; +} diff --git a/packages/dev-utils/src/index.ts b/packages/dev-utils/src/index.ts index e899ac206..cc3e668a1 100644 --- a/packages/dev-utils/src/index.ts +++ b/packages/dev-utils/src/index.ts @@ -2,3 +2,4 @@ export { RPC } from './rpc'; export { BlockchainLifecycle } from './blockchain_lifecycle'; export { web3Factory } from './web3_factory'; export { constants as devConstants } from './constants'; +export { postpublishUtils } from './postpublish_utils'; diff --git a/packages/dev-utils/src/postpublish_utils.ts b/packages/dev-utils/src/postpublish_utils.ts new file mode 100644 index 000000000..35d046e26 --- /dev/null +++ b/packages/dev-utils/src/postpublish_utils.ts @@ -0,0 +1,86 @@ +import { promisify } from '@0xproject/utils'; +import { execAsync } from 'async-child-process'; +import * as _ from 'lodash'; +import * as publishRelease from 'publish-release'; +import semverSort = require('semver-sort'); + +import { utils } from './utils'; + +const publishReleaseAsync = promisify(publishRelease); +const githubPersonalAccessToken = process.env.GITHUB_PERSONAL_ACCESS_TOKEN_0X_JS; +const generatedDocsDirectoryName = 'generated_docs'; + +export interface TagAndVersion { + tag: string; + version: string; +} + +export const postpublishUtils = { + getLatestTagAndVersionAsync(subPackageName: string): Promise { + const subPackagePrefix = `${subPackageName}@`; + const gitTagsCommand = `git tag -l "${subPackagePrefix}*"`; + return execAsync(gitTagsCommand).then((result: any) => { + if (!_.isEmpty(result.stderr)) { + throw new Error(result.stderr); + } + const tags = result.stdout.trim().split('\n'); + const versions = tags.map((tag: string) => { + return tag.slice(subPackagePrefix.length); + }); + const sortedVersions = semverSort.desc(versions); + const latestVersion = sortedVersions[0]; + const latestTag = subPackagePrefix + latestVersion; + return { + tag: latestTag, + version: latestVersion, + }; + }); + }, + publishReleaseNotesAsync(tag: string, releaseName: string, assets: string[]) { + utils.log('POSTPUBLISH: Releasing ', releaseName, '...'); + return publishReleaseAsync({ + token: githubPersonalAccessToken, + owner: '0xProject', + repo: '0x.js', + tag, + name: releaseName, + notes: 'N/A', + draft: false, + prerelease: false, + reuseRelease: true, + reuseDraftOnly: false, + assets, + }); + }, + getReleaseName(subPackageName: string, version: string): string { + const releaseName = `${subPackageName} v${version}`; + return releaseName; + }, + async standardPostPublishAsync(subPackageName: string): Promise { + const result: TagAndVersion = await this.getLatestTagAndVersionAsync(subPackageName); + const releaseName = this.getReleaseName(subPackageName, result.version); + const assets: string[] = []; + await this.publishReleaseNotesAsync(result.tag, releaseName, assets); + }, + adjustFileIncludePaths(fileIncludes: string[], cwd: string): string[] { + const fileIncludesAdjusted = _.map(fileIncludes, fileInclude => { + let path; + if (_.startsWith(fileInclude, '../')) { + path = `${cwd}/../${fileInclude}`; + } else if (_.startsWith(fileInclude, './')) { + path = `${cwd}/../${fileInclude.substr(2)}`; + } else { + path = `${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); + } + return path; + }); + return fileIncludesAdjusted; + }, + generatedDocsDirectoryName, +}; diff --git a/packages/dev-utils/src/utils.ts b/packages/dev-utils/src/utils.ts new file mode 100644 index 000000000..5423cabd9 --- /dev/null +++ b/packages/dev-utils/src/utils.ts @@ -0,0 +1,5 @@ +export const utils = { + log(...args: any[]): void { + console.log(...args); // tslint:disable-line:no-console + }, +}; -- cgit v1.2.3