[all] Check for VERCEL_ environment variables with getPlatformEnv() (#4274)

Added the following env vars, most are undocumented but its good to be consistent:

- `VERCEL_REGION`
- `VERCEL_DEBUG`
- `VERCEL_BUILDER_DEBUG`
- `VERCEL_TOKEN`
- `__VERCEL_SKIP_DEV_CMD`

I also updated the error code prefixes to remove `NOW_`.
There `code` isn't used anywhere, this is just to make it unique and a little shorter.
This commit is contained in:
Steven
2020-05-06 18:13:12 -04:00
committed by GitHub
parent 639a9b03d2
commit ba25004ea8
25 changed files with 85 additions and 77 deletions

View File

@@ -1,5 +1,7 @@
import { getPlatformEnv } from './';
export default function debug(message: string, ...additional: any[]) {
if (process.env.NOW_BUILDER_DEBUG) {
if (getPlatformEnv('BUILDER_DEBUG')) {
console.log(message, ...additional);
}
}

View File

@@ -23,7 +23,7 @@ interface Props {
message: string;
/**
* A unique error code for this particular error.
* Should start with the builder name such as `NOW_NODE_`.
* Should start with the builder name such as `NODE_`.
*/
code: string;
/**

View File

@@ -54,7 +54,7 @@ export async function getSupportedNodeVersion(
engineRange +
'".';
throw new NowBuildError({
code: 'NOW_BUILD_UTILS_NODE_VERSION_INVALID',
code: 'BUILD_UTILS_NODE_VERSION_INVALID',
link:
'https://vercel.com/docs/runtimes#official-runtimes/node-js/node-js-version',
message: intro + '\n' + pleaseSet,
@@ -72,7 +72,7 @@ export async function getSupportedNodeVersion(
engineRange +
'".';
throw new NowBuildError({
code: 'NOW_BUILD_UTILS_NODE_VERSION_DISCONTINUED',
code: 'BUILD_UTILS_NODE_VERSION_DISCONTINUED',
link:
'https://vercel.com/docs/runtimes#official-runtimes/node-js/node-js-version',
message: intro + '\n' + pleaseSet + '\n' + upstreamProvider,

View File

@@ -39,7 +39,7 @@ export function spawnAsync(
: 'Command';
reject(
new NowBuildError({
code: `NOW_BUILD_UTILS_SPAWN_${code || signal}`,
code: `BUILD_UTILS_SPAWN_${code || signal}`,
message:
opts.stdio === 'inherit'
? `${cmd} exited with ${code || signal}`
@@ -81,7 +81,7 @@ export function execAsync(
return reject(
new NowBuildError({
code: `NOW_BUILD_UTILS_EXEC_${code || signal}`,
code: `BUILD_UTILS_EXEC_${code || signal}`,
message: `${cmd} exited with ${code || signal}`,
})
);

View File

@@ -91,3 +91,10 @@ export const isOfficialRuntime = (desired: string, name?: string): boolean => {
name.startsWith(`@now/${desired}`))
);
};
/**
* Helper function to support both `VERCEL_` and legacy `NOW_` env vars.
*/
export const getPlatformEnv = (name: string): string | undefined => {
return process.env[`VERCEL_${name}`] || process.env[`NOW_${name}`];
};

View File

@@ -43,7 +43,7 @@ export default async function dev(
return link.exitCode;
}
if (link.status === 'not_linked' && !process.env.__NOW_SKIP_DEV_COMMAND) {
if (link.status === 'not_linked' && !process.env.__VERCEL_SKIP_DEV_CMD) {
output.error(
`Your codebase isnt linked to a project on Vercel. Run ${getCommandName()} to link it.`
);

View File

@@ -76,6 +76,7 @@ async function createBuildProcess(
PATH,
...envConfigs.allEnv,
NOW_REGION: 'dev1',
VERCEL_REGION: 'dev1',
};
const buildProcess = fork(modulePath, [], {
@@ -379,6 +380,7 @@ export async function executeBuild(
...asset.environment,
...envConfigs.runEnv,
NOW_REGION: 'dev1',
VERCEL_REGION: 'dev1',
},
},
});

View File

@@ -1696,6 +1696,7 @@ export default class DevServer {
...process.env,
...this.envConfigs.allEnv,
NOW_REGION: 'dev1',
VERCEL_REGION: 'dev1',
PORT: `${port}`,
};

View File

@@ -1,6 +1,7 @@
import crypto from 'crypto';
import ua from 'universal-analytics';
import { platform, release, userInfo } from 'os';
import { getPlatformEnv } from '@vercel/build-utils';
import userAgent from './ua-browser';
import { GA_TRACKING_ID } from './constants';
@@ -10,7 +11,7 @@ const config: any = configFiles.getConfigFilePath();
export const shouldCollectMetrics =
(config.collectMetrics === undefined || config.collectMetrics === true) &&
process.env.NOW_CLI_COLLECT_METRICS !== '0' &&
getPlatformEnv('CLI_COLLECT_METRICS') !== '0' &&
GA_TRACKING_ID;
export const metrics = (): ua.Visitor => {

View File

@@ -14,6 +14,7 @@ import chalk from 'chalk';
import { prependEmoji, emoji } from '../emoji';
import AJV from 'ajv';
import { isDirectory } from '../config/global-path';
import { getPlatformEnv } from '@vercel/build-utils';
const readFile = promisify(fs.readFile);
const writeFile = promisify(fs.writeFile);
@@ -104,7 +105,8 @@ export async function getLinkedProject(
| { status: 'not_linked'; org: null; project: null }
| { status: 'error'; exitCode: number }
> {
const { VERCEL_ORG_ID, VERCEL_PROJECT_ID } = getFlags();
const VERCEL_ORG_ID = getPlatformEnv('ORG_ID');
const VERCEL_PROJECT_ID = getPlatformEnv('PROJECT_ID');
const shouldUseEnv = Boolean(VERCEL_ORG_ID && VERCEL_PROJECT_ID);
if ((VERCEL_ORG_ID || VERCEL_PROJECT_ID) && !shouldUseEnv) {
@@ -163,20 +165,6 @@ export async function getLinkedProject(
return { status: 'linked', org, project };
}
export function getFlags() {
let {
VERCEL_ORG_ID,
VERCEL_PROJECT_ID,
NOW_ORG_ID,
NOW_PROJECT_ID,
} = process.env;
// Fallback to old NOW env vars if available
VERCEL_ORG_ID = VERCEL_ORG_ID || NOW_ORG_ID;
VERCEL_PROJECT_ID = VERCEL_PROJECT_ID || NOW_PROJECT_ID;
return { VERCEL_ORG_ID, VERCEL_PROJECT_ID };
}
export async function linkFolderToProject(
output: Output,
path: string,
@@ -184,7 +172,8 @@ export async function linkFolderToProject(
projectName: string,
orgSlug: string
) {
const { VERCEL_ORG_ID, VERCEL_PROJECT_ID } = getFlags();
const VERCEL_ORG_ID = getPlatformEnv('ORG_ID');
const VERCEL_PROJECT_ID = getPlatformEnv('PROJECT_ID');
// if defined, skip linking
if (VERCEL_ORG_ID || VERCEL_PROJECT_ID) {

View File

@@ -104,7 +104,7 @@ async function exec(directory, args = []) {
return execa(binaryPath, ['dev', directory, ...args], {
reject: false,
shell: true,
env: { __NOW_SKIP_DEV_COMMAND: 1 },
env: { __VERCEL_SKIP_DEV_CMD: 1 },
});
}
@@ -180,7 +180,7 @@ async function testFixture(directory, opts = {}, args = []) {
shell: true,
stdio: 'pipe',
...opts,
env: { ...opts.env, __NOW_SKIP_DEV_COMMAND: 1 },
env: { ...opts.env, __VERCEL_SKIP_DEV_CMD: 1 },
}
);
@@ -287,7 +287,7 @@ function testFixtureStdio(
let printedOutput = false;
const env = skipDeploy
? { ...process.env, __NOW_SKIP_DEV_COMMAND: 1 }
? { ...process.env, __VERCEL_SKIP_DEV_CMD: 1 }
: process.env;
dev = execa(
binaryPath,

View File

@@ -172,7 +172,8 @@ fs.writeFileSync(
'index.js',
fs
.readFileSync('index.js', 'utf8')
.replace('BUILD_ENV_DEBUG', process.env.NOW_BUILDER_DEBUG ? 'on' : 'off'),
.replace('BUILD_ENV_DEBUG', process.env.NOW_BUILDER_DEBUG ? 'on' : 'off')
.replace('BUILD_ENV_DEBUG', process.env.VERCEL_BUILDER_DEBUG ? 'on' : 'off'),
);
`,
'index.js': `

View File

@@ -237,9 +237,7 @@ export const prepareFiles = (
};
export function createDebug(debug?: boolean) {
const isDebug = debug || process.env.NOW_CLIENT_DEBUG;
if (isDebug) {
if (debug) {
return (...logs: string[]) => {
process.stderr.write(
[`[now-client-debug] ${new Date().toISOString()}`, ...logs].join(' ') +

View File

@@ -215,7 +215,7 @@ export const build = async ({
if (!nextVersion) {
throw new NowBuildError({
code: 'NOW_NEXT_NO_VERSION',
code: 'NEXT_NO_VERSION',
message:
'No Next.js version could be detected in "package.json". Make sure `"next"` is installed in "dependencies" or "devDependencies"',
});
@@ -443,14 +443,14 @@ export const build = async ({
if (!nextBasePath.startsWith('/')) {
throw new NowBuildError({
code: 'NOW_NEXT_BASEPATH_STARTING_SLASH',
code: 'NEXT_BASEPATH_STARTING_SLASH',
message:
'basePath must start with `/`. Please upgrade your `@vercel/next` builder and try again. Contact support if this continues to happen.',
});
}
if (nextBasePath.endsWith('/')) {
throw new NowBuildError({
code: 'NOW_NEXT_BASEPATH_TRAILING_SLASH',
code: 'NEXT_BASEPATH_TRAILING_SLASH',
message:
'basePath must not end with `/`. Please upgrade your `@vercel/next` builder and try again. Contact support if this continues to happen.',
});
@@ -467,7 +467,7 @@ export const build = async ({
default: {
// update MIN_ROUTES_MANIFEST_VERSION in ./utils.ts
throw new NowBuildError({
code: 'NOW_NEXT_VERSION_OUTDATED',
code: 'NEXT_VERSION_OUTDATED',
message:
'This version of `@vercel/next` does not support the version of Next.js you are trying to deploy.\n' +
'Please upgrade your `@vercel/next` builder and try again. Contact support if this continues to happen.',
@@ -485,7 +485,7 @@ export const build = async ({
const resultingExport = await getExportStatus(entryPath);
if (!resultingExport) {
throw new NowBuildError({
code: 'NOW_NEXT_EXPORT_FAILED',
code: 'NEXT_EXPORT_FAILED',
message:
'Exporting Next.js app failed. Please check your build logs and contact us if this continues.',
});
@@ -493,7 +493,7 @@ export const build = async ({
if (resultingExport.success !== true) {
throw new NowBuildError({
code: 'NOW_NEXT_EXPORT_FAILED',
code: 'NEXT_EXPORT_FAILED',
message: 'Export of Next.js app failed. Please check your build logs.',
});
}
@@ -639,7 +639,7 @@ export const build = async ({
'BUILD_ID not found in ".next". The "package.json" "build" script did not run "next build"'
);
throw new NowBuildError({
code: 'NOW_NEXT_NO_BUILD_ID',
code: 'NEXT_NO_BUILD_ID',
message: 'Missing BUILD_ID',
});
}
@@ -786,7 +786,7 @@ export const build = async ({
}
throw new NowBuildError({
code: 'NOW_NEXT_NO_SERVERLESS_PAGES',
code: 'NEXT_NO_SERVERLESS_PAGES',
message: 'No serverless pages were built',
link: 'https://err.sh/zeit/now/now-next-no-serverless-pages-built',
});
@@ -997,7 +997,7 @@ export const build = async ({
) => {
if (isBlocking && isFallback) {
throw new NowBuildError({
code: 'NOW_NEXT_ISBLOCKING_ISFALLBACK',
code: 'NEXT_ISBLOCKING_ISFALLBACK',
message: 'invariant: isBlocking and isFallback cannot both be true',
});
}
@@ -1040,7 +1040,7 @@ export const build = async ({
if (initialRevalidate === false) {
// Lazy routes cannot be "snapshotted" in time.
throw new NowBuildError({
code: 'NOW_NEXT_ISLAZY_INITIALREVALIDATE',
code: 'NEXT_ISLAZY_INITIALREVALIDATE',
message: 'invariant isLazy: initialRevalidate !== false',
});
}
@@ -1064,7 +1064,7 @@ export const build = async ({
const lambda = lambdas[outputSrcPathPage];
if (lambda == null) {
throw new NowBuildError({
code: 'NOW_NEXT_MISSING_LAMBDA',
code: 'NEXT_MISSING_LAMBDA',
message: `Unable to find lambda for route: ${routeFileNoExt}`,
});
}
@@ -1072,7 +1072,7 @@ export const build = async ({
if (initialRevalidate === false) {
if (htmlFsRef == null || jsonFsRef == null) {
throw new NowBuildError({
code: 'NOW_NEXT_HTMLFSREF_JSONFSREF',
code: 'NEXT_HTMLFSREF_JSONFSREF',
message: 'invariant: htmlFsRef != null && jsonFsRef != null',
});
}
@@ -1189,7 +1189,7 @@ export const build = async ({
);
if (typeof lambdas[routeFileNoExt] === undefined) {
throw new NowBuildError({
code: 'NOW_NEXT__UNKNOWN_ROUTE_KEY',
code: 'NEXT__UNKNOWN_ROUTE_KEY',
message: `invariant: unknown lambda ${routeKey} (lookup: ${routeFileNoExt}) | please report this immediately`,
});
}
@@ -1328,7 +1328,7 @@ export const prepareCache = async ({
const nextVersion = getNextVersion(pkg);
if (!nextVersion)
throw new NowBuildError({
code: 'NOW_NEXT_VERSION_PARSE_FAILED',
code: 'NEXT_VERSION_PARSE_FAILED',
message: 'Could not parse Next.js version',
});
const isLegacy = isLegacyNext(nextVersion);

View File

@@ -4,8 +4,8 @@ import url from 'url';
import { Bridge } from './now__bridge';
if (!process.env.NODE_ENV) {
process.env.NODE_ENV =
process.env.NOW_REGION === 'dev1' ? 'development' : 'production';
const region = process.env.VERCEL_REGION || process.env.NOW_REGION;
process.env.NODE_ENV = region === 'dev1' ? 'development' : 'production';
}
const app = next({});

View File

@@ -1,6 +1,6 @@
if (!process.env.NODE_ENV) {
process.env.NODE_ENV =
process.env.NOW_REGION === 'dev1' ? 'development' : 'production';
const region = process.env.VERCEL_REGION || process.env.NOW_REGION;
process.env.NODE_ENV = region === 'dev1' ? 'development' : 'production';
}
import { Server } from 'http';

View File

@@ -42,7 +42,7 @@ function validateEntrypoint(entrypoint: string) {
throw new NowBuildError({
message:
'Specified "src" for "@vercel/next" has to be "package.json" or "next.config.js"',
code: 'NOW_NEXT_INCORRECT_SRC',
code: 'NEXT_INCORRECT_SRC',
});
}
}
@@ -352,7 +352,7 @@ export async function getRoutesManifest(
throw new NowBuildError({
message: `A "routes-manifest.json" couldn't be found. Is the correct output directory configured? This setting does not need to be changed in most cases`,
link: 'https://err.sh/zeit/now/now-next-routes-manifest',
code: 'NOW_NEXT_NO_ROUTES_MANIFEST',
code: 'NEXT_NO_ROUTES_MANIFEST',
});
}
@@ -400,7 +400,7 @@ export async function getDynamicRoutes(
message:
'This version of `@vercel/next` does not support the version of Next.js you are trying to deploy.\n' +
'Please upgrade your `@vercel/next` builder and try again. Contact support if this continues to happen.',
code: 'NOW_NEXT_VERSION_UPGRADE',
code: 'NEXT_VERSION_UPGRADE',
});
}
}
@@ -441,7 +441,7 @@ export async function getDynamicRoutes(
throw new NowBuildError({
message:
'Found usage of dynamic routes but not on a new enough version of Next.js.',
code: 'NOW_NEXT_DYNAMIC_ROUTES_OUTDATED',
code: 'NEXT_DYNAMIC_ROUTES_OUTDATED',
});
}

View File

@@ -31,8 +31,8 @@ Server.prototype.listen = function listen() {
};
if (!process.env.NODE_ENV) {
process.env.NODE_ENV =
process.env.NOW_REGION === 'dev1' ? 'development' : 'production';
const region = process.env.VERCEL_REGION || process.env.NOW_REGION;
process.env.NODE_ENV = region === 'dev1' ? 'development' : 'production';
}
try {
@@ -85,7 +85,7 @@ exports.launcher = bridge.launcher;`;
export function makeAwsLauncher({
entrypointPath,
awsLambdaHandler = ''
awsLambdaHandler = '',
}: LauncherConfiguration): string {
const funcName = awsLambdaHandler.split('.').pop();
return `const url = require("url");

View File

@@ -182,7 +182,7 @@ export function register(opts: Options = {}): Register {
function createTSError(diagnostics: ReadonlyArray<_ts.Diagnostic>) {
const message = formatDiagnostics(diagnostics, diagnosticHost);
return new NowBuildError({ code: 'NOW_NODE_TYPESCRIPT_ERROR', message });
return new NowBuildError({ code: 'NODE_TYPESCRIPT_ERROR', message });
}
function reportTSError(

View File

@@ -40,7 +40,7 @@ function getRubyPath(meta: Meta, gemfileContents: string) {
});
if (!found) {
throw new NowBuildError({
code: 'NOW_RUBY_INVALID_VERSION',
code: 'RUBY_INVALID_VERSION',
message: 'Found `Gemfile` with invalid Ruby version: `' + line + '`.',
link:
'https://vercel.com/docs/runtimes#official-runtimes/ruby/ruby-version',

View File

@@ -60,7 +60,7 @@ function validateDistDir(distDir: string) {
if (!exists()) {
throw new NowBuildError({
code: 'NOW_STATIC_BUILD_NO_OUT_DIR',
code: 'STATIC_BUILD_NO_OUT_DIR',
message: `No Output Directory named "${distDirName}" found after the Build completed. You can configure the Output Directory in your project settings.`,
link,
});
@@ -68,7 +68,7 @@ function validateDistDir(distDir: string) {
if (!isDirectory()) {
throw new NowBuildError({
code: 'NOW_STATIC_BUILD_NOT_A_DIR',
code: 'STATIC_BUILD_NOT_A_DIR',
message: `The path specified as Output Directory ("${distDirName}") is not actually a directory.`,
link,
});
@@ -76,7 +76,7 @@ function validateDistDir(distDir: string) {
if (isEmpty()) {
throw new NowBuildError({
code: 'NOW_STATIC_BUILD_EMPTY_OUT_DIR',
code: 'STATIC_BUILD_EMPTY_OUT_DIR',
message: `The Output Directory "${distDirName}" is empty.`,
link,
});
@@ -229,7 +229,7 @@ async function fetchBinary(url: string, framework: string, version: string) {
const res = await fetch(url);
if (res.status === 404) {
throw new NowBuildError({
code: 'NOW_STATIC_BUILD_BINARY_NOT_FOUND',
code: 'STATIC_BUILD_BINARY_NOT_FOUND',
message: `Version ${version} of ${framework} does not exist. Please specify a different one.`,
link: 'https://vercel.com/docs/v2/build-step#framework-versioning',
});

View File

@@ -12,7 +12,7 @@
],
"build": {
"env": {
"NOW_BUILDER_DEBUG": "1"
"VERCEL_BUILDER_DEBUG": "1"
}
},
"probes": [{ "path": "/", "mustContain": "hello world" }]

View File

@@ -11,7 +11,7 @@
],
"build": {
"env": {
"NOW_BUILDER_DEBUG": "1"
"VERCEL_BUILDER_DEBUG": "1"
}
},
"probes": [{ "path": "/", "mustContain": "My First Post" }]

View File

@@ -15,7 +15,7 @@ async function nowDeploy(bodies, randomness) {
mode: path.extname(n) === '.sh' ? 0o100755 : 0o100644,
}));
const { FORCE_BUILD_IN_REGION, NOW_DEBUG } = process.env;
const { FORCE_BUILD_IN_REGION, NOW_DEBUG, VERCEL_DEBUG } = process.env;
const nowJson = JSON.parse(bodies['now.json']);
const nowDeployPayload = {
@@ -28,6 +28,7 @@ async function nowDeploy(bodies, randomness) {
RANDOMNESS_BUILD_ENV_VAR: randomness,
FORCE_BUILD_IN_REGION,
NOW_DEBUG,
VERCEL_DEBUG,
},
},
name: 'test2020',
@@ -145,10 +146,9 @@ async function fetchWithAuth(url, opts = {}) {
currentCount += 1;
if (!token || currentCount === MAX_COUNT) {
currentCount = 0;
if (process.env.NOW_TOKEN) {
// used for health checks
token = process.env.NOW_TOKEN;
} else {
token = process.env.VERCEL_TOKEN || process.env.NOW_TOKEN;
if (!token) {
// used by GH Actions
token = await fetchTokenWithRetry();
}
@@ -161,14 +161,21 @@ async function fetchWithAuth(url, opts = {}) {
}
async function fetchTokenWithRetry(retries = 5) {
const { NOW_TOKEN, ZEIT_TEAM_TOKEN, ZEIT_REGISTRATION_URL } = process.env;
if (NOW_TOKEN) {
console.log('Using NOW_TOKEN for test deployment');
return NOW_TOKEN;
const {
NOW_TOKEN,
VERCEL_TOKEN,
ZEIT_TEAM_TOKEN,
ZEIT_REGISTRATION_URL,
} = process.env;
if (VERCEL_TOKEN || NOW_TOKEN) {
console.log('Your personal token will be used to make test deployments.');
return VERCEL_TOKEN || NOW_TOKEN;
}
if (!ZEIT_TEAM_TOKEN || !ZEIT_REGISTRATION_URL) {
throw new Error(
'Failed to create test deployment. Did you forget to set NOW_TOKEN?'
process.env.CI
? 'Failed to create test deployment. This is expected for 3rd-party Pull Requests. Please run tests locally.'
: 'Failed to create test deployment. Please set `VERCEL_TOKEN` environment variable and run again.'
);
}
try {

View File

@@ -54,16 +54,16 @@ async function testDeployment(
}
// we use json5 to allow comments for probes
const nowJson = json5.parse(bodies['now.json']);
const nowJson = json5.parse(bodies['vercel.json'] || bodies['now.json']);
if (process.env.NOW_BUILDER_DEBUG) {
if (process.env.VERCEL_BUILDER_DEBUG) {
if (!nowJson.build) {
nowJson.build = {};
}
if (!nowJson.build.env) {
nowJson.build.env = {};
}
nowJson.build.env.NOW_BUILDER_DEBUG = process.env.NOW_BUILDER_DEBUG;
nowJson.build.env.VERCEL_BUILDER_DEBUG = process.env.VERCEL_BUILDER_DEBUG;
}
for (const build of nowJson.builds || []) {