Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 26 additions & 14 deletions src/schematics/deploy/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ const DEFAULT_CLOUD_RUN_OPTIONS: Partial<CloudRunOptions> = {

const spawnAsync = async (
command: string,
args: string[],
options?: SpawnOptionsWithoutStdio
) =>
new Promise<Buffer>((resolve, reject) => {
const [spawnCommand, ...args] = command.split(/\s+/);
const spawnProcess = spawn(spawnCommand, args, options);
const spawnProcess = spawn(command, args, options);
const chunks: Buffer[] = [];
const errorChunks: Buffer[] = [];
spawnProcess.stdout.on('data', (data) => {
Expand Down Expand Up @@ -353,25 +353,37 @@ export const deployToCloudRun = async (
throw new SchematicsException('Cloud Run preview not supported.');
}

const deployArguments: any[] = [];
const deployArguments: string[] = [];
const cloudRunOptions = options.cloudRunOptions || {};
Object.entries(DEFAULT_CLOUD_RUN_OPTIONS).forEach(([k, v]) => {
cloudRunOptions[k] ||= v;
});
// lean on the schema for validation (rather than sanitize)
if (cloudRunOptions.cpus) { deployArguments.push('--cpu', cloudRunOptions.cpus); }
if (cloudRunOptions.maxConcurrency) { deployArguments.push('--concurrency', cloudRunOptions.maxConcurrency); }
if (cloudRunOptions.maxInstances) { deployArguments.push('--max-instances', cloudRunOptions.maxInstances); }
if (cloudRunOptions.memory) { deployArguments.push('--memory', cloudRunOptions.memory); }
if (cloudRunOptions.minInstances) { deployArguments.push('--min-instances', cloudRunOptions.minInstances); }
if (cloudRunOptions.timeout) { deployArguments.push('--timeout', cloudRunOptions.timeout); }
if (cloudRunOptions.cpus) { deployArguments.push('--cpu', cloudRunOptions.cpus.toString()); }
if (cloudRunOptions.maxConcurrency) { deployArguments.push('--concurrency', cloudRunOptions.maxConcurrency.toString()); }
if (cloudRunOptions.maxInstances) { deployArguments.push('--max-instances', cloudRunOptions.maxInstances.toString()); }
if (cloudRunOptions.memory) { deployArguments.push('--memory', cloudRunOptions.memory.toString()); }
if (cloudRunOptions.minInstances) { deployArguments.push('--min-instances', cloudRunOptions.minInstances.toString()); }
if (cloudRunOptions.timeout) { deployArguments.push('--timeout', cloudRunOptions.timeout.toString()); }
if (cloudRunOptions.vpcConnector) { deployArguments.push('--vpc-connector', cloudRunOptions.vpcConnector); }

// TODO validate serviceId, firebaseProject, and vpcConnector both to limit errors and opp for injection

context.logger.info(`📦 Deploying to Cloud Run`);
await spawnAsync(`gcloud builds submit ${cloudRunOut} --tag gcr.io/${options.firebaseProject}/${serviceId} --project ${options.firebaseProject} --quiet`);
await spawnAsync(`gcloud run deploy ${serviceId} --image gcr.io/${options.firebaseProject}/${serviceId} --project ${options.firebaseProject} ${deployArguments.join(' ')} --platform managed --allow-unauthenticated --region=${options.region} --quiet`);
await spawnAsync('gcloud', [
'builds', 'submit', cloudRunOut,
'--tag', `gcr.io/${options.firebaseProject}/${serviceId}`,
'--project', options.firebaseProject,
'--quiet',
]);
await spawnAsync('gcloud', [
'run', 'deploy', serviceId,
'--image', `gcr.io/${options.firebaseProject}/${serviceId}`,
'--project', options.firebaseProject,
...deployArguments,
'--platform', 'managed',
'--allow-unauthenticated',
'--region', options.region,
'--quiet',
]);

// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const siteTarget = options.target ?? context.target!.project;
Expand Down Expand Up @@ -405,7 +417,7 @@ export default async function deploy(
}

if (!firebaseToken && process.env.GOOGLE_APPLICATION_CREDENTIALS) {
await spawnAsync(`gcloud auth activate-service-account --key-file ${process.env.GOOGLE_APPLICATION_CREDENTIALS}`);
await spawnAsync('gcloud', ['auth', 'activate-service-account', '--key-file', process.env.GOOGLE_APPLICATION_CREDENTIALS as string]);
console.log(`Using Google Application Credentials.`);
}

Expand Down