-
Notifications
You must be signed in to change notification settings - Fork 6.8k
/
Copy pathdeploy-to-site.mts
75 lines (61 loc) · 2.6 KB
/
deploy-to-site.mts
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
import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path';
import {$} from 'zx';
import {SiteTarget} from './utils.mjs';
interface Deployment {
projectId: string;
site: SiteTarget;
}
/** Interface describing a production deployment. */
export interface ProductionDeployment extends Deployment {
description: string;
}
/** Interface describing a temporary preview deployment. */
export interface PreviewDeployment extends Deployment {
channelId: string;
expires: string;
}
/** Type describing a Firebase deployment. */
export type DeploymentInfo = ProductionDeployment | PreviewDeployment;
/** Path to a temporary file for the GCP service key credentials file. */
const gcpServiceKeyTmpFile = path.join(os.tmpdir(), 'mat-docs-deploy-gcp-key.json');
/**
* Deploys the docs site at the specified directory to Firebase with respect
* to the deployment information provided.
*
* The deployment info either describes the production deployment information,
* or a preview temporary deployment that will expire automatically.
*/
export async function deployToSite(
projectPath: string,
firebaseServiceKey: string,
info: DeploymentInfo,
) {
const firebase = async (...cmd: string[]) =>
$`pnpm --dir=${projectPath}/docs firebase --non-interactive ${cmd}`;
// Setup GCP service key for the docs-app deployment.
// https://firebase.google.com/docs/admin/setup.
await fs.promises.writeFile(gcpServiceKeyTmpFile, firebaseServiceKey);
process.env['GOOGLE_APPLICATION_CREDENTIALS'] = gcpServiceKeyTmpFile;
await firebase('use', info.projectId);
await firebase('target:clear', 'hosting', 'mat-aio');
await firebase('target:apply', 'hosting', 'mat-aio', info.site.firebaseSiteId);
if (isPreviewDeployment(info)) {
const channelId = info.channelId;
const expires = info.expires;
await firebase('hosting:channel:deploy', channelId, '--only', 'mat-aio', '--expires', expires);
} else {
await firebase('deploy', '--only', 'hosting:mat-aio', '--message', info.description);
}
// Remove the temporary service key file (this is an optional step and just for sanity).
await fs.promises.rm(gcpServiceKeyTmpFile, {force: true});
}
/** Whether the given deployment info corresponds to a preview deployment. */
export function isPreviewDeployment(info: DeploymentInfo): info is PreviewDeployment {
return (info as Partial<PreviewDeployment>).channelId !== undefined;
}
/** Whether the given deployment info corresponds to a production deployment. */
export function isProductionDeployment(info: DeploymentInfo): info is ProductionDeployment {
return !isPreviewDeployment(info);
}