Skip to content

feat: support Task lifecycle hooks in functions#10728

Open
wandamora wants to merge 14 commits into
mainfrom
morawand-cf3-lifecycle-hooks
Open

feat: support Task lifecycle hooks in functions#10728
wandamora wants to merge 14 commits into
mainfrom
morawand-cf3-lifecycle-hooks

Conversation

@wandamora

@wandamora wandamora commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Description

This PR introduces support for Cloud Functions (CF3) lifecycle hooks, allowing developers to run actions after deployment events. This only supports Task Queue hooks. Execution of Callable and HTTP hooks will be implemented in a future CL.

The implementation spans:

  1. Manifest & Discovery Parsing: Parses lifecycleHooks config from the generated functions build manifest/metadata. Support is added to define task (Task Queue functions), call (Callable functions), and http (HTTP functions or custom URLs) hooks.
  2. Release Execution Flow: During deployment release, the CLI compares the codebase's current status and target backend configurations to determine if a deploy is a fresh install (afterInstall hook target) or a subsequent update (afterUpdate hook target).
  3. Task Queue Hook Execution & Authentication: Integrates with Cloud Tasks (cloudtasks.ts) to enqueue tasks targeting hook functions. Resolves the service account to attach an oidcToken so that invocations are securely authenticated.
  4. Validation & Prefixing:
    • Validates that target endpoints exist in the backend, match expected triggers (e.g., task hook targeting a task queue function), and are GCF Gen 2 functions.
    • Supports codebase prefixing for target functions in multi-codebase setups.
  5. Logging: Logs a Google Cloud Console log viewer link to easily monitor hook function execution.

Scenarios Tested

  • Verified afterInstall only deploys for new codebases
  • Verified afterUpdate only deploys for any changes in the codebase
  • Verified that error is thrown if either hook is declared more than once
  • Verified task queues are dispatched correctly
  • Verified hooks are removed upon deletion
  • Verified hooks in multiple codebases depend on their respective codebases
  • Verified log URLs are correctly output on success

@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 support for GCF Gen 2 lifecycle hooks (afterInstall and afterUpdate) in Firebase Functions deployments, including manifest parsing, backend validation, and execution of task queue hooks via Cloud Tasks. The review feedback highlights several critical issues: a type mismatch when calling getProjectNumber, a logic bug in codebase filtering that causes hooks to be skipped for the default codebase, validation failures during partial deployments, a potential runtime TypeError when parsing null lifecycle hooks, and the silent skipping of unsupported callable and http hooks during execution.

Comment thread src/deploy/functions/release/lifecycle.ts Outdated
Comment thread src/deploy/functions/release/lifecycle.ts
Comment thread src/deploy/functions/validate.ts Outdated
Comment thread src/deploy/functions/runtimes/discovery/v1alpha1.ts Outdated
Comment thread src/deploy/functions/release/lifecycle.ts Outdated
@wandamora wandamora force-pushed the morawand-cf3-lifecycle-hooks branch from f688cf8 to f1e0350 Compare June 26, 2026 21:30
@wandamora wandamora changed the title feat: support Cloud Functions lifecycle hooks feat: support Task lifecycle hooks in functions Jun 29, 2026
@wandamora wandamora marked this pull request as ready for review June 29, 2026 14:26
@wandamora wandamora requested review from ajperel and inlined June 29, 2026 14:38

@inlined inlined left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Done with a pass. Nothing foundational needs to be changed and I'm off today, so I'm LGTMing

const wantBackend = backend.merge(...Object.values(payload.functions).map((p) => p.wantBackend));
printTriggerUrls(wantBackend, projectNumber);

for (const [codebase, { wantBackend: w, haveBackend: h }] of Object.entries(payload.functions)) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Printing URLs should probably be at the end users don't have to dig through the output to get them

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

AFAICT this already does? At least it was for when I was deploying functions in a test project.

Comment thread src/deploy/functions/release/lifecycle.spec.ts Outdated
Comment thread src/deploy/functions/release/lifecycle.ts
Comment thread src/deploy/functions/release/lifecycle.ts Outdated
Comment thread src/deploy/functions/release/lifecycle.ts
backendSpec: backend.Backend,
targetId: string,
): backend.Endpoint | undefined {
for (const endpoint of backend.allEndpoints(backendSpec)) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Was just looking up the backend utility method (findEndpoint) and realized that there's an edge case we're not handling here where there may be multiple functions with the same name in different regions. Though I guess that shouldn't be a problem for task queue functions (HTTP functions can trigger this by specifying multiple regions)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Should we address that in a separate CL? This seems like a non-blocking issue for this CL.

Comment thread src/deploy/functions/backend.ts Outdated
Comment thread src/deploy/functions/validate.spec.ts Outdated
Comment thread src/deploy/functions/validate.spec.ts
Comment thread src/gcp/cloudtasks.ts
@wandamora wandamora force-pushed the morawand-cf3-lifecycle-hooks branch 2 times, most recently from 1da9c0e to b2c6ec6 Compare June 29, 2026 19:53
- Add explanatory comments
- Update logging
- Change LifecycleHook to union type
- Add assertExhaustive checks
- Update project number detection
@wandamora wandamora force-pushed the morawand-cf3-lifecycle-hooks branch from b2c6ec6 to dbe17dd Compare June 29, 2026 21:20
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.

3 participants