mirror of
https://github.com/LukeHagar/vercel.git
synced 2025-12-07 12:57:47 +00:00
[next] Add @vercel/next Builder (#7793)
This commit is contained in:
@@ -4,12 +4,21 @@ const path = require('path');
|
||||
const _fetch = require('node-fetch');
|
||||
const fetch = require('./fetch-retry.js');
|
||||
const fileModeSymbol = Symbol('fileMode');
|
||||
const { logWithinTest } = require('./log');
|
||||
const ms = require('ms');
|
||||
|
||||
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
|
||||
|
||||
async function nowDeploy(bodies, randomness, uploadNowJson) {
|
||||
const files = Object.keys(bodies)
|
||||
.filter(n =>
|
||||
uploadNowJson ? true : n !== 'vercel.json' && n !== 'now.json'
|
||||
uploadNowJson
|
||||
? true
|
||||
: n !== 'vercel.json' &&
|
||||
n !== 'now.json' &&
|
||||
!n.includes('node_modules/') &&
|
||||
!n.includes('.git/') &&
|
||||
!n.includes('.next/')
|
||||
)
|
||||
.map(n => ({
|
||||
sha: digestOfFile(bodies[n]),
|
||||
@@ -20,12 +29,7 @@ async function nowDeploy(bodies, randomness, uploadNowJson) {
|
||||
(path.extname(n) === '.sh' ? 0o100755 : 0o100644),
|
||||
}));
|
||||
|
||||
const {
|
||||
FORCE_BUILD_IN_REGION,
|
||||
NOW_DEBUG,
|
||||
VERCEL_DEBUG,
|
||||
VERCEL_BUILDER_DEBUG,
|
||||
} = process.env;
|
||||
const { FORCE_BUILD_IN_REGION, NOW_DEBUG, VERCEL_DEBUG } = process.env;
|
||||
const nowJson = JSON.parse(bodies['vercel.json'] || bodies['now.json']);
|
||||
|
||||
const nowDeployPayload = {
|
||||
@@ -39,17 +43,22 @@ async function nowDeploy(bodies, randomness, uploadNowJson) {
|
||||
FORCE_BUILD_IN_REGION,
|
||||
NOW_DEBUG,
|
||||
VERCEL_DEBUG,
|
||||
VERCEL_BUILDER_DEBUG,
|
||||
NEXT_TELEMETRY_DISABLED: '1',
|
||||
},
|
||||
},
|
||||
name: 'test2020',
|
||||
files,
|
||||
builds: nowJson.builds,
|
||||
routes: nowJson.routes || [],
|
||||
meta: {},
|
||||
};
|
||||
|
||||
console.log(`posting ${files.length} files`);
|
||||
for (const field of ['routes', 'rewrites', 'headers', 'redirects']) {
|
||||
if (nowJson[field]) {
|
||||
nowDeployPayload[field] = nowJson[field];
|
||||
}
|
||||
}
|
||||
|
||||
logWithinTest(`posting ${files.length} files`);
|
||||
|
||||
for (const { file: filename } of files) {
|
||||
await filePost(bodies[filename], digestOfFile(bodies[filename]));
|
||||
@@ -66,22 +75,28 @@ async function nowDeploy(bodies, randomness, uploadNowJson) {
|
||||
deploymentUrl = json.url;
|
||||
}
|
||||
|
||||
console.log('id', deploymentId);
|
||||
console.log('deploymentUrl', `https://${deploymentUrl}`);
|
||||
logWithinTest('id', deploymentId);
|
||||
const st = expect.getState();
|
||||
const expectstate = {
|
||||
currentTestName: st.currentTestName,
|
||||
testPath: st.testPath,
|
||||
};
|
||||
logWithinTest('deploymentUrl', `https://${deploymentUrl}`, expectstate);
|
||||
|
||||
for (let i = 0; i < 750; i += 1) {
|
||||
const deployment = await deploymentGet(deploymentId);
|
||||
const { readyState } = deployment;
|
||||
if (readyState === 'ERROR') {
|
||||
const error = new Error(
|
||||
`State of https://${deploymentUrl} is ${readyState}`
|
||||
);
|
||||
logWithinTest('state is ERROR, throwing');
|
||||
const error = new Error(`State of https://${deploymentUrl} is ERROR`);
|
||||
error.deployment = deployment;
|
||||
throw error;
|
||||
}
|
||||
if (readyState === 'READY') {
|
||||
logWithinTest('state is READY, moving on');
|
||||
break;
|
||||
}
|
||||
logWithinTest('state is ', readyState, 'retrying in 1 second');
|
||||
await new Promise(r => setTimeout(r, 1000));
|
||||
}
|
||||
|
||||
@@ -108,6 +123,7 @@ async function filePost(body, digest) {
|
||||
method: 'POST',
|
||||
headers,
|
||||
body,
|
||||
timeout: ms('30s'),
|
||||
});
|
||||
|
||||
const json = await resp.json();
|
||||
@@ -115,7 +131,7 @@ async function filePost(body, digest) {
|
||||
if (json.error) {
|
||||
const { status, statusText, headers } = resp;
|
||||
const { message } = json.error;
|
||||
console.log('Fetch Error', { url, status, statusText, headers, digest });
|
||||
logWithinTest('Fetch Error', { url, status, statusText, headers, digest });
|
||||
throw new Error(message);
|
||||
}
|
||||
return json;
|
||||
@@ -133,7 +149,7 @@ async function deploymentPost(payload) {
|
||||
if (json.error) {
|
||||
const { status, statusText, headers } = resp;
|
||||
const { message } = json.error;
|
||||
console.log('Fetch Error', { url, status, statusText, headers });
|
||||
logWithinTest('Fetch Error', { url, status, statusText, headers });
|
||||
throw new Error(message);
|
||||
}
|
||||
return json;
|
||||
@@ -141,12 +157,13 @@ async function deploymentPost(payload) {
|
||||
|
||||
async function deploymentGet(deploymentId) {
|
||||
const url = `/v12/now/deployments/${deploymentId}`;
|
||||
logWithinTest('fetching deployment', url);
|
||||
const resp = await fetchWithAuth(url);
|
||||
const json = await resp.json();
|
||||
if (json.error) {
|
||||
const { status, statusText, headers } = resp;
|
||||
const { message } = json.error;
|
||||
console.log('Fetch Error', { url, status, statusText, headers });
|
||||
logWithinTest('Fetch Error', { url, status, statusText, headers, message });
|
||||
throw new Error(message);
|
||||
}
|
||||
return json;
|
||||
@@ -163,6 +180,11 @@ async function fetchWithAuth(url, opts = {}) {
|
||||
opts.headers.Authorization = `Bearer ${await fetchCachedToken()}`;
|
||||
}
|
||||
|
||||
const { VERCEL_TEAM_ID } = process.env;
|
||||
|
||||
if (VERCEL_TEAM_ID) {
|
||||
url += `${url.includes('?') ? '&' : '?'}teamId=${VERCEL_TEAM_ID}`;
|
||||
}
|
||||
return await fetchApi(url, opts);
|
||||
}
|
||||
|
||||
@@ -178,13 +200,18 @@ async function fetchCachedToken() {
|
||||
async function fetchTokenWithRetry(retries = 5) {
|
||||
const {
|
||||
NOW_TOKEN,
|
||||
TEMP_TOKEN,
|
||||
VERCEL_TOKEN,
|
||||
VERCEL_TEAM_TOKEN,
|
||||
VERCEL_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 (VERCEL_TOKEN || NOW_TOKEN || TEMP_TOKEN) {
|
||||
if (!TEMP_TOKEN) {
|
||||
logWithinTest(
|
||||
'Your personal token will be used to make test deployments.'
|
||||
);
|
||||
}
|
||||
return VERCEL_TOKEN || NOW_TOKEN || TEMP_TOKEN;
|
||||
}
|
||||
if (!VERCEL_TEAM_TOKEN || !VERCEL_REGISTRATION_URL) {
|
||||
throw new Error(
|
||||
@@ -216,9 +243,12 @@ async function fetchTokenWithRetry(retries = 5) {
|
||||
}
|
||||
return data.token;
|
||||
} catch (error) {
|
||||
console.log(`Failed to fetch token. Retries remaining: ${retries}`);
|
||||
logWithinTest(
|
||||
`Failed to fetch token. Retries remaining: ${retries}`,
|
||||
error.message
|
||||
);
|
||||
if (retries === 0) {
|
||||
console.log(error);
|
||||
logWithinTest(error);
|
||||
throw error;
|
||||
}
|
||||
await sleep(500);
|
||||
@@ -232,8 +262,8 @@ async function fetchApi(url, opts = {}) {
|
||||
const { method = 'GET', body } = opts;
|
||||
|
||||
if (process.env.VERBOSE) {
|
||||
console.log('fetch', method, url);
|
||||
if (body) console.log(encodeURIComponent(body).slice(0, 80));
|
||||
logWithinTest('fetch', method, url);
|
||||
if (body) logWithinTest(encodeURIComponent(body).slice(0, 80));
|
||||
}
|
||||
|
||||
if (!opts.headers) opts.headers = {};
|
||||
@@ -242,6 +272,10 @@ async function fetchApi(url, opts = {}) {
|
||||
opts.headers.Accept = 'application/json';
|
||||
}
|
||||
|
||||
if (typeof opts.timeout === 'undefined') {
|
||||
opts.timeout = ms('30s');
|
||||
}
|
||||
|
||||
opts.headers['x-now-trace-priority'] = '1';
|
||||
|
||||
return await fetch(urlWithHost, opts);
|
||||
|
||||
Reference in New Issue
Block a user