Skip to content

Zip deploy aryanf#10046

Draft
falahat wants to merge 30 commits intomainfrom
zip_deploy_aryanf
Draft

Zip deploy aryanf#10046
falahat wants to merge 30 commits intomainfrom
zip_deploy_aryanf

Conversation

@falahat
Copy link
Contributor

@falahat falahat commented Mar 9, 2026

Description

Improves the ability to test changes locally and build firebase app hosting apps locally before deployment.

Scenarios Tested

Sample Commands

annajowang and others added 19 commits November 22, 2025 01:29
1. Fix for injecting auto-init variables into the build

2. Fixes how we handle dependencies, nodejs paths, modulepaths, etc. This needs closer attention/fixes.

3. Adds env var handling (not secrets) and determines which env vars to pass down to the build
… variants) and include them in the final artifact
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the local development and deployment experience for Firebase App Hosting applications. It refines the local build process by enabling dynamic environment variable injection and proper Node.js module resolution, making local testing more robust. Furthermore, the deployment mechanism has been upgraded to use .tar.gz archives for source code, improving efficiency and compatibility. Key infrastructure changes include ensuring the App Hosting service agent has the correct permissions and updating GCS bucket configurations for improved security and management. These changes collectively streamline the journey from local development to cloud deployment for App Hosting users.

Highlights

  • Local Build and Testing Improvements: Enhanced the local build process for App Hosting applications by enabling environment variable injection and proper NODE_PATH configuration, facilitating more robust local testing and development.
  • Deployment Archiving Format Update: Switched the deployment artifact format from .zip to .tar.gz for source code and built applications, along with corresponding updates to archiving utilities and deployment logic.
  • Firebase SDK Auto-initialization: Implemented automatic injection of Firebase SDK configuration as environment variables during local builds and serving, streamlining integration for Firebase projects.
  • App Hosting Service Agent Permissions: Introduced a new function (ensureAppHostingServiceAgentRoles) to ensure the App Hosting service agent has necessary IAM roles, specifically storage.objectViewer, to manage resources.
  • API Version and Runtime Specification: Updated the App Hosting API version to v1alpha and added a runtime field for backend creation, defaulting to nodejs22.
  • GCS Bucket Configuration Enhancements: Enhanced Google Cloud Storage bucket creation and patching to support iamConfiguration for uniform bucket-level access.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • package.json
    • Updated @apphosting/build to ^0.1.7 and removed @apphosting/common.
    • Added es2020 dependency.
  • src/apphosting/backend.ts
    • Imported logger for improved logging.
    • Added ensureAppHostingServiceAgentRoles function to grant storage.objectViewer role to the App Hosting service agent.
    • Included a runtime field (nodejs22) in createBackend requests.
  • src/apphosting/config.spec.ts
    • Added a new test suite for splitEnvVars to verify stringification of numeric environment variables.
  • src/apphosting/config.ts
    • Imported basename from path.
    • Added splitEnvVars to separate build and runtime environment variables.
    • Introduced getAppHostingConfiguration to load and merge apphosting.yaml files with options for emulator and local configurations.
  • src/apphosting/localbuilds.ts
    • Imported path and EnvMap.
    • Modified localBuild to inject environment variables from EnvMap into process.env and manage NODE_PATH during the build process.
    • Added a toProcessEnv helper function for environment variable conversion.
  • src/apphosting/utils.ts
    • Imported WebConfig.
    • Added getAutoinitEnvVars to generate Firebase JS SDK auto-initialization environment variables.
  • src/deploy/apphosting/args.ts
    • Extended the LocalBuild interface to include an env array for runtime environment variables.
  • src/deploy/apphosting/deploy.spec.ts
    • Updated initializeContext to include an empty env array in LocalBuild.
    • Renamed createArchiveStub to createTarArchiveStub in tests.
    • Adjusted assertions to expect .tar.gz file extensions instead of .zip for archived sources.
  • src/deploy/apphosting/deploy.ts
    • Refactored to use util.createTarArchive instead of createArchive for source archiving.
    • Updated logging messages for clarity.
    • Added iamConfiguration with uniformBucketLevelAccess to GCS bucket creation requests.
    • Specified gcs.ContentType.TAR for uploaded objects.
  • src/deploy/apphosting/prepare.spec.ts
    • Imported managementApps.
    • Updated LocalBuild initialization to include env: [].
    • Added a test case to verify Firebase configuration injection into local build environment variables.
  • src/deploy/apphosting/prepare.ts
    • Imported several new modules for configuration and management.
    • Added a call to ensureAppHostingServiceAgentRoles.
    • Implemented logic to read apphosting.yaml for build and runtime environment variables.
    • Injected Firebase web app configuration into local build environment variables if an appId is present.
  • src/deploy/apphosting/release.ts
    • Removed the warning that local builds are not supported.
    • Updated the buildInput for orchestrateRollout to include combined build and runtime environment variables and set locallyBuiltSource: true.
  • src/deploy/apphosting/util.spec.ts
    • Added a new test file for the createTarArchive utility.
    • Included tests for archiving subdirectories and ensuring apphosting.yaml is included from the root.
  • src/deploy/apphosting/util.ts
    • Replaced the createArchive function with createTarArchive which uses the tar library to create .tar.gz archives.
    • Updated ignore patterns for archiving.
    • Added logic to include apphosting.yaml from the root directory when archiving a subdirectory.
  • src/emulator/apphosting/config.spec.ts
    • Modified test setup to explicitly set filename for AppHostingYamlConfig instances.
  • src/emulator/apphosting/config.ts
    • Simplified getLocalAppHostingConfiguration by utilizing the new getAppHostingConfiguration function.
  • src/emulator/apphosting/serve.ts
    • Imported getAutoinitEnvVars.
    • Used getAutoinitEnvVars to inject Firebase web app configuration into the environment variables for local serving.
  • src/gcp/apphosting.ts
    • Changed the API_VERSION constant from v1beta to v1alpha.
    • Added a Runtime interface and a runtime field to the Backend interface.
  • src/gcp/storage.ts
    • Made the lifecycle property optional in UpsertBucketRequest and CreateBucketRequest.
    • Added an optional iamConfiguration property to both UpsertBucketRequest and CreateBucketRequest interfaces.
    • Updated upsertBucket to patch existing buckets with iamConfiguration if needed.
  • tsconfig.json
    • Reformated the include and exclude arrays for better readability.
