Files
vercel/packages/now-cli/src/util/deploy/process-deployment.ts
Nathan Rajlich 8a68211cad [all] Rename packages to vercel and add logic to publish legacy package names to npm (#4233)
https://vercel.com/blog/zeit-is-now-vercel

* Updates all org packages from `@now` to `@vercel`
* Updates Now CLI package name from `now` to `vercel`
  * Packages contains `"bin"` entries for _both_ `vercel` and `now` in the package.json
* Updates `now-client` package name to `@vercel/client` (org scoped, for authenticity)

There is also a new `publish-legacy.sh` script which ensures that all the legacy package names (i.e. `now`, `now-client`, `@now/node`, etc.) will still be published as well.

We will remove this legacy publishing logic on Jan 1, 2021.
2020-05-05 23:43:57 +00:00

290 lines
6.3 KiB
TypeScript

import bytes from 'bytes';
import Progress from 'progress';
import chalk from 'chalk';
import {
createDeployment,
DeploymentOptions,
NowClientOptions,
} from '@vercel/client';
import { Output } from '../output';
// @ts-ignore
import Now from '../../util';
import { NowConfig } from '../dev/types';
import { Org } from '../../types';
import ua from '../ua';
import processLegacyDeployment from './process-legacy-deployment';
import { linkFolderToProject } from '../projects/link';
import { prependEmoji, emoji } from '../emoji';
function printInspectUrl(
output: Output,
deploymentUrl: string,
deployStamp: () => string,
orgSlug: string
) {
const url = deploymentUrl.replace('https://', '');
// example urls:
// lucim-fyulaijvg.now.sh
// s-66p6vb23x.n8.io (custom domain suffix)
const [sub, ...p] = url.split('.');
const apex = p.join('.');
const q = sub.split('-');
const deploymentShortId = q.pop();
const projectName = q.join('-');
const inspectUrl = `https://vercel.com/${orgSlug}/${projectName}/${deploymentShortId}${
apex !== 'now.sh' ? `/${apex}` : ''
}`;
output.print(
prependEmoji(
`Inspect: ${chalk.bold(inspectUrl)} ${deployStamp()}`,
emoji('inspect')
) + `\n`
);
}
export default async function processDeployment({
isLegacy,
org,
cwd,
projectName,
isSettingUpProject,
skipAutoDetectionConfirmation,
...args
}: {
now: Now;
output: Output;
hashes: { [key: string]: any };
paths: string[];
requestBody: DeploymentOptions;
uploadStamp: () => string;
deployStamp: () => string;
isLegacy: boolean;
quiet: boolean;
nowConfig?: NowConfig;
force?: boolean;
withCache?: boolean;
org: Org;
projectName: string;
isSettingUpProject: boolean;
skipAutoDetectionConfirmation?: boolean;
cwd?: string;
}) {
if (isLegacy) return processLegacyDeployment(args);
let {
now,
output,
hashes,
paths,
requestBody,
deployStamp,
force,
withCache,
nowConfig,
quiet,
} = args;
const { debug } = output;
let bar: Progress | null = null;
const { env = {} } = requestBody;
const nowClientOptions: NowClientOptions = {
teamId: org.type === 'team' ? org.id : undefined,
apiUrl: now._apiUrl,
token: now._token,
debug: now._debug,
userAgent: ua,
path: paths[0],
force,
withCache,
skipAutoDetectionConfirmation,
};
let queuedSpinner = null;
let buildSpinner = null;
let deploySpinner = null;
let deployingSpinner = output.spinner(
isSettingUpProject
? 'Setting up project'
: `Deploying ${chalk.bold(`${org.slug}/${projectName}`)}`,
0
);
// collect indications to show the user once
// the deployment is done
const indications = [];
for await (const event of createDeployment(
nowClientOptions,
requestBody,
nowConfig
)) {
if (event.type === 'hashes-calculated') {
hashes = event.payload;
}
if (['tip', 'notice', 'warning'].includes(event.type)) {
indications.push(event);
}
if (event.type === 'file-count') {
debug(
`Total files ${event.payload.total.size}, ${event.payload.missing.length} changed`
);
const missingSize = event.payload.missing
.map((sha: string) => event.payload.total.get(sha).data.length)
.reduce((a: number, b: number) => a + b, 0);
if (queuedSpinner) {
queuedSpinner();
}
if (buildSpinner) {
buildSpinner();
}
if (deploySpinner) {
deploySpinner();
}
if (deployingSpinner) {
deployingSpinner();
}
bar = new Progress(`${chalk.gray('>')} Upload [:bar] :percent :etas`, {
width: 20,
complete: '=',
incomplete: '',
total: missingSize,
clear: true,
});
}
if (event.type === 'file-uploaded') {
debug(
`Uploaded: ${event.payload.file.names.join(' ')} (${bytes(
event.payload.file.data.length
)})`
);
if (bar) {
bar.tick(event.payload.file.data.length);
}
}
if (event.type === 'created') {
if (deployingSpinner) {
deployingSpinner();
}
now._host = event.payload.url;
await linkFolderToProject(
output,
cwd || paths[0],
{
orgId: org.id,
projectId: event.payload.projectId,
},
projectName,
org.slug
);
now.url = event.payload.url;
printInspectUrl(output, event.payload.url, deployStamp, org.slug);
if (quiet) {
process.stdout.write(`https://${event.payload.url}`);
}
if (queuedSpinner === null) {
queuedSpinner =
event.payload.readyState === 'QUEUED'
? output.spinner('Queued', 0)
: output.spinner('Building', 0);
}
}
if (event.type === 'building') {
if (queuedSpinner) {
queuedSpinner();
}
if (buildSpinner === null) {
buildSpinner = output.spinner('Building', 0);
}
}
if (event.type === 'canceled') {
if (queuedSpinner) {
queuedSpinner();
}
if (buildSpinner) {
buildSpinner();
}
return event.payload;
}
if (event.type === 'ready') {
if (queuedSpinner) {
queuedSpinner();
}
if (buildSpinner) {
buildSpinner();
}
deploySpinner = output.spinner('Completing', 0);
}
// Handle error events
if (event.type === 'error') {
if (queuedSpinner) {
queuedSpinner();
}
if (buildSpinner) {
buildSpinner();
}
if (deploySpinner) {
deploySpinner();
}
if (deployingSpinner) {
deployingSpinner();
}
const error = await now.handleDeploymentError(event.payload, {
hashes,
env,
});
if (error.code === 'missing_project_settings') {
return error;
}
throw error;
}
// Handle alias-assigned event
if (event.type === 'alias-assigned') {
if (queuedSpinner) {
queuedSpinner();
}
if (buildSpinner) {
buildSpinner();
}
if (deploySpinner) {
deploySpinner();
}
if (deployingSpinner) {
deployingSpinner();
}
event.payload.indications = indications;
return event.payload;
}
}
}