forked from forbole/big-dipper-2.0-cosmos
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvercel-deploy.js
124 lines (106 loc) · 3.96 KB
/
vercel-deploy.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/* eslint-disable @typescript-eslint/no-var-requires, no-console, turbo/no-undeclared-env-vars */
/**
* This script is used to build the correct project based on the PR.
* the title suffix should be in the format of [workspace-name]
* otherwise, it will build the web project
*/
const { execSync } = require('child_process');
/**
* It executes a shell command and returns the result
* @param command - The command to execute.
* @returns The result of the command being executed.
*/
function execShell(command) {
console.log(`executing command ${command}`);
const output = execSync(command, {
cwd: process.cwd(),
encoding: 'utf-8',
env: process.env,
});
console.log(output);
return output;
}
/**
* Getting the list of projects in the workspace and then
* finding the project that matches the title of the PR.
*/
function getProjectList() {
const projects = execShell(`yarn workspaces list --json`);
const projectList = projects
.split(/\n/g)
.filter((p) => p)
.map((p) => JSON.parse(p).name)
.filter((p) => p.startsWith('web'));
return projectList;
}
/**
* It removes all the unused projects from the workspace, cleans the yarn cache, and moves the built
* project to the web folder
* @param project - The name of the project to build.
*/
function cleanUnusedProjects(project, projectList) {
const unusedProjects = projectList
.filter((p) => p !== project)
.map((p) => `apps/${p} `)
.join('');
if (unusedProjects) execShell(`rm -rf ${unusedProjects}`);
execShell(`yarn cache clean --mirror`);
execShell(`yarn config set supportedArchitectures --json '{}'`);
/* Move the built project to the web folder. */
if (project !== 'web') {
execShell(`mv apps/${project} apps/web`);
}
}
console.log('running vercel-deploy.js', process.argv[2] ?? '');
/**
* Vercel deployment flow:
* 1. turbo-ignore, if error, proceed with deployment, otherwise cancel the deployment
* `node vercel-deploy.js turbo-ignore`
* 2. install
* `node vercel-deploy.js install`
* 3. build
* `node vercel-deploy.js`
*/
if (process.argv[2] === 'manual') {
const projectList = getProjectList();
const project = projectList.find((p) => p === process.argv[3]);
if (!project) throw new Error('project not found');
cleanUnusedProjects(project, projectList);
execShell(`YARN_ENABLE_IMMUTABLE_INSTALLS=false yarn install --inline-builds`);
} else if (process.argv[2] === 'turbo-ignore') {
try {
let project = 'web';
const projectList = getProjectList();
// VERCEL_GIT_PULL_REQUEST_ID is the pull request id
const pullId = process.env.VERCEL_GIT_PULL_REQUEST_ID;
console.log(`VERCEL_GIT_PULL_REQUEST_ID:`, pullId);
if (pullId) {
// GITHUB_API_TOKEN is the github api token, we need it to get the pull request title
const apiToken = process.env.GITHUB_API_TOKEN;
if (!apiToken) throw new Error('GITHUB_API_TOKEN is not defined');
/* Getting the pull request title. */
const response = execShell(
`curl ` +
`-H 'Accept: application/vnd.github+json' ` +
`-H 'Authorization: Bearer '$GITHUB_API_TOKEN ` +
`-H 'X-GitHub-Api-Version: 2022-11-28' ` +
`https://api.github.com/repos/forbole/big-dipper-2.0-cosmos/pulls/${pullId}`
);
const { title } = JSON.parse(response);
project = projectList.find((p) => title.endsWith(`[${p}]`)) || 'web';
}
cleanUnusedProjects(project, projectList);
} catch (error) {
console.error(error);
return; // cancel deployment
}
if (process.env.VERCEL_ENV === 'production')
throw new Error('✅ proceeding with deployment (production)');
execShell(`yarn workspace ${project} dlx turbo-ignore`);
} else if (process.argv[2] === 'install') {
execShell(`YARN_ENABLE_IMMUTABLE_INSTALLS=false yarn install --inline-builds`);
} else {
/* Building the project. */
const { name } = JSON.parse(execShell(`cat apps/web/package.json`));
execShell(`BASE_PATH=/ yarn workspace ${name} next build`);
}