Activity
  • No specific activity (comments, reviews, progress updates) was provided in the context for this pull request.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

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

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 significant enhancements for Firebase App Hosting, primarily enabling local builds and deployment of the resulting artifacts. Key changes include updating the packaging format to .tar.gz, integrating the local build process, and improving environment variable handling from apphosting.yaml files for both build and runtime. The changes also include refactoring configuration loading for better reusability and enforcing stricter security on GCS buckets. My review found one medium-severity issue related to a style guide violation where as any is used as a type-casting escape hatch.

!managedBucket.iamConfiguration?.uniformBucketLevelAccess?.enabled
) {
await dynamicDispatch.patchBucket(managedBucket.name, {
iamConfiguration: opts.req.iamConfiguration as any,
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The use of as any here is an escape hatch that violates the repository's style guide, which states: "Never use any or unknown as an escape hatch. Define proper interfaces/types or use type guards." (GEMINI.md:38).

The type of opts.req.iamConfiguration from UpsertBucketRequest is not fully compatible with BucketResponse['iamConfiguration'] which is expected by patchBucket. To resolve this and improve type safety, consider defining a more specific type for the patch operation, or adjusting the existing types to be compatible.

For example, you could define a patch-specific type for iamConfiguration.

A similar issue exists on line 491.

References
  1. The style guide prohibits using any or unknown as a type escape hatch. Proper interfaces or types should be defined instead. (link)

falahat added 9 commits March 9, 2026 18:21
…ctually a local build (instead of assuming true.)
…ore strictly. We also remove some hardcoded values and we generalize the code so that it does not affect source deploys.

The goal is to prepare this PR so that we can safely submit it to main (behind the experiment flag.)
…ive. Only run it if it's a local build and the local build experiment flag is enabled.
@falahat
Copy link
Contributor Author

falahat commented Mar 13, 2026

/gemini review

Copy link
Contributor

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

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 significantly enhances App Hosting deployment by introducing support for local builds. Key changes include updating dependencies, adding a new ensureAppHostingServiceAgentRoles function to manage IAM permissions for the App Hosting service agent, and implementing splitEnvVars to categorize environment variables for build and runtime. The localBuild function now injects environment variables into process.env during the build process. The deployment flow has been updated to use .tar.gz archives for local builds, requiring the apphostinglocalbuilds experiment to be enabled. Firebase configuration is now automatically injected into local builds when an appId is present. The review comments highlight a consistent issue across multiple files where any is used in catch blocks, recommending the use of unknown with proper type checking to adhere to the style guide and improve type safety.

Comment on lines +64 to +68
} catch (e: any) {
if (e.message && !e.message.includes("doesn't exist")) {
throw e;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The style guide prohibits using any as an escape hatch. Using e: any in a catch block is unsafe. Please use e: unknown and perform a type check before accessing its properties.

Suggested change
} catch (e: any) {
if (e.message && !e.message.includes("doesn't exist")) {
throw e;
}
}
} catch (e: unknown) {
if (e instanceof Error && e.message && !e.message.includes("doesn't exist")) {
throw e;
}
}
References
  1. The repository style guide states to 'Never use any or unknown as an escape hatch. Define proper interfaces/types or use type guards.' Using any in a catch block without type checking is an example of such an escape hatch. (link)

Comment on lines +211 to +216
} catch (e) {
logLabeledWarning(
"apphosting",
`Unable to lookup details for backend ${cfg.backendId}. Firebase SDK autoinit will not be available.`,
);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The style guide prohibits using any, and implicit any in a catch block should be avoided. Please explicitly type the caught error as unknown.

Suggested change
} catch (e) {
logLabeledWarning(
"apphosting",
`Unable to lookup details for backend ${cfg.backendId}. Firebase SDK autoinit will not be available.`,
);
}
} catch (e: unknown) {
logLabeledWarning(
"apphosting",
`Unable to lookup details for backend ${cfg.backendId}. Firebase SDK autoinit will not be available.`,
);
}
References
  1. The repository style guide states to 'Never use any or unknown as an escape hatch.' An untyped catch clause results in an implicit any type, which should be avoided in favor of unknown. (link)

Comment on lines +58 to +63
} catch (err: any) {
if (err.code === "ENOENT") {
throw new FirebaseError(`Could not read directory "${rootDir}"`);
}
throw err;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The style guide prohibits using any as an escape hatch. Please use err: unknown and perform a type check before accessing properties on the error object.

Suggested change
} catch (err: any) {
if (err.code === "ENOENT") {
throw new FirebaseError(`Could not read directory "${rootDir}"`);
}
throw err;
}
} catch (err: unknown) {
if ((err as NodeJS.ErrnoException)?.code === "ENOENT") {
throw new FirebaseError(`Could not read directory "${rootDir}"`);
}
throw err;
}
References
  1. The repository style guide states to 'Never use any or unknown as an escape hatch. Define proper interfaces/types or use type guards.' Using any in a catch block without type checking is an example of such an escape hatch. (link)

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.

4 participants