fix: normalize GCF v2 IDs loaded from Cloud Run services - #10910
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces ID normalization for GCF v2 services in src/gcp/runv2.ts by replacing dots with dashes to match GCF v2 API behavior and prevent duplicate endpoints, alongside adding comprehensive unit tests in src/gcp/runv2.spec.ts. The review feedback recommends handling cases where rawId might be undefined to ensure strict null safety and prevent potential runtime TypeErrors.
85dc512 to
0df8948
Compare
…dots only)
### Description
Fixes an issue where GCF v2 functions with dots in their names (which GCF normalizes to dashes) were incorrectly flagged for deletion during deployments when the `dartfunctions` or `functionsrunapionly` experiments were enabled.
**The Bug:**
When loading the existing state of a project, the GCF V2 API returns function IDs with dashes (e.g. `v2-helloWorldNode`). However, if the experiments are enabled, the CLI also queries the Cloud Run API to check for missing services. It parses the ID from the service annotations, which preserves the original name with dots (e.g. `v2.helloWorldNode`). Because of this mismatch, the CLI loaded both as separate duplicate endpoints in `existingBackend`. The planner then flagged the dot-version for deletion while planning to update the dash-version.
**How to Reproduce:**
1. Enable the `dartfunctions` experiment: `firebase experiments:enable dartfunctions`
2. Define a nested GCF v2 function (e.g. `exports.v2 = { helloWorldNode: ... }`), which has the logical ID `v2.helloWorldNode`.
3. Deploy the function: `firebase deploy --only functions` (it will be created in GCP as `v2-helloWorldNode`).
4. Run another deployment: `firebase deploy --only functions`.
5. Observe that the CLI prompts to delete `v2.helloWorldNode` while also updating `v2-helloWorldNode`.
**The Fix:**
Normalized GCF v2 IDs loaded from Cloud Run services to replace dots (`.`) with dashes (`-`), matching GCF V2 API behavior. Underscores (`_`) are preserved because GCF v2 natively supports them. We do not normalize for `"run"` platform services (like Dart functions) because their local specs do not undergo GCF-style normalization.
### Scenarios Tested
- Verified all tests pass
- Verified bad behavior happens only when dartfunctions experiment is on (and presumably runfunctionsonly)
- Manually tested deploys creating, updating, and deleting with and without this change using a function in code as "v2.helloWorld" (and some others)
### Sample Commands
`npm run test`
`firebase deploy --only functions` (with and without additional filters)
TAG=agy
CONV=ca939fe8-e463-44c5-b6ae-7a50e7b4599a
0df8948 to
74883a9
Compare
inlined
left a comment
There was a problem hiding this comment.
It might be worth improving comments a bit.
It sounds like we're NOT finding FUNCTION_ID_ANNOTATION but we ARE finding FUNCTIN_TARGET_ANNOTATION, and in the case of function groups specifically those are not the same thing.
It's also not entirely clear why you have to conditionally replace.
|
I will probably abandon this PR because I think the Run API will be fixed instead. Leaving it open till that's verified. That said.
I'm replacing for gcfv2 only because that's the only case where we're reconciling between the two. If we're only using cloud run (the dart case) the rawID is the only one we have and use. There is a different bug that right now you can only reference Dart functions by the renamed method so if we turn |
Description
Fixes an issue where GCF v2 functions with dots in their names (which GCF normalizes to dashes) were incorrectly flagged for deletion during deployments when the
dartfunctionsorfunctionsrunapionlyexperiments were enabled.The Bug:
When loading the existing state of a project, the GCF V2 API returns function IDs with dashes (e.g.
v2-helloWorldNode). However, if the experiments are enabled, the CLI also queries the Cloud Run API to check for missing services. It parses the ID from the service annotations, which preserves the original name with dots (e.g.v2.helloWorldNode). Because of this mismatch, the CLI loaded both as separate duplicate endpoints inexistingBackend. The planner then flagged the dot-version for deletion while planning to update the dash-version.How to Reproduce:
dartfunctionsexperiment:firebase experiments:enable dartfunctionsexports.v2 = { helloWorldNode: ... }), which has the logical IDv2.helloWorldNode.firebase deploy --only functions(it will be created in GCP asv2-helloWorldNode).firebase deploy --only functions.v2.helloWorldNodewhile also updatingv2-helloWorldNode.The Fix:
Normalized GCF v2 IDs loaded from Cloud Run services to replace dots (
.) with dashes (-), matching GCF V2 API behavior. Underscores (_) are preserved because GCF v2 natively supports them. We do not normalize for"run"platform services (like Dart functions) because their local specs do not undergo GCF-style normalization.Scenarios Tested
Sample Commands
npm run testfirebase deploy --only functions(with and without additional filters)TAG=agy
CONV=ca939fe8-e463-44c5-b6ae-7a50e7b4599a