diff --git a/CHANGELOG.md b/CHANGELOG.md index e69de29bb2d..f23b5e79a96 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -0,0 +1,4 @@ +- Validate task queue function names at deploy time, since Cloud Tasks queue IDs (derived from the function name) cannot contain underscores (#7365). +- Add `MCP-Protocol-Version`, `Mcp-Method`, and `Mcp-Name` HTTP headers to `OneMcpServer` requests per the MCP 0728 standard release candidate (https://blog.modelcontextprotocol.io/posts/2026-07-28-release-candidate/ and https://modelcontextprotocol.io/seps/2243-http-standardization). +- Fixes Storage Emulator to support JSON uploads larger than 100KB without hanging or throwing 413 error (#8355) +- Add `extdeprecationwarnings` experiment to display phased deprecation notices and guidance across `ext:*` CLI commands. diff --git a/src/deploy/functions/validate.spec.ts b/src/deploy/functions/validate.spec.ts index 165317a106b..6711eafde6f 100644 --- a/src/deploy/functions/validate.spec.ts +++ b/src/deploy/functions/validate.spec.ts @@ -114,6 +114,43 @@ describe("validate", () => { }); }); + describe("taskQueueFunctionNamesAreValid", () => { + const ENDPOINT_BASE: backend.Endpoint = { + platform: "gcfv2", + id: "id", + region: "us-east1", + project: "project", + entryPoint: "id", + runtime: "nodejs16", + httpsTrigger: {}, + }; + + it("should not throw on hyphenated task queue function names", () => { + const endpoints: backend.Endpoint[] = [ + { ...ENDPOINT_BASE, id: "my-task-function", taskQueueTrigger: {} }, + ]; + expect(() => { + validate.taskQueueFunctionNamesAreValid(endpoints); + }).to.not.throw(); + }); + + it("should throw on underscores in task queue function names", () => { + const endpoints: backend.Endpoint[] = [ + { ...ENDPOINT_BASE, id: "dummy_function", taskQueueTrigger: {} }, + ]; + expect(() => { + validate.taskQueueFunctionNamesAreValid(endpoints); + }).to.throw(FirebaseError, /dummy_function/); + }); + + it("should ignore underscores in non-task-queue function names", () => { + const endpoints: backend.Endpoint[] = [{ ...ENDPOINT_BASE, id: "dummy_function" }]; + expect(() => { + validate.taskQueueFunctionNamesAreValid(endpoints); + }).to.not.throw(); + }); + }); + describe("endpointsAreValid", () => { const ENDPOINT_BASE: backend.Endpoint = { platform: "gcfv2", diff --git a/src/deploy/functions/validate.ts b/src/deploy/functions/validate.ts index 14efb258f4a..14e5523e00f 100644 --- a/src/deploy/functions/validate.ts +++ b/src/deploy/functions/validate.ts @@ -91,6 +91,7 @@ export function endpointsAreValid( validateLifecycleHooks(wantBackend, existingBackend); const endpoints = backend.allEndpoints(wantBackend); functionIdsAreValid(endpoints); + taskQueueFunctionNamesAreValid(endpoints); validateTimeoutConfig(endpoints); for (const ep of endpoints) { validateScheduledTimeout(ep); @@ -329,6 +330,27 @@ export function functionIdsAreValid(functions: { id: string; platform: string }[ } } +/** + * Validate that task queue function names conform to Cloud Tasks queue ID naming rules. + * Unlike Cloud Functions, Cloud Tasks queue IDs (which we derive from the function name) + * cannot contain underscores. See + * https://cloud.google.com/tasks/docs/reference/rest/v2/projects.locations.queues#Queue + * @throws { FirebaseError } Task queue function names must be valid Cloud Tasks queue IDs. + */ +export function taskQueueFunctionNamesAreValid(endpoints: backend.Endpoint[]): void { + const queueId = /^[a-zA-Z0-9-]{1,100}$/; + const invalidIds = endpoints + .filter(backend.isTaskQueueTriggered) + .filter((ep) => !queueId.test(ep.id)); + if (invalidIds.length !== 0) { + const msg = + `${invalidIds.map((f) => f.id).join(", ")} task queue function name(s) can only contain ` + + `letters, numbers, and hyphens (no underscores), and not exceed 100 characters in length. ` + + `This is because the function's name is used as the Cloud Tasks queue ID.`; + throw new FirebaseError(msg); + } +} + /** * Validate secret environment variables setting, if any. * A bad secret configuration can lead to a significant delay in function deploys.