Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions kits/storage-resize-images/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
- fix: remove `europe-north2` and `northamerica-south1` from the `BUCKET_REGION` options. Cloud Functions has no location in either, so choosing one failed the deploy with `Location europe-north2 is not found or access is unauthorized.` The Firebase CLI only lets a function listen to a regional bucket from the same region, so the kit cannot serve a bucket in either region. Setting either in `.env` now throws an error saying so when the functions load.

- fix: `generateResizedImage` now handles one event per instance, as the extension's 1st gen trigger did, and sizes its CPU from `FUNCTION_MEMORY` the 1st gen way. Left unset, the Firebase CLI deployed it with 1 vCPU and a concurrency of 80, so a burst of uploads landed on a single instance and every resize shared its CPU. With 80 large images uploaded at once, 58 requests reached the 60s timeout and 56 images were never resized: the trigger has no retry policy, the timeouts were logged as HTTP 200 at INFO severity, and no `onError` event or failed-image copy was written. The next deploy updates the function in place; no `.env` change is needed.

- fix: an Eventarc publish failure no longer fails the function. A channel that was deleted or is unreachable answers `PERMISSION_DENIED`, and the publish was awaited before the work the function exists to do, so the image was never resized. The publish failure is now logged as a warning and the invocation continues. Deploys also declare `eventarcpublishing.googleapis.com`, so the API is enabled on your project whether or not you use events.
Expand Down
4 changes: 4 additions & 0 deletions kits/storage-resize-images/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,10 @@ inside them - `us` to `us-east1`, `eu` to `europe-west1`, `asia` to
`asia-east1` - because they are not Cloud Run regions themselves and would fail
the deploy. The value is matched case-insensitively.

Cloud Functions has no location in `europe-north2` or `northamerica-south1`, so
the kit can't serve a bucket there. The extension can: keep using it, or move to
a listed region.

Dual-region buckets (`nam4`, `eur4`, `asia1`) are not offered as such and are
not mapped. Pick one of the regions the pair is made of instead, all of which
are in the list: `us-central1` or `us-east1` for `nam4`, `europe-north1` or
Expand Down
2 changes: 0 additions & 2 deletions kits/storage-resize-images/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ const params = {
"Dallas (us-south1)": "us-south1",
"Montreal (northamerica-northeast1)": "northamerica-northeast1",
"Toronto (northamerica-northeast2)": "northamerica-northeast2",
"Queretaro (northamerica-south1)": "northamerica-south1",
"Sao Paulo (southamerica-east1)": "southamerica-east1",
"Santiago (southamerica-west1)": "southamerica-west1",
"Belgium (europe-west1)": "europe-west1",
Expand All @@ -82,7 +81,6 @@ const params = {
"Turin (europe-west12)": "europe-west12",
"Madrid (europe-southwest1)": "europe-southwest1",
"Finland (europe-north1)": "europe-north1",
Comment thread
IzaakGough marked this conversation as resolved.
"Stockholm (europe-north2)": "europe-north2",
"Warsaw (europe-central2)": "europe-central2",
"Doha (me-central1)": "me-central1",
"Dammam (me-central2)": "me-central2",
Expand Down
13 changes: 12 additions & 1 deletion kits/storage-resize-images/src/region.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,18 @@ const MULTI_REGION_TO_FUNCTION_REGION: Record<string, string> = {
asia: "asia-east1",
};

// Cloud Functions has no location in these, and a 2nd gen storage trigger
// cannot cross regions. The CLI does not check `.env` values against the
// BUCKET_REGION options, so a hand-written one must be rejected here.
const UNSUPPORTED_LOCATIONS = ["europe-north2", "northamerica-south1"];

/**
* Maps a Cloud Storage bucket location to the Cloud Run region the functions
* should deploy to. The lookup is case-insensitive and ignores surrounding
* whitespace, as the CLI's own region handling is. Regional locations pass
* through lowercased; an unset or blank location returns `undefined`, meaning
* the functions declare no region.
* the functions declare no region. Throws for a location Cloud Functions
* cannot serve.
*
* Dual-region locations (`nam4`, `eur4`, `asia1`, ...) are not mapped and pass
* through, which fails the deploy. firebase-tools has the same gap, so a
Expand All @@ -45,5 +51,10 @@ export function bucketLocationToFunctionRegion(
if (!normalized) {
return undefined;
}
if (UNSUPPORTED_LOCATIONS.includes(normalized)) {
throw new Error(
`BUCKET_REGION ${normalized} is not supported: Cloud Functions has no location there, so the kit cannot serve a bucket in it.`
);
}
return MULTI_REGION_TO_FUNCTION_REGION[normalized] ?? normalized;
}
21 changes: 21 additions & 0 deletions kits/storage-resize-images/tests/function-region.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/

import { afterEach, describe, expect, test } from "vitest";
import { declaredParams } from "firebase-functions/params";

import { envFunctionRegion } from "../src/config";

Expand Down Expand Up @@ -60,3 +61,23 @@ describe("envFunctionRegion function region", () => {
expect(envFunctionRegion()).toBeUndefined();
});
});

describe("BUCKET_REGION options", () => {
test.each(["europe-north2", "northamerica-south1"])(
Comment thread
IzaakGough marked this conversation as resolved.
"do not offer %s, which has no Cloud Functions location",
(region) => {
const declaration = (
declaredParams as unknown as {
name: string;
options?: { input?: { select?: { options: { value: string }[] } } };
}[]
).find((param) => param.name === "BUCKET_REGION");
const values = declaration?.options?.input?.select?.options.map(
(option) => option.value
);
Comment thread
IzaakGough marked this conversation as resolved.

expect(values).toContain("europe-north1");
expect(values).not.toContain(region);
}
);
});
9 changes: 9 additions & 0 deletions kits/storage-resize-images/tests/region.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,15 @@ describe("bucketLocationToFunctionRegion", () => {
expect(bucketLocationToFunctionRegion(location)).toBe(region);
});

test.each(["europe-north2", "northamerica-south1", " Europe-North2 "])(
"rejects %s, which has no Cloud Functions location",
(location) => {
expect(() => bucketLocationToFunctionRegion(location)).toThrow(
/Cloud Functions has no location there/
);
}
);

test("lowercases and trims a regional location", () => {
expect(bucketLocationToFunctionRegion(" Europe-West2 ")).toBe(
"europe-west2"
Expand Down
Loading