Merge branch 'development' into feature/bignumber-8.0

This commit is contained in:
Leonid Logvinov
2019-01-18 12:53:04 +01:00
committed by GitHub
115 changed files with 1268 additions and 471 deletions

View File

@@ -1,7 +1,7 @@
{
"private": true,
"name": "@0x/monorepo-scripts",
"version": "1.0.18",
"version": "1.0.19",
"engines": {
"node": ">=6.12"
},

View File

@@ -6,6 +6,8 @@ import semverSort = require('semver-sort');
import { constants } from './constants';
import { Package } from './types';
import { changelogUtils } from './utils/changelog_utils';
import { configs } from './utils/configs';
import { dockerHubUtils } from './utils/docker_hub_utils';
import { npmUtils } from './utils/npm_utils';
import { utils } from './utils/utils';
@@ -17,6 +19,12 @@ async function prepublishChecksAsync(): Promise<void> {
await checkChangelogFormatAsync(updatedPublicPackages);
await checkGitTagsForNextVersionAndDeleteIfExistAsync(updatedPublicPackages);
await checkPublishRequiredSetupAsync();
await checkDockerHubSetupAsync();
}
async function checkDockerHubSetupAsync(): Promise<void> {
await dockerHubUtils.checkUserAddedToOrganizationOrThrowAsync(configs.DOCKER_HUB_ORG);
await dockerHubUtils.loginUserToDockerCommandlineOrThrowAsync();
}
async function checkGitTagsForNextVersionAndDeleteIfExistAsync(updatedPublicPackages: Package[]): Promise<void> {

View File

@@ -1,11 +1,12 @@
#!/usr/bin/env node
import { logUtils } from '@0x/utils';
import * as promisify from 'es6-promisify';
import * as fs from 'fs';
import * as _ from 'lodash';
import * as moment from 'moment';
import opn = require('opn');
import { exec as execAsync } from 'promisify-child-process';
import { exec as execAsync, spawn as spawnAsync } from 'promisify-child-process';
import * as prompt from 'prompt';
import semver = require('semver');
import semverSort = require('semver-sort');
@@ -79,12 +80,16 @@ async function confirmAsync(message: string): Promise<void> {
});
utils.log(`Calling 'lerna publish'...`);
await lernaPublishAsync(packageToNextVersion);
if (!configs.IS_LOCAL_PUBLISH) {
const isDryRun = configs.IS_LOCAL_PUBLISH;
if (!isDryRun) {
// Publish docker images to DockerHub
await publishImagesToDockerHubAsync(allPackagesToPublish);
const isStaging = false;
const shouldUploadDocs = true;
await generateAndUploadDocJsonsAsync(packagesWithDocs, isStaging, shouldUploadDocs);
}
const isDryRun = configs.IS_LOCAL_PUBLISH;
const releaseNotes = await publishReleaseNotesAsync(updatedPublicPackages, isDryRun);
utils.log('Published release notes');
@@ -95,11 +100,45 @@ async function confirmAsync(message: string): Promise<void> {
utils.log("Publish successful, but couldn't auto-alert discord (", e.message, '), Please alert manually.');
}
}
process.exit(0);
})().catch(err => {
utils.log(err);
process.exit(1);
});
async function publishImagesToDockerHubAsync(allUpdatedPackages: Package[]): Promise<void> {
for (const pkg of allUpdatedPackages) {
const packageJSON = pkg.packageJson;
const shouldPublishDockerImage =
!_.isUndefined(packageJSON.config) &&
!_.isUndefined(packageJSON.config.postpublish) &&
!_.isUndefined(packageJSON.config.postpublish.dockerHubRepo);
if (!shouldPublishDockerImage) {
continue;
}
const dockerHubRepo = _.get(packageJSON, 'config.postpublish.dockerHubRepo');
const pkgName = pkg.packageJson.name;
const packageDirName = _.startsWith(pkgName, '@0x/') ? pkgName.split('/')[1] : pkgName;
// Build the Docker image
logUtils.log(`Building '${dockerHubRepo}' docker image...`);
await spawnAsync('docker', ['build', '-t', dockerHubRepo, '.'], {
cwd: `${constants.monorepoRootPath}/packages/${packageDirName}`,
});
// Tag the docker image with the latest version
const version = pkg.packageJson.version;
logUtils.log(`Tagging '${dockerHubRepo}' docker image with version ${version}...`);
await execAsync(`docker tag ${dockerHubRepo} ${configs.DOCKER_HUB_ORG}/${dockerHubRepo}:${version}`);
await execAsync(`docker tag ${dockerHubRepo} ${configs.DOCKER_HUB_ORG}/${dockerHubRepo}:latest`);
// Publish to DockerHub
logUtils.log(`Pushing '${dockerHubRepo}' docker image to DockerHub...`);
await execAsync(`docker push ${configs.DOCKER_HUB_ORG}/${dockerHubRepo}:${version}`);
await execAsync(`docker push ${configs.DOCKER_HUB_ORG}/${dockerHubRepo}:latest`);
}
}
function getPackagesWithDocs(allUpdatedPackages: Package[]): Package[] {
const rootPackageJsonPath = `${constants.monorepoRootPath}/package.json`;
const rootPackageJson = JSON.parse(fs.readFileSync(rootPackageJsonPath).toString());

View File

@@ -41,7 +41,11 @@ export interface PackageJSON {
main?: string;
scripts?: { [command: string]: string };
config?: {
additionalTsTypings?: string[];
postpublish?: {
assets?: string[];
docOmitExports?: string[];
dockerHubRepo?: string;
};
};
}

View File

@@ -5,4 +5,5 @@ const REMOTE_NPM_REGISTRY_URL = 'https://registry.npmjs.org';
export const configs = {
IS_LOCAL_PUBLISH,
NPM_REGISTRY_URL: IS_LOCAL_PUBLISH ? LOCAL_NPM_REGISTRY_URL : REMOTE_NPM_REGISTRY_URL,
DOCKER_HUB_ORG: '0xorg',
};

View File

@@ -0,0 +1,65 @@
import { fetchAsync } from '@0x/utils';
import { exec as execAsync } from 'promisify-child-process';
import { utils } from './utils';
const API_ENDPOINT = 'https://hub.docker.com/v2';
const HTTP_OK_STATUS = 200;
export const dockerHubUtils = {
async getTokenAsync(): Promise<string> {
const payload = {
username: process.env.DOCKER_USERNAME,
password: process.env.DOCKER_PASS,
};
const response = await fetchAsync(`${API_ENDPOINT}/users/login`, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(payload),
});
if (response.status !== HTTP_OK_STATUS) {
throw new Error(
`DockerHub user login failed (status code: ${
response.status
}). Make sure you have environment variables 'DOCKER_USERNAME; and 'DOCKER_PASS' set`,
);
}
const respPayload = await response.json();
const token = respPayload.token;
return token;
},
async checkUserAddedToOrganizationOrThrowAsync(organization: string): Promise<void> {
utils.log('Checking that the user was added to the 0xorg DockerHub organization...');
const token = await dockerHubUtils.getTokenAsync();
const response = await fetchAsync(`${API_ENDPOINT}/repositories/${organization}/?page_size=10`, {
method: 'GET',
headers: {
Accept: 'application/json',
Authorization: `JWT ${token}`,
},
});
const respPayload = await response.json();
if (response.status !== HTTP_OK_STATUS || respPayload.count === 0) {
throw new Error(
`Failed to fetch org: ${organization}'s list of repos (status code: ${
response.status
}). Make sure your account has been added to the '${organization}' org on DockerHub`,
);
}
},
async loginUserToDockerCommandlineOrThrowAsync(): Promise<void> {
try {
utils.log('Checking that the user is logged in to docker command...');
await execAsync(`echo "$DOCKER_PASS" | docker login -u $DOCKER_USERNAME --password-stdin`);
} catch (err) {
throw new Error(
`Failed to log you into the 'docker' commandline tool. Make sure you have the 'docker' commandline tool installed. Full error: ${
err.message
}`,
);
}
},
};

View File

@@ -106,8 +106,10 @@ export const utils = {
return nextVersionIfValid;
},
async getRemoteGitTagsAsync(): Promise<string[]> {
const TEN_MEGA_BYTES = 1024 * 1024 * 10; // tslint:disable-line custom-no-magic-numbers
const result = await execAsync(`git ls-remote --tags`, {
cwd: constants.monorepoRootPath,
maxBuffer: TEN_MEGA_BYTES,
});
const tagsString = result.stdout;
const tagOutputs: string[] = tagsString.split('\n');