diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a2f2936f88..6370a92b8b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Added `functions.list_functions` as a MCP tool (#9369) - Added AI Logic to `firebase init` CLI command and `firebase_init` MCP tool. (#9185) - Improved error messages for Firebase AI Logic provisioning during 'firebase init' (#9377) +- Fixed issue where 'init hosting' failed to prompt for the public directory and set up Hosting files (#9403) - Added `appdistribution:testcases:export` and `appdistribution:testcases:import` (#9397) - Updated to v2.16.0 of the Data Connect emulator, which includes internal improvements. - Data Connect now allows executing a valid query / operation even if the other operations are invalid. (This toleration provides convenience on a best-effort basis. Some errors like invalid syntax can still cause the whole request to be rejected.) diff --git a/src/init/features/hosting/github.ts b/src/init/features/hosting/github.ts index 906b27bedca..633829d394f 100644 --- a/src/init/features/hosting/github.ts +++ b/src/init/features/hosting/github.ts @@ -57,7 +57,7 @@ export async function initGitHub(setup: Setup): Promise { return reject("Could not determine Project ID, can't set up GitHub workflow.", { exit: 1 }); } - if (!setup.config.hosting) { + if (!setup.config.hosting && !setup.featureInfo?.hosting) { return reject( `Didn't find a Hosting config in firebase.json. Run ${bold("firebase init hosting")} instead.`, ); @@ -132,7 +132,7 @@ export async function initGitHub(setup: Setup): Promise { // If the developer is using predeploy scripts in firebase.json, // remind them before they set up a script in their workflow file. - if (!Array.isArray(setup.config.hosting) && setup.config.hosting.predeploy) { + if (!Array.isArray(setup.config.hosting) && setup.config.hosting?.predeploy) { logBullet(`You have a predeploy script configured in firebase.json.`); } diff --git a/src/init/features/hosting/index.ts b/src/init/features/hosting/index.ts index 5db896fd96e..e80e73eb5f3 100644 --- a/src/init/features/hosting/index.ts +++ b/src/init/features/hosting/index.ts @@ -68,10 +68,11 @@ export async function askQuestions(setup: Setup, config: Config, options: Option } } + let discoveredFramework = experiments.isEnabled("webframeworks") + ? await discover(config.projectDir, false) + : undefined; + if (experiments.isEnabled("webframeworks")) { - let discoveredFramework = experiments.isEnabled("webframeworks") - ? await discover(config.projectDir, false) - : undefined; // First, if we're in a framework directory, ask to use that. if ( discoveredFramework && @@ -90,54 +91,53 @@ export async function askQuestions(setup: Setup, config: Config, options: Option `Do you want to use a web framework? (${clc.bold("experimental")})`, ); } - // If they say yes, ask for source directory if its not already known - if (setup.featureInfo.hosting.useWebFrameworks) { - setup.featureInfo.hosting.source ??= await input({ - message: "What folder would you like to use for your web application's root directory?", - default: "hosting", - }); + } - discoveredFramework = await discover( - join(config.projectDir, setup.featureInfo.hosting.source), - ); + // If they say yes, ask for source directory if its not already known + if (setup.featureInfo.hosting.useWebFrameworks) { + setup.featureInfo.hosting.source ??= await input({ + message: "What folder would you like to use for your web application's root directory?", + default: "hosting", + }); - if (discoveredFramework) { - const name = WebFrameworks[discoveredFramework.framework].name; - setup.featureInfo.hosting.useDiscoveredFramework ??= await confirm({ - message: `Detected an existing ${name} codebase in ${setup.featureInfo.hosting.source}, should we use this?`, - default: true, - }); - if (setup.featureInfo.hosting.useDiscoveredFramework) - setup.featureInfo.hosting.webFramework = discoveredFramework.framework; - } + discoveredFramework = await discover(join(config.projectDir, setup.featureInfo.hosting.source)); - // If it is not known already, ask what framework to use. - const choices: { name: string; value: string }[] = []; - for (const value in WebFrameworks) { - if (WebFrameworks[value]) { - const { name, init } = WebFrameworks[value]; - if (init) choices.push({ name, value }); - } + if (discoveredFramework) { + const name = WebFrameworks[discoveredFramework.framework].name; + setup.featureInfo.hosting.useDiscoveredFramework ??= await confirm({ + message: `Detected an existing ${name} codebase in ${setup.featureInfo.hosting.source}, should we use this?`, + default: true, + }); + if (setup.featureInfo.hosting.useDiscoveredFramework) + setup.featureInfo.hosting.webFramework = discoveredFramework.framework; + } + + // If it is not known already, ask what framework to use. + const choices: { name: string; value: string }[] = []; + for (const value in WebFrameworks) { + if (WebFrameworks[value]) { + const { name, init } = WebFrameworks[value]; + if (init) choices.push({ name, value }); } + } - const defaultChoice = choices.find( - ({ value }) => value === discoveredFramework?.framework, - )?.value; + const defaultChoice = choices.find( + ({ value }) => value === discoveredFramework?.framework, + )?.value; - setup.featureInfo.hosting.webFramework ??= await select({ - message: "Please choose the framework:", - default: defaultChoice, - choices, - }); + setup.featureInfo.hosting.webFramework ??= await select({ + message: "Please choose the framework:", + default: defaultChoice, + choices, + }); - setup.featureInfo.hosting.region = - setup.featureInfo.hosting.region || - (await select({ - message: "In which region would you like to host server-side content, if applicable?", - default: DEFAULT_REGION, - choices: ALLOWED_SSR_REGIONS.filter((region) => region.recommended), - })); - } + setup.featureInfo.hosting.region = + setup.featureInfo.hosting.region || + (await select({ + message: "In which region would you like to host server-side content, if applicable?", + default: DEFAULT_REGION, + choices: ALLOWED_SSR_REGIONS.filter((region) => region.recommended), + })); } else { logger.info(); logger.info( @@ -157,6 +157,7 @@ export async function askQuestions(setup: Setup, config: Config, options: Option "Configure as a single-page app (rewrite all urls to /index.html)?", ); } + // GitHub Action set up is still structured as doSetup if (await confirm("Set up automatic builds and deploys with GitHub?")) { return initGitHub(setup);