Skip to content

Commit 3e1dd77

Browse files
authored
Improve log messages on skipped App Hosting source deploys (#8674)
* clearly display which backends are skipped & add spinners for hanging operations * remove skipped backend log if no backends skipped
1 parent 5578967 commit 3e1dd77

File tree

6 files changed

+51
-32
lines changed

6 files changed

+51
-32
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
- Improve log messages on skipped App Hosting source deploys. (#8674)
12
- Fixed issue in `init` where users were forced to specify emulator UI port (#8626)
23
- Added MCP tools for App Hosting (#8605)
34
- Fixed crash when starting the App Hosting emulator in certain applications (#8624)

src/apphosting/backend.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,10 +183,13 @@ export async function doSetupSourceDeploy(
183183
projectId,
184184
"Select a primary region to host your backend:\n",
185185
);
186+
const webAppSpinner = ora("Creating a new web app...\n").start();
186187
const webApp = await webApps.getOrCreateWebApp(projectId, null, backendId);
187188
if (!webApp) {
188189
logWarning(`Firebase web app not set`);
189190
}
191+
webAppSpinner.stop();
192+
190193
const createBackendSpinner = ora("Creating your new backend...").start();
191194
const backend = await createBackend(projectId, location, backendId, null, undefined, webApp?.id);
192195
createBackendSpinner.succeed(`Successfully created backend!\n\t${backend.name}\n`);

src/deploy/apphosting/deploy.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ import { createArchive } from "./util";
1414
* build and deployment. Creates storage buckets if necessary.
1515
*/
1616
export default async function (context: Context, options: Options): Promise<void> {
17+
if (context.backendConfigs.size === 0) {
18+
return;
19+
}
1720
const projectId = needProjectId(options);
1821
options.projectNumber = await getProjectNumber(options);
1922
if (!context.backendConfigs) {

src/deploy/apphosting/prepare.ts

Lines changed: 38 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ export default async function (context: Context, options: Options): Promise<void
4848
const foundBackends: AppHostingSingle[] = [];
4949
const notFoundBackends: AppHostingSingle[] = [];
5050
const ambiguousBackends: AppHostingSingle[] = [];
51+
const skippedBackends: AppHostingSingle[] = [];
5152
for (const cfg of configs) {
5253
const filteredBackends = backends.filter(
5354
(backend) => parseBackendName(backend.name).id === cfg.backendId,
@@ -85,6 +86,7 @@ export default async function (context: Context, options: Options): Promise<void
8586
(backend) => parseBackendName(backend.name).id === cfg.backendId,
8687
);
8788
if (cfg.alwaysDeployFromSource === false) {
89+
skippedBackends.push(cfg);
8890
continue;
8991
}
9092
const backend = filteredBackends[0];
@@ -106,10 +108,10 @@ export default async function (context: Context, options: Options): Promise<void
106108
options.config.writeProjectFile(configPath, options.config.src);
107109
logLabeledBullet(
108110
"apphosting",
109-
`On future invocations of "firebase deploy", your local source will be deployed to ${cfg.backendId}. You can edit this setting in your firebase.json at any time.`,
111+
`On future invocations of "firebase deploy", your local source will ${!confirmDeploy ? "not " : ""}be deployed to ${cfg.backendId}. You can edit this setting in your firebase.json at any time.`,
110112
);
111113
if (!confirmDeploy) {
112-
logLabeledWarning("apphosting", `Skipping deployment of backend ${cfg.backendId}`);
114+
skippedBackends.push(cfg);
113115
continue;
114116
}
115117
}
@@ -118,38 +120,44 @@ export default async function (context: Context, options: Options): Promise<void
118120
context.backendLocations.set(cfg.backendId, location);
119121
}
120122

121-
if (notFoundBackends.length === 0) {
122-
return;
123+
if (notFoundBackends.length > 0) {
124+
if (options.force) {
125+
logLabeledWarning(
126+
"apphosting",
127+
`Skipping deployments of backend(s) ${notFoundBackends.map((cfg) => cfg.backendId).join(", ")}; ` +
128+
"the backend(s) do not exist yet and we cannot create them for you because you must choose primary regions for each one. " +
129+
"Please run 'firebase deploy' without the --force flag, or 'firebase apphosting:backends:create' to create the backend, " +
130+
"then retry deployment.",
131+
);
132+
return;
133+
}
134+
const confirmCreate = await confirm({
135+
default: true,
136+
message: `Did not find backend(s) ${notFoundBackends.map((cfg) => cfg.backendId).join(", ")}. Do you want to create them (you'll have the option to select which to create in the next step)?`,
137+
});
138+
if (confirmCreate) {
139+
const selected = await checkbox<string>({
140+
message: "Which backends do you want to create and deploy to?",
141+
choices: notFoundBackends.map((cfg) => cfg.backendId),
142+
});
143+
const selectedBackends = selected.map((id) =>
144+
notFoundBackends.find((backend) => backend.backendId === id),
145+
) as AppHostingSingle[];
146+
for (const cfg of selectedBackends) {
147+
logLabeledBullet("apphosting", `Creating a new backend ${cfg.backendId}...`);
148+
const { location } = await doSetupSourceDeploy(projectId, cfg.backendId);
149+
context.backendConfigs.set(cfg.backendId, cfg);
150+
context.backendLocations.set(cfg.backendId, location);
151+
}
152+
} else {
153+
skippedBackends.push(...notFoundBackends);
154+
}
123155
}
124-
if (options.force) {
156+
if (skippedBackends.length > 0) {
125157
logLabeledWarning(
126158
"apphosting",
127-
`Skipping deployments of backend(s) ${notFoundBackends.map((cfg) => cfg.backendId).join(", ")}; ` +
128-
"the backend(s) do not exist yet and we cannot create them for you because you must choose primary regions for each one. " +
129-
"Please run 'firebase deploy' without the --force flag, or 'firebase apphosting:backends:create' to create the backend, " +
130-
"then retry deployment.",
159+
`Skipping deployment of backend(s) ${skippedBackends.map((cfg) => cfg.backendId).join(", ")}.`,
131160
);
132-
return;
133-
}
134-
const confirmCreate = await confirm({
135-
default: true,
136-
message: `Did not find backend(s) ${notFoundBackends.map((cfg) => cfg.backendId).join(", ")}. Do you want to create them (you'll have the option to select which to create in the next step)?`,
137-
});
138-
if (!confirmCreate) {
139-
return;
140-
}
141-
const selected = await checkbox<string>({
142-
message: "Which backends do you want to create and deploy to?",
143-
choices: notFoundBackends.map((cfg) => cfg.backendId),
144-
});
145-
const selectedBackends = selected.map((id) =>
146-
notFoundBackends.find((backend) => backend.backendId === id),
147-
) as AppHostingSingle[];
148-
for (const cfg of selectedBackends) {
149-
logLabeledBullet("apphosting", `Creating a new backend ${cfg.backendId}...`);
150-
const { location } = await doSetupSourceDeploy(projectId, cfg.backendId);
151-
context.backendConfigs.set(cfg.backendId, cfg);
152-
context.backendLocations.set(cfg.backendId, location);
153161
}
154162
return;
155163
}

src/deploy/apphosting/release.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@ import { Context } from "./args";
1616
* Orchestrates rollouts for the backends targeted for deployment.
1717
*/
1818
export default async function (context: Context, options: Options): Promise<void> {
19+
if (context.backendConfigs.size === 0) {
20+
return;
21+
}
1922
const projectId = needProjectId(options);
20-
2123
const rollouts = [];
2224
const backendIds = [];
2325
for (const backendId of context.backendConfigs.keys()) {

src/init/features/apphosting.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,17 @@ export async function doSetup(setup: Setup, config: Config): Promise<void> {
4343
// since IAM propagation delay will likely cause the first one to fail. However,
4444
// `firebase init apphosting` is a prerequisite to the `firebase deploy` command,
4545
// so we check and add the role here to give the IAM changes time to propagate.
46+
const spinner = ora("Checking your App Hosting compute service account...").start();
4647
try {
4748
await ensureAppHostingComputeServiceAccount(
4849
projectId,
4950
/* serviceAccount= */ "",
5051
/* deployFromSource= */ true,
5152
);
53+
spinner.succeed("App Hosting compute Service account is ready");
5254
} catch (err) {
5355
if ((err as FirebaseError).status === 400) {
54-
utils.logWarning(
56+
spinner.warn(
5557
"Your App Hosting compute service account is still being provisioned. Please try again in a few moments.",
5658
);
5759
}

0 commit comments

Comments
 (0)