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

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
- Fixed a crash during parallel deployments when buildConfig is empty (#9455)
- [Added] support for new google-genai plugin during `init genkit` (#8957)
- Updated to v2.17.1 of the Data Connect emulator, which fixes an admin SDK bug for operation without argument #9449 (#9454).
- Fixed "Precondition failed" error when updating GCFv2 functions in a FAILED state without code changes.
2 changes: 1 addition & 1 deletion src/deploy/functions/backend.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ describe("Backend", () => {
cpu: 1,
httpsTrigger: {},
runServiceId: HAVE_CLOUD_FUNCTION_V2.serviceConfig?.service,
source: HAVE_CLOUD_FUNCTION_V2.buildConfig.source,
source: HAVE_CLOUD_FUNCTION_V2.buildConfig?.source,
uri: HAVE_CLOUD_FUNCTION_V2.serviceConfig?.uri,
}),
);
Expand Down
2 changes: 1 addition & 1 deletion src/deploy/functions/backend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@
Triggered & {
entryPoint: string;
platform: FunctionsPlatform;
runtime: Runtime;
runtime?: Runtime;

// Output only
// "Codebase" is not part of the container contract. Instead, it's value is provided by firebase.json or derived
Expand Down Expand Up @@ -551,8 +551,8 @@
existingBackend.endpoints[endpoint.region][endpoint.id] = endpoint;
}
unreachableRegions.gcfV2 = gcfV2Results.unreachable;
} catch (err: any) {

Check warning on line 554 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unexpected any. Specify a different type
if (err.status === 404 && err.message?.toLowerCase().includes("method not found")) {

Check warning on line 555 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe call of an `any` typed value

Check warning on line 555 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe member access .message on an `any` value

Check warning on line 555 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe call of an `any` typed value

Check warning on line 555 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe member access .includes on an `any` value

Check warning on line 555 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe member access .status on an `any` value
// customer has preview enabled without allowlist set
} else {
throw err;
Expand Down
2 changes: 1 addition & 1 deletion src/deploy/functions/release/fabricator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@
try {
await fn();
this.logOpSuccess(op, endpoint);
} catch (err: any) {

Check warning on line 126 in src/deploy/functions/release/fabricator.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unexpected any. Specify a different type
result.error = err as Error;
}
result.durationMs = timer.stop();
Expand Down Expand Up @@ -232,7 +232,7 @@
}

async createV1Function(endpoint: backend.Endpoint, scraper: SourceTokenScraper): Promise<void> {
const sourceUrl = this.sources[endpoint.codebase!]?.sourceUrl;

Check warning on line 235 in src/deploy/functions/release/fabricator.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Forbidden non-null assertion
if (!sourceUrl) {
logger.debug("Precondition failed. Cannot create a GCF function without sourceUrl");
throw new Error("Precondition failed");
Expand All @@ -251,7 +251,7 @@
const op: { name: string } = await gcf.createFunction(apiFunction);
return poller.pollOperation<gcf.CloudFunction>({
...gcfV1PollerOptions,
pollerName: `create-${endpoint.codebase}-${endpoint.region}-${endpoint.id}`,

Check warning on line 254 in src/deploy/functions/release/fabricator.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Invalid type "string | undefined" of template literal expression
operationResourceName: op.name,
onPoll: scraper.poller,
});
Expand Down Expand Up @@ -288,7 +288,7 @@
}
} else if (
backend.isBlockingTriggered(endpoint) &&
AUTH_BLOCKING_EVENTS.includes(endpoint.blockingTrigger.eventType as any)

Check warning on line 291 in src/deploy/functions/release/fabricator.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe argument of type `any` assigned to a parameter of type `"providers/cloud.auth/eventTypes/user.beforeCreate" | "providers/cloud.auth/eventTypes/user.beforeSignIn" | "providers/cloud.auth/eventTypes/user.beforeSendEmail" | "providers/cloud.auth/eventTypes/user.beforeSendSms"`
) {
// Auth Blocking functions should always be public
await this.executor
Expand Down Expand Up @@ -759,7 +759,7 @@
}

logOpStart(op: string, endpoint: backend.Endpoint): void {
const runtime = RUNTIMES[endpoint.runtime].friendly;
const runtime = endpoint.runtime ? RUNTIMES[endpoint.runtime].friendly : "unknown";
const platform = getHumanFriendlyPlatformName(endpoint.platform);
const label = helper.getFunctionLabel(endpoint);
utils.logLabeledBullet(
Expand Down
2 changes: 1 addition & 1 deletion src/functions/secrets.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,7 @@ describe("functions/secret", () => {
};
const fn: Omit<gcf.CloudFunction, gcf.OutputOnlyFields> = {
name: `projects/${endpoint.project}/locations/${endpoint.region}/functions/${endpoint.id}`,
runtime: endpoint.runtime,
runtime: endpoint.runtime!,
entryPoint: endpoint.entryPoint,
secretEnvironmentVariables: [{ ...sev, version: "2" }],
};
Expand Down
2 changes: 1 addition & 1 deletion src/gcp/cloudfunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -622,7 +622,7 @@ export function functionFromEndpoint(
);
}

if (!supported.isRuntime(endpoint.runtime)) {
if (!endpoint.runtime || !supported.isRuntime(endpoint.runtime)) {
throw new FirebaseError(
"Failed internal assertion. Trying to deploy a new function with a deprecated runtime." +
" This should never happen",
Expand Down
18 changes: 18 additions & 0 deletions src/gcp/cloudfunctionsv2.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -798,6 +798,24 @@ describe("cloudfunctionsv2", () => {
}),
).to.deep.equal(expectedEndpoint);
});

it("should convert function without buildConfig", () => {
const expectedEndpoint = {
...ENDPOINT,
platform: "gcfv2",
httpsTrigger: {},
uri: GCF_URL,
entryPoint: "",
runtime: undefined,
source: undefined,
};
expect(
cloudfunctionsv2.endpointFromFunction({
...HAVE_CLOUD_FUNCTION_V2,
buildConfig: undefined,
}),
).to.deep.equal(expectedEndpoint);
});
});

describe("createFunction", () => {
Expand Down
19 changes: 10 additions & 9 deletions src/gcp/cloudfunctionsv2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export type RetryPolicy =

/** Settings for building a container out of the customer source. */
export interface BuildConfig {
runtime: supported.Runtime;
runtime?: supported.Runtime;
entryPoint: string;
source: Source;
sourceToken?: string;
Expand Down Expand Up @@ -158,7 +158,7 @@ export interface EventTrigger {
interface CloudFunctionBase {
name: string;
description?: string;
buildConfig: BuildConfig;
buildConfig?: BuildConfig;
serviceConfig?: ServiceConfig;
eventTrigger?: EventTrigger;
labels?: Record<string, string> | null;
Expand All @@ -172,6 +172,7 @@ export type OutputCloudFunction = CloudFunctionBase & {
};

export type InputCloudFunction = CloudFunctionBase & {
buildConfig: BuildConfig;
// serviceConfig is required.
serviceConfig: ServiceConfig;
};
Expand Down Expand Up @@ -228,7 +229,7 @@ function functionsOpLogReject(func: InputCloudFunction, type: string, err: any):
"Either reduce this function's maximum instances, or request a quota increase on the underlying Cloud Run service " +
"at https://cloud.google.com/run/quotas.",
);
const suggestedFix = func.buildConfig.runtime.startsWith("python")
const suggestedFix = func.buildConfig.runtime?.startsWith("python")
? "firebase_functions.options.set_global_options(max_instances=10)"
: "setGlobalOptions({maxInstances: 10})";
utils.logLabeledWarning(
Expand Down Expand Up @@ -436,7 +437,7 @@ export function functionFromEndpoint(endpoint: backend.Endpoint): InputCloudFunc
);
}

if (!supported.isRuntime(endpoint.runtime)) {
if (endpoint.runtime && !supported.isRuntime(endpoint.runtime)) {
throw new FirebaseError(
"Failed internal assertion. Trying to deploy a new function with a deprecated runtime." +
" This should never happen",
Expand All @@ -446,7 +447,7 @@ export function functionFromEndpoint(endpoint: backend.Endpoint): InputCloudFunc
const gcfFunction: InputCloudFunction = {
name: backend.functionName(endpoint),
buildConfig: {
runtime: endpoint.runtime,
runtime: endpoint.runtime || undefined,
entryPoint: endpoint.entryPoint,
source: {
storageSource: endpoint.source?.storageSource,
Expand Down Expand Up @@ -664,7 +665,7 @@ export function endpointFromFunction(gcfFunction: OutputCloudFunction): backend.
trigger = { httpsTrigger: {} };
}

if (!supported.isRuntime(gcfFunction.buildConfig.runtime)) {
if (gcfFunction.buildConfig?.runtime && !supported.isRuntime(gcfFunction.buildConfig.runtime)) {
logger.debug("GCFv2 function has a deprecated runtime:", JSON.stringify(gcfFunction, null, 2));
}

Expand All @@ -674,9 +675,9 @@ export function endpointFromFunction(gcfFunction: OutputCloudFunction): backend.
project,
region,
...trigger,
entryPoint: gcfFunction.buildConfig.entryPoint,
runtime: gcfFunction.buildConfig.runtime,
source: gcfFunction.buildConfig.source,
entryPoint: gcfFunction.buildConfig?.entryPoint || "",
runtime: gcfFunction.buildConfig?.runtime || undefined,
source: gcfFunction.buildConfig?.source,
};
if (gcfFunction.serviceConfig) {
proto.copyIfPresent(
Expand Down
2 changes: 1 addition & 1 deletion src/gcp/runv2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,7 @@ export function serviceFromEndpoint(
): Omit<Service, ServiceOutputFields> {
const labels: Record<string, string> = {
...endpoint.labels,
[RUNTIME_LABEL]: endpoint.runtime,
...(endpoint.runtime ? { [RUNTIME_LABEL]: endpoint.runtime } : {}),
[CLIENT_NAME_LABEL]: "firebase-functions",
};

Expand Down
Loading