-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdeploy-functions.js
119 lines (105 loc) · 2.97 KB
/
deploy-functions.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
// @ts-check
/**
* A script to deploy functions to Firebase.
*
* Exists because Firebase's CLI cannot fetch code outside the functions
* folder.
*
* Run with `node deploy-functions.js`
*
* Optionally pass in a token and then project, like so:
* `node deploy-functions.js $TOKEN production`
*/
const { spawnSync } = require('child_process');
const fs = require('fs');
const path = require('path');
/**
*
* @param {string[]} commands
* @param {string | undefined} cwd
*/
function spawnSyncWithExitCodeCheck([command, ...commandArguments], cwd = undefined) {
const spawnedProcess = spawnSync(command, commandArguments, {
shell: true,
cwd,
stdio: [process.stdin, process.stdout, process.stderr],
});
if (spawnedProcess.status !== 0) {
process.exit(1);
}
}
// Step 1: Build projects
spawnSyncWithExitCodeCheck(['yarn']);
spawnSyncWithExitCodeCheck(['yarn', 'workspace', 'functions', 'build']);
// Step 2: Make mirror folders for deployment
/**
* Directory copy
* @param {string} from The path to the thing to copy.
* @param {string} to The path to the new copy.
*/
function copyFolderSync(from, to) {
fs.mkdirSync(to);
fs.readdirSync(from).forEach((element) => {
if (fs.lstatSync(path.join(from, element)).isFile()) {
fs.copyFileSync(path.join(from, element), path.join(to, element));
} else {
copyFolderSync(path.join(from, element), path.join(to, element));
}
});
}
fs.mkdirSync('temp');
/**
* Delete a folder recursively (because fs.rmdirSync recursive doesn't work on CI)
*
* @param {string} p The path to delete
*/
function deleteFolderRecursive(p) {
if (fs.existsSync(p)) {
fs.readdirSync(p).forEach((file) => {
const curPath = path.join(p, file);
if (fs.lstatSync(curPath).isDirectory()) {
// recurse
deleteFolderRecursive(curPath);
} else {
// delete file
fs.unlinkSync(curPath);
}
});
fs.rmdirSync(p);
}
}
// Copy deployment code
copyFolderSync('functions/compiled/', 'temp/functions/');
deleteFolderRecursive('functions/compiled/');
const tmpPackage = `{
"name": "functions",
"private": true,
"version": "0.1.0",
"main": "index.js",
"engines": {
"node": "12"
}
}`;
fs.writeFileSync('temp/functions/package.json', tmpPackage);
// Copy Firebase configs
fs.copyFileSync('firebase.json', 'temp/firebase.json');
fs.copyFileSync('.firebaserc', 'temp/.firebaserc');
// Step 3: Deploy
const token = process.argv[2];
const project = process.argv[3] ? process.argv[3] : 'default';
/**
* Run the firebase CLI with specified argument array
*
* @param {string[]} args Array of arguments to pass to the CLI.
*/
function firebase(args) {
spawnSyncWithExitCodeCheck([`${__dirname}/node_modules/.bin/firebase`, ...args], 'temp');
}
firebase(['use', project]);
if (!token) {
firebase(['deploy', '--only', 'functions']);
} else {
firebase(['deploy', `--token=${token}`, '--non-interactive', '--only', 'functions']);
}
// Step 4: Cleanup
deleteFolderRecursive('temp');