diff options
Diffstat (limited to 'packages/monorepo-scripts/src')
-rw-r--r-- | packages/monorepo-scripts/src/postpublish_utils.ts | 141 |
1 files changed, 97 insertions, 44 deletions
diff --git a/packages/monorepo-scripts/src/postpublish_utils.ts b/packages/monorepo-scripts/src/postpublish_utils.ts index a36408ccd..55c44ca63 100644 --- a/packages/monorepo-scripts/src/postpublish_utils.ts +++ b/packages/monorepo-scripts/src/postpublish_utils.ts @@ -10,37 +10,95 @@ const publishReleaseAsync = promisify(publishRelease); const githubPersonalAccessToken = process.env.GITHUB_PERSONAL_ACCESS_TOKEN_0X_JS; const generatedDocsDirectoryName = 'generated_docs'; -export interface TagAndVersion { - tag: string; +export interface PostpublishConfigs { + cwd: string; + packageName: string; version: string; + assets: string[]; + docPublishConfigs: DocPublishConfigs; +} + +export interface DocPublishConfigs { + fileIncludes: string[]; + s3BucketPath: string; + s3StagingBucketPath: string; } export const postpublishUtils = { - async getLatestTagAndVersionAsync(subPackageName: string): Promise<TagAndVersion> { - const subPackagePrefix = `${subPackageName}@`; - const gitTagsCommand = `git tag -l "${subPackagePrefix}*"`; - const result = await execAsync(gitTagsCommand); - if (!_.isEmpty(result.stderr)) { - throw new Error(result.stderr); + generateConfig(packageJSON: any, tsConfigJSON: any, cwd: string): PostpublishConfigs { + if (_.isUndefined(packageJSON.name)) { + throw new Error('name field required in package.json. Cannot publish release notes to Github.'); } - 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, + if (_.isUndefined(packageJSON.version)) { + throw new Error('version field required in package.json. Cannot publish release notes to Github.'); + } + const postpublishConfig = _.get(packageJSON, 'config.postpublish', {}); + const configs: PostpublishConfigs = { + cwd, + packageName: packageJSON.name, + version: packageJSON.version, + assets: _.get(postpublishConfig, 'assets', []), + docPublishConfigs: { + // 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. + fileIncludes: [ + ...(tsConfigJSON as any).include, + ..._.get(postpublishConfig, 'docPublishConfigs.extraFileIncludes', []), + ], + s3BucketPath: _.get(postpublishConfig, 'docPublishConfigs.s3BucketPath'), + s3StagingBucketPath: _.get(postpublishConfig, 'docPublishConfigs.s3StagingBucketPath'), + }, }; + return configs; + }, + async runAsync(packageJSON: any, tsConfigJSON: any, cwd: string): Promise<void> { + const configs = this.generateConfig(packageJSON, tsConfigJSON, cwd); + const release = await this.publishReleaseNotesAsync( + configs.cwd, + configs.packageName, + configs.version, + configs.assets, + ); + if ( + !_.isUndefined(configs.docPublishConfigs.s3BucketPath) || + !_.isUndefined(configs.docPublishConfigs.s3StagingBucketPath) + ) { + utils.log('POSTPUBLISH: Release successful, generating docs...'); + await postpublishUtils.generateAndUploadDocsAsync( + configs.cwd, + configs.docPublishConfigs.fileIncludes, + configs.version, + configs.docPublishConfigs.s3BucketPath, + ); + } else { + utils.log(`POSTPUBLISH: No S3Bucket config found for ${packageJSON.name}. Skipping doc JSON generation.`); + } + }, + async publishDocsToStagingAsync(packageJSON: any, tsConfigJSON: any, cwd: string) { + const configs = this.generateConfig(packageJSON, tsConfigJSON, cwd); + if (_.isUndefined(configs.docPublishConfigs.s3StagingBucketPath)) { + utils.log('config.postpublish.docPublishConfigs.s3StagingBucketPath entry in package.json not found!'); + return; + } + + utils.log('POSTPUBLISH: Generating docs...'); + await postpublishUtils.generateAndUploadDocsAsync( + configs.cwd, + configs.docPublishConfigs.fileIncludes, + configs.version, + configs.docPublishConfigs.s3StagingBucketPath, + ); }, - async publishReleaseNotesAsync(tag: string, releaseName: string, assets: string[]) { + async publishReleaseNotesAsync(cwd: string, packageName: string, version: string, assets: string[]): Promise<void> { + const releaseName = this.getReleaseName(packageName, version); + const tag = this.getTag(packageName, version); utils.log('POSTPUBLISH: Releasing ', releaseName, '...'); - return publishReleaseAsync({ + const finalAssets = this.adjustAssetPaths(cwd, assets); + const result = await publishReleaseAsync({ token: githubPersonalAccessToken, owner: '0xProject', - repo: '0x.js', + repo: '0x-monorepo', tag, name: releaseName, notes: 'N/A', @@ -51,26 +109,23 @@ export const postpublishUtils = { assets, }); }, + getTag(packageName: string, version: string) { + return `${packageName}@${version}`; + }, getReleaseName(subPackageName: string, version: string): string { const releaseName = `${subPackageName} v${version}`; return releaseName; }, - async standardPostPublishAsync(subPackageName: string): Promise<void> { - const result: TagAndVersion = await this.getLatestTagAndVersionAsync(subPackageName); - const releaseName = this.getReleaseName(subPackageName, result.version); - const assets: string[] = []; - await this.publishReleaseNotesAsync(result.tag, releaseName, assets); + adjustAssetPaths(cwd: string, assets: string[]) { + const finalAssets: string[] = []; + _.each(assets, (asset: string) => { + finalAssets.push(`${cwd}/${asset}`); + }); + return finalAssets; }, 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}`; - } + let path = _.startsWith(fileInclude, './') ? `${cwd}/${fileInclude.substr(2)}` : `${cwd}/${fileInclude}`; // HACK: tsconfig.json needs wildcard directory endings as `/**/*` // but TypeDoc needs it as `/**` in order to pick up files at the root @@ -81,15 +136,10 @@ export const postpublishUtils = { }); return fileIncludesAdjusted; }, - async generateAndUploadDocsAsync( - dirname: string, - cwd: string, - includedFiles: string[], - version: string, - S3BucketPath: string, - ) { - const jsonFilePath = `${dirname}/../${postpublishUtils.generatedDocsDirectoryName}/index.json`; - const projectFiles = includedFiles.join(' '); + async generateAndUploadDocsAsync(cwd: string, fileIncludes: string[], version: string, S3BucketPath: string) { + const fileIncludesAdjusted = this.adjustFileIncludePaths(fileIncludes, cwd); + const projectFiles = fileIncludesAdjusted.join(' '); + const jsonFilePath = `${cwd}/${generatedDocsDirectoryName}/index.json`; const result = await execAsync( `JSON_FILE_PATH=${jsonFilePath} PROJECT_FILES="${projectFiles}" yarn docs:json`, { @@ -105,7 +155,10 @@ export const postpublishUtils = { await execAsync(`S3_URL=${s3Url} yarn upload_docs_json`, { cwd, }); + // Remove the generated docs directory + await execAsync(`rm -rf ${generatedDocsDirectoryName}`, { + cwd, + }); utils.log(`POSTPUBLISH: Docs uploaded to S3 bucket: ${S3BucketPath}`); }, - generatedDocsDirectoryName, }; |