From 9f42ceb5a3962c3e9e251da8791182e561139b08 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Wed, 8 Aug 2018 09:47:06 -0400 Subject: Split publish_utils since it was becoming too big and unwieldy --- .../src/utils/github_release_utils.ts | 102 +++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 packages/monorepo-scripts/src/utils/github_release_utils.ts (limited to 'packages/monorepo-scripts/src/utils/github_release_utils.ts') diff --git a/packages/monorepo-scripts/src/utils/github_release_utils.ts b/packages/monorepo-scripts/src/utils/github_release_utils.ts new file mode 100644 index 000000000..1f4c4f1e9 --- /dev/null +++ b/packages/monorepo-scripts/src/utils/github_release_utils.ts @@ -0,0 +1,102 @@ +import * as _ from 'lodash'; +import * as promisify from 'es6-promisify'; +import * as publishRelease from 'publish-release'; + +import { constants } from '../constants'; +import { Package } from '../types'; +import { utils } from './utils'; + +import { readFileSync } from 'fs'; +import * as path from 'path'; +import { exec as execAsync } from 'promisify-child-process'; + +const publishReleaseAsync = promisify(publishRelease); +export async function publishReleaseNotesAsync(updatedPublishPackages: Package[]): Promise { + // Git push a tag representing this publish (publish-{commit-hash}) (truncate hash) + const result = await execAsync('git log -n 1 --pretty=format:"%H"', { cwd: constants.monorepoRootPath }); + const latestGitCommit = result.stdout; + const shortenedGitCommit = latestGitCommit.slice(0, 7); + const tagName = `monorepo@${shortenedGitCommit}`; + + await execAsync(`git rev-parse ${tagName}`); + await execAsync('git tag ${tagName}'); + + await execAsync('git push origin ${tagName}'); + const releaseName = `0x monorepo - ${shortenedGitCommit}`; + + let assets: string[] = []; + let aggregateNotes = ''; + _.each(updatedPublishPackages, pkg => { + const notes = getReleaseNotesForPackage(pkg.packageJson.name, pkg.packageJson.version); + if (_.isEmpty(notes)) { + return; // don't include it + } + aggregateNotes += `### ${pkg.packageJson.name}@${pkg.packageJson.version}\n${notes}\n\n`; + + const packageAssets = _.get(pkg.packageJson, 'config.postpublish.assets'); + if (!_.isUndefined(packageAssets)) { + assets = [...assets, ...packageAssets]; + } + }); + const finalAssets = adjustAssetPaths(assets); + + utils.log('Publishing release notes ', releaseName, '...'); + // TODO: Currently publish-release doesn't let you specify the labels for each asset uploaded + // Ideally we would like to name the assets after the package they are from + // Source: https://github.com/remixz/publish-release/issues/39 + await publishReleaseAsync({ + token: constants.githubPersonalAccessToken, + owner: '0xProject', + tag: tagName, + repo: '0x-monorepo', + name: releaseName, + notes: aggregateNotes, + draft: false, + prerelease: false, + reuseRelease: true, + reuseDraftOnly: false, + assets: finalAssets, + }); +} + +// Asset paths should described from the monorepo root. This method prefixes +// the supplied path with the absolute path to the monorepo root. +function adjustAssetPaths(assets: string[]): string[] { + const finalAssets: string[] = []; + _.each(assets, (asset: string) => { + const finalAsset = `${constants.monorepoRootPath}/${asset}`; + finalAssets.push(finalAsset); + }); + return finalAssets; +} + +function getReleaseNotesForPackage(packageName: string, version: string): string { + const packageNameWithoutNamespace = packageName.replace('@0xproject/', ''); + const changelogJSONPath = path.join( + constants.monorepoRootPath, + 'packages', + packageNameWithoutNamespace, + 'CHANGELOG.json', + ); + const changelogJSON = readFileSync(changelogJSONPath, 'utf-8'); + const changelogs = JSON.parse(changelogJSON); + const latestLog = changelogs[0]; + // If only has a `Dependencies updated` changelog, we don't include it in release notes + if (latestLog.changes.length === 1 && latestLog.changes[0].note === constants.dependenciesUpdatedMessage) { + return ''; + } + // We sanity check that the version for the changelog notes we are about to publish to Github + // correspond to the new version of the package. + // if (version !== latestLog.version) { + // throw new Error('Expected CHANGELOG.json latest entry version to coincide with published version.'); + // } + let notes = ''; + _.each(latestLog.changes, change => { + notes += `* ${change.note}`; + if (change.pr) { + notes += ` (#${change.pr})`; + } + notes += `\n`; + }); + return notes; +} -- cgit v1.2.3 From b7c119b2aaaa2f3579ca4aeef198eca7f38f1216 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Wed, 22 Aug 2018 18:52:17 +0100 Subject: Fix many linter errors that showed up upon upgrading tsutil --- .../monorepo-scripts/src/utils/github_release_utils.ts | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'packages/monorepo-scripts/src/utils/github_release_utils.ts') diff --git a/packages/monorepo-scripts/src/utils/github_release_utils.ts b/packages/monorepo-scripts/src/utils/github_release_utils.ts index 1f4c4f1e9..28dce70ac 100644 --- a/packages/monorepo-scripts/src/utils/github_release_utils.ts +++ b/packages/monorepo-scripts/src/utils/github_release_utils.ts @@ -1,27 +1,29 @@ -import * as _ from 'lodash'; import * as promisify from 'es6-promisify'; +import { readFileSync } from 'fs'; +import * as _ from 'lodash'; +import * as path from 'path'; +import { exec as execAsync } from 'promisify-child-process'; import * as publishRelease from 'publish-release'; import { constants } from '../constants'; import { Package } from '../types'; -import { utils } from './utils'; -import { readFileSync } from 'fs'; -import * as path from 'path'; -import { exec as execAsync } from 'promisify-child-process'; +import { utils } from './utils'; const publishReleaseAsync = promisify(publishRelease); +// tslint:disable-next-line:completed-docs export async function publishReleaseNotesAsync(updatedPublishPackages: Package[]): Promise { // Git push a tag representing this publish (publish-{commit-hash}) (truncate hash) const result = await execAsync('git log -n 1 --pretty=format:"%H"', { cwd: constants.monorepoRootPath }); const latestGitCommit = result.stdout; - const shortenedGitCommit = latestGitCommit.slice(0, 7); + const prefixLength = 7; + const shortenedGitCommit = latestGitCommit.slice(0, prefixLength); const tagName = `monorepo@${shortenedGitCommit}`; await execAsync(`git rev-parse ${tagName}`); - await execAsync('git tag ${tagName}'); + await execAsync(`git tag ${tagName}`); - await execAsync('git push origin ${tagName}'); + await execAsync(`git push origin ${tagName}`); const releaseName = `0x monorepo - ${shortenedGitCommit}`; let assets: string[] = []; -- cgit v1.2.3 From 2b38163274de9621160d54a8d809284c0b353cc4 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 23 Aug 2018 13:56:40 +0100 Subject: Enable dry run of release publishing and handle git tags existing --- .../src/utils/github_release_utils.ts | 40 ++++++++++++++++------ 1 file changed, 30 insertions(+), 10 deletions(-) (limited to 'packages/monorepo-scripts/src/utils/github_release_utils.ts') diff --git a/packages/monorepo-scripts/src/utils/github_release_utils.ts b/packages/monorepo-scripts/src/utils/github_release_utils.ts index 28dce70ac..43d0d9fc3 100644 --- a/packages/monorepo-scripts/src/utils/github_release_utils.ts +++ b/packages/monorepo-scripts/src/utils/github_release_utils.ts @@ -12,7 +12,7 @@ import { utils } from './utils'; const publishReleaseAsync = promisify(publishRelease); // tslint:disable-next-line:completed-docs -export async function publishReleaseNotesAsync(updatedPublishPackages: Package[]): Promise { +export async function publishReleaseNotesAsync(updatedPublishPackages: Package[], isDryRun: boolean): Promise { // Git push a tag representing this publish (publish-{commit-hash}) (truncate hash) const result = await execAsync('git log -n 1 --pretty=format:"%H"', { cwd: constants.monorepoRootPath }); const latestGitCommit = result.stdout; @@ -20,10 +20,22 @@ export async function publishReleaseNotesAsync(updatedPublishPackages: Package[] const shortenedGitCommit = latestGitCommit.slice(0, prefixLength); const tagName = `monorepo@${shortenedGitCommit}`; - await execAsync(`git rev-parse ${tagName}`); - await execAsync(`git tag ${tagName}`); + if (!isDryRun) { + try { + await execAsync(`git tag ${tagName}`); + } catch (err) { + if (_.includes(err.message, 'already exists')) { + // Noop tag creation since already exists + } else { + throw err; + } + } + const {stdout} = await execAsync(`git ls-remote --tags origin refs/tags/${tagName}`); + if (_.isEmpty(stdout)) { + await execAsync(`git push origin ${tagName}`); + } + } - await execAsync(`git push origin ${tagName}`); const releaseName = `0x monorepo - ${shortenedGitCommit}`; let assets: string[] = []; @@ -42,11 +54,7 @@ export async function publishReleaseNotesAsync(updatedPublishPackages: Package[] }); const finalAssets = adjustAssetPaths(assets); - utils.log('Publishing release notes ', releaseName, '...'); - // TODO: Currently publish-release doesn't let you specify the labels for each asset uploaded - // Ideally we would like to name the assets after the package they are from - // Source: https://github.com/remixz/publish-release/issues/39 - await publishReleaseAsync({ + const publishReleaseConfigs = { token: constants.githubPersonalAccessToken, owner: '0xProject', tag: tagName, @@ -58,7 +66,19 @@ export async function publishReleaseNotesAsync(updatedPublishPackages: Package[] reuseRelease: true, reuseDraftOnly: false, assets: finalAssets, - }); + }; + + if (isDryRun) { + utils.log(`Dry run: stopping short of publishing release notes to github`); + utils.log(`Would publish with configs:\n${JSON.stringify(publishReleaseConfigs, null, '\t')}`); + return; + } + + utils.log('Publishing release notes ', releaseName, '...'); + // TODO: Currently publish-release doesn't let you specify the labels for each asset uploaded + // Ideally we would like to name the assets after the package they are from + // Source: https://github.com/remixz/publish-release/issues/39 + await publishReleaseAsync(publishReleaseConfigs); } // Asset paths should described from the monorepo root. This method prefixes -- cgit v1.2.3 From 15a34dca790dc2ef25b302c2b2d50524865d2954 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 23 Aug 2018 13:58:49 +0100 Subject: Fix prettier issues --- packages/monorepo-scripts/src/utils/github_release_utils.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'packages/monorepo-scripts/src/utils/github_release_utils.ts') diff --git a/packages/monorepo-scripts/src/utils/github_release_utils.ts b/packages/monorepo-scripts/src/utils/github_release_utils.ts index 43d0d9fc3..9b5b26d7e 100644 --- a/packages/monorepo-scripts/src/utils/github_release_utils.ts +++ b/packages/monorepo-scripts/src/utils/github_release_utils.ts @@ -24,13 +24,13 @@ export async function publishReleaseNotesAsync(updatedPublishPackages: Package[] try { await execAsync(`git tag ${tagName}`); } catch (err) { - if (_.includes(err.message, 'already exists')) { + if (_.includes(err.message, 'already exists')) { // Noop tag creation since already exists } else { throw err; } } - const {stdout} = await execAsync(`git ls-remote --tags origin refs/tags/${tagName}`); + const { stdout } = await execAsync(`git ls-remote --tags origin refs/tags/${tagName}`); if (_.isEmpty(stdout)) { await execAsync(`git push origin ${tagName}`); } -- cgit v1.2.3 From 610caef73faf735a9b9f38863acee007280151be Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 23 Aug 2018 15:08:02 +0100 Subject: Fix comments --- packages/monorepo-scripts/src/utils/github_release_utils.ts | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'packages/monorepo-scripts/src/utils/github_release_utils.ts') diff --git a/packages/monorepo-scripts/src/utils/github_release_utils.ts b/packages/monorepo-scripts/src/utils/github_release_utils.ts index 9b5b26d7e..0f3485de0 100644 --- a/packages/monorepo-scripts/src/utils/github_release_utils.ts +++ b/packages/monorepo-scripts/src/utils/github_release_utils.ts @@ -65,6 +65,9 @@ export async function publishReleaseNotesAsync(updatedPublishPackages: Package[] prerelease: false, reuseRelease: true, reuseDraftOnly: false, + // TODO: Currently publish-release doesn't let you specify the labels for each asset uploaded + // Ideally we would like to name the assets after the package they are from + // Source: https://github.com/remixz/publish-release/issues/39 assets: finalAssets, }; @@ -75,9 +78,6 @@ export async function publishReleaseNotesAsync(updatedPublishPackages: Package[] } utils.log('Publishing release notes ', releaseName, '...'); - // TODO: Currently publish-release doesn't let you specify the labels for each asset uploaded - // Ideally we would like to name the assets after the package they are from - // Source: https://github.com/remixz/publish-release/issues/39 await publishReleaseAsync(publishReleaseConfigs); } @@ -107,11 +107,6 @@ function getReleaseNotesForPackage(packageName: string, version: string): string if (latestLog.changes.length === 1 && latestLog.changes[0].note === constants.dependenciesUpdatedMessage) { return ''; } - // We sanity check that the version for the changelog notes we are about to publish to Github - // correspond to the new version of the package. - // if (version !== latestLog.version) { - // throw new Error('Expected CHANGELOG.json latest entry version to coincide with published version.'); - // } let notes = ''; _.each(latestLog.changes, change => { notes += `* ${change.note}`; -- cgit v1.2.3