Skip to content

Add firebase run:services:update command - #11206

Open
falahat wants to merge 3 commits into
bapi_deploy_runfrom
bapi_services_update
Open

falahat wants to merge 3 commits into
bapi_deploy_runfrom
bapi_services_update

Conversation

@falahat

@falahat falahat commented Sep 30, 2026

Copy link
Copy Markdown
Contributor

Description

Scenarios Tested

Sample Commands

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new command run:services:update (gated behind the direct_cloud_run experiment) to update, rebuild, and redeploy Cloud Run services, specifically supporting setting or clearing a base image. Feedback on the changes suggests: (1) iterating through all configurations returned by getServiceConfigs to properly support multi-region setups instead of only checking the first one, (2) gracefully handling cases where config.region is undefined in missingServiceMessage to prevent printing 'undefined' to users, and (3) using defensive assignment (|| {}) when initializing client.run namespaces to avoid overwriting existing properties.

Comment thread src/deploy/run/update.ts Outdated
Comment on lines +37 to +45
const [config] = getServiceConfigs({ ...options, only });
const existing = await getExistingService(projectId, config.region, serviceId);
if (!existing) {
throw new FirebaseError(`${missingServiceMessage(config)} Then you can update it.`);
}
if (clearBaseImage && !mainContainer(existing.template)?.baseImageUri) {
logBullet(`Service ${clc.bold(serviceId)} does not have a base image.`);
return;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The current implementation only checks the first configuration returned by getServiceConfigs. If a user has configured the same service in multiple regions (a common multi-region setup), this will only validate and clear the base image for the first region, while completely ignoring the others. Additionally, if config.region is missing from firebase.json, it will result in a malformed request or a generic crash. We should iterate through all configurations, validate that the region is specified, check if the service exists in each region, and determine if any of them have a base image before proceeding.

  const configs = getServiceConfigs({ ...options, only });
  let hasBaseImage = false;
  for (const config of configs) {
    if (!config.region) {
      throw new FirebaseError("Region is missing for service ${serviceId} in firebase.json.");
    }
    const existing = await getExistingService(projectId, config.region, serviceId);
    if (!existing) {
      throw new FirebaseError(`${missingServiceMessage(config)} Then you can update it.`);
    }
    if (mainContainer(existing.template)?.baseImageUri) {
      hasBaseImage = true;
    }
  }
  if (clearBaseImage && !hasBaseImage) {
    logBullet(`Service ${clc.bold(serviceId)} does not have a base image.`);
    return;
  }
References
  1. Use strict null checks and handle undefined/null explicitly. (link)

Comment thread src/deploy/run/util.ts
Comment on lines +63 to +66
export function missingServiceMessage(config: RunSingle): string {
const how = `Create it with ${clc.bold("firebase init run")} or ${clc.bold(`firebase deploy --only run:${config.serviceId}`)}.`;
return `Cloud Run service ${config.serviceId} doesn't exist in ${config.region} yet. ${how}`;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

If config.region is not defined in firebase.json, missingServiceMessage will print undefined in the error message (e.g., doesn't exist in undefined yet). We should handle the absence of config.region gracefully by omitting the region clause if it is not present.

Suggested change
export function missingServiceMessage(config: RunSingle): string {
const how = `Create it with ${clc.bold("firebase init run")} or ${clc.bold(`firebase deploy --only run:${config.serviceId}`)}.`;
return `Cloud Run service ${config.serviceId} doesn't exist in ${config.region} yet. ${how}`;
}
export function missingServiceMessage(config: RunSingle): string {
const regionStr = config.region ? ` in ${config.region}` : "";
const how = `Create it with ${clc.bold("firebase init run")} or ${clc.bold(`firebase deploy --only run:${config.serviceId}`)}.`;
return `Cloud Run service ${config.serviceId} doesn't exist${regionStr} yet. ${how}`;
}

Comment thread src/commands/index.ts Outdated
Comment on lines +304 to +308
if (experiments.isEnabled("direct_cloud_run")) {
client.run = {};
client.run.services = {};
client.run.services.update = loadCommand("run-services-update");
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

To prevent accidentally overwriting any existing client.run or client.run.services namespaces that might be initialized elsewhere or in future updates, use defensive assignment (|| {}).

Suggested change
if (experiments.isEnabled("direct_cloud_run")) {
client.run = {};
client.run.services = {};
client.run.services.update = loadCommand("run-services-update");
}
if (experiments.isEnabled("direct_cloud_run")) {
client.run = client.run || {};
client.run.services = client.run.services || {};
client.run.services.update = loadCommand("run-services-update");
}

@falahat
falahat added this pull request to stack #11209 September 30, 2026 04:19
@falahat
falahat force-pushed the bapi_services_update branch from 51f4259 to 595ee57 Compare September 30, 2026 04:20
@falahat
falahat force-pushed the bapi_services_update branch from 1608f73 to 9a8b7ca Compare September 30, 2026 21:37
@falahat
falahat removed this pull request from stack #11209 September 30, 2026 21:42

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants