Skip to content

Commit

Permalink
super secret totally not related to any event updates (#4536)
Browse files Browse the repository at this point in the history
* Un-hide CF3v2 (#4525)

* Resolve relative paths for local extensions (#4529)

* Improve error message when parsing function source fails. (#4527)

Previously, an invalid function source would show error message like this:

```bash
$ firebase deploy --only functions

i  deploying functions
...
Error: Failed to parse backend specification:
- YAMLException incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line at line 1, column 65:
     ...  function source: ReferenceError: aa is not defined
```

This is surprising - a YAMLException? A backend specification? Often times, the full error message would curt short, and debugging the issue required the user to carefully inspect the debug log.

We improve the error message to the following:

```bash
$ firebase deploy --only functions

i  deploying functions
...
Error: Failed to load function definition from source: Failed to generate manifest from function source: ReferenceError: aa is not defined
```

We hid the YAML portion of the error and make sure to relay the full error message returned from the underlying Functions Control API (i.e. the serve responsible for loading and advertising the `functions.yaml` baked into the Functions SDK)

* Set `enableCors` debug feature when emulating CF3 functions. (#4528)

Accompanies firebase/firebase-functions#1099.

With this change, users using the supported version of the Firebase Functions SDK will be able to bypass existing/default cors settings to call the emulated HTTP/callable v2 functions.

* Removing extensions-emulator preview flag (#4484)

* Removing extensions-emulator preview flag

* fix test

* Adding changelog entry

* formats

* Pin to emulator UI v1.7.0

* Fix outdated package.json templates (#4531)

* Remove firebase-functions-test dependency

* Bump all the dependencies

* Inlined.cpu fixes (#4530)

* Add extra validation for CPU x memory constraints

* Force default memory to avoid MB -> MiB bugs

* Unbreak unit tests

* Adding CHANGELOG entry for cf3v2 (#4537)

* Adding CHANGELOG entry for cf3v2

* gen 2

* More firebase-frameworks work (#4463)

* Work with emulators:start

* Add dev mode flag

* Dev flag not actually needed

* Move entry into firebase-tools

* Cleanup

* Bump dep

* fix missing import

Co-authored-by: Bryan Kendall <bkend@google.com>

Co-authored-by: Thomas Bouldin <inlined@users.noreply.github.com>
Co-authored-by: joehan <joehanley@google.com>
Co-authored-by: Daniel Lee <danielylee@google.com>
Co-authored-by: James Daniels <jamesdaniels@google.com>
  • Loading branch information
5 people committed May 10, 2022
2 parents 3522dd7 + 745e167 commit 20039d2
Show file tree
Hide file tree
Showing 29 changed files with 617 additions and 290 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
@@ -0,0 +1,2 @@
- Adds Firebase Extensions emulator. Learn more about how to test Extensions in the Emulator Suite here: https://firebase.google.com/docs/extensions/manifest.
- Adds support for Cloud Functions for Firebase gen 2.
108 changes: 101 additions & 7 deletions npm-shrinkwrap.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -107,7 +107,7 @@
"exit-code": "^1.0.2",
"express": "^4.16.4",
"filesize": "^6.1.0",
"firebase-frameworks": "^0.3.0",
"firebase-frameworks": "^0.4.0",
"fs-extra": "^5.0.0",
"glob": "^7.1.2",
"google-auth-library": "^7.11.0",
Expand Down
1 change: 0 additions & 1 deletion scripts/extensions-emulator-tests/run.sh
Expand Up @@ -8,5 +8,4 @@ source scripts/set-default-credentials.sh
npm install
)

firebase --open-sesame extensionsemulator
mocha scripts/extensions-emulator-tests/tests.ts
32 changes: 12 additions & 20 deletions src/commands/functions-list.ts
Expand Up @@ -5,7 +5,6 @@ import { needProjectId } from "../projectUtils";
import { Options } from "../options";
import { requirePermissions } from "../requirePermissions";
import * as backend from "../deploy/functions/backend";
import { previews } from "../previews";
import { logger } from "../logger";
import Table = require("cli-table");

Expand All @@ -19,28 +18,21 @@ export default new Command("functions:list")
} as args.Context;
const existing = await backend.existingBackend(context);
const endpointsList = backend.allEndpoints(existing).sort(backend.compareFunctions);
const table = previews.functionsv2
? new Table({
head: ["Function", "Version", "Trigger", "Location", "Memory", "Runtime"],
style: { head: ["yellow"] },
})
: new Table({
head: ["Function", "Trigger", "Location", "Memory", "Runtime"],
style: { head: ["yellow"] },
});
const table = new Table({
head: ["Function", "Version", "Trigger", "Location", "Memory", "Runtime"],
style: { head: ["yellow"] },
});
for (const endpoint of endpointsList) {
const trigger = backend.endpointTriggerType(endpoint);
const availableMemoryMb = endpoint.availableMemoryMb || "---";
const entry = previews.functionsv2
? [
endpoint.id,
endpoint.platform === "gcfv2" ? "v2" : "v1",
trigger,
endpoint.region,
availableMemoryMb,
endpoint.runtime,
]
: [endpoint.id, trigger, endpoint.region, availableMemoryMb, endpoint.runtime];
const entry = [
endpoint.id,
endpoint.platform === "gcfv2" ? "v2" : "v1",
trigger,
endpoint.region,
availableMemoryMb,
endpoint.runtime,
];
table.push(entry);
}
logger.info(table.toString());
Expand Down
5 changes: 0 additions & 5 deletions src/deploy/functions/backend.ts
Expand Up @@ -6,7 +6,6 @@ import * as utils from "../../utils";
import * as runtimes from "./runtimes";
import { FirebaseError } from "../../error";
import { Context } from "./args";
import { previews } from "../../previews";
import { flattenArray, zip } from "../../functional";

/** Retry settings for a ScheduleSpec. */
Expand Down Expand Up @@ -525,10 +524,6 @@ async function loadExistingBackend(ctx: Context & PrivateContextFields): Promise
}
ctx.unreachableRegions.gcfV1 = gcfV1Results.unreachable;

if (!previews.functionsv2) {
return;
}

let gcfV2Results;
try {
gcfV2Results = await gcfV2.listAllFunctions(ctx.projectId);
Expand Down
11 changes: 0 additions & 11 deletions src/deploy/functions/prepare.ts
Expand Up @@ -148,17 +148,6 @@ export async function prepare(
);
}
if (backend.someEndpoint(wantBackend, (e) => e.platform === "gcfv2")) {
if (!previews.functionsv2) {
throw new FirebaseError(
"This version of firebase-tools does not support Google Cloud " +
"Functions gen 2\n" +
"If Cloud Functions for Firebase gen 2 is still in alpha, sign up " +
"for the alpha program at " +
"https://services.google.com/fb/forms/firebasealphaprogram/\n" +
"If Cloud Functions for Firebase gen 2 is in beta, get the latest " +
"version of Firebse Tools with `npm i -g firebase-tools@latest`"
);
}
source.functionsSourceV2 = await prepareFunctionsUpload(sourceDir, config);
}
if (backend.someEndpoint(wantBackend, (e) => e.platform === "gcfv1")) {
Expand Down
5 changes: 3 additions & 2 deletions src/deploy/functions/runtimes/discovery/index.ts
Expand Up @@ -60,7 +60,7 @@ export async function detectFromPort(
port: number,
project: string,
runtime: runtimes.Runtime,
timeout: number = 30_000 /* 30s to boot up */
timeout = 30_000 /* 30s to boot up */
): Promise<backend.Backend> {
// The result type of fetch isn't exported
let res: { text(): Promise<string> };
Expand Down Expand Up @@ -90,7 +90,8 @@ export async function detectFromPort(
try {
parsed = yaml.load(text);
} catch (err: any) {
throw new FirebaseError("Failed to parse backend specification", { children: [err] });
logger.debug("Failed to parse functions.yaml", err);
throw new FirebaseError(`Failed to load function definition from source: ${text}`);
}

return yamlToBackend(parsed, project, api.functionsDefaultRegion, runtime);
Expand Down
78 changes: 37 additions & 41 deletions src/deploy/functions/runtimes/node/index.ts
Expand Up @@ -9,7 +9,6 @@ import fetch from "node-fetch";
import { FirebaseError } from "../../../../error";
import { getRuntimeChoice } from "./parseRuntimeAndValidateSDK";
import { logger } from "../../../../logger";
import { previews } from "../../../../previews";
import { logLabeledWarning } from "../../../../utils";
import * as backend from "../../backend";
import * as build from "../../build";
Expand Down Expand Up @@ -128,48 +127,45 @@ export class Delegate {
config: backend.RuntimeConfigValues,
env: backend.EnvironmentVariables
): Promise<backend.Backend> {
if (previews.functionsv2) {
if (!semver.valid(this.sdkVersion)) {
logger.debug(
`Could not parse firebase-functions version '${this.sdkVersion}' into semver. Falling back to parseTriggers.`
);
return parseTriggers.discoverBackend(
this.projectId,
this.sourceDir,
this.runtime,
config,
env
);
}
if (semver.lt(this.sdkVersion, MIN_FUNCTIONS_SDK_VERSION)) {
logLabeledWarning(
"functions",
`You are using an old version of firebase-functions SDK (${this.sdkVersion}). ` +
`Please update firebase-functions SDK to >=${MIN_FUNCTIONS_SDK_VERSION}`
);
return parseTriggers.discoverBackend(
this.projectId,
this.sourceDir,
this.runtime,
config,
env
);
}
let discovered = await discovery.detectFromYaml(this.sourceDir, this.projectId, this.runtime);
if (!discovered) {
const getPort = promisify(portfinder.getPort) as () => Promise<number>;
const port = await getPort();
const kill = await this.serve(port, env);
try {
discovered = await discovery.detectFromPort(port, this.projectId, this.runtime);
} finally {
await kill();
}
if (!semver.valid(this.sdkVersion)) {
logger.debug(
`Could not parse firebase-functions version '${this.sdkVersion}' into semver. Falling back to parseTriggers.`
);
return parseTriggers.discoverBackend(
this.projectId,
this.sourceDir,
this.runtime,
config,
env
);
}
if (semver.lt(this.sdkVersion, MIN_FUNCTIONS_SDK_VERSION)) {
logLabeledWarning(
"functions",
`You are using an old version of firebase-functions SDK (${this.sdkVersion}). ` +
`Please update firebase-functions SDK to >=${MIN_FUNCTIONS_SDK_VERSION}`
);
return parseTriggers.discoverBackend(
this.projectId,
this.sourceDir,
this.runtime,
config,
env
);
}
let discovered = await discovery.detectFromYaml(this.sourceDir, this.projectId, this.runtime);
if (!discovered) {
const getPort = promisify(portfinder.getPort) as () => Promise<number>;
const port = await getPort();
const kill = await this.serve(port, env);
try {
discovered = await discovery.detectFromPort(port, this.projectId, this.runtime);
} finally {
await kill();
}
discovered.environmentVariables = env;
return discovered;
}
return parseTriggers.discoverBackend(this.projectId, this.sourceDir, this.runtime, config, env);
discovered.environmentVariables = env;
return discovered;
}

// eslint-disable-next-line require-await
Expand Down

0 comments on commit 20039d2

Please sign in to comment.