Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Encapsulate runtime-dependent code #3454

Merged
merged 2 commits into from
Jun 7, 2021
Merged

Encapsulate runtime-dependent code #3454

merged 2 commits into from
Jun 7, 2021

Conversation

inlined
Copy link
Member

@inlined inlined commented Jun 5, 2021

Node JS code is now behind /deploy/functions/runtimes/node. The rest of the codebase now only interacts with the runtime through a RuntimeDelegate interface exposed in /deploy/functions/runtimes.

The following files/functions have been renamed:

from to
checkFirebaseSDKVersions.ts deploy/functions/runtimes/node/versioning.ts
deploy/functions/discovery/jsexports/* deploy/functions/runtimes/node
deploy/functions/checkRuntimeDependencies.ts deploy/functions/ensureCloudBuildEnabled.ts
deploy/functions/validate.ts deploy/functions/runtimes/node/validate.ts (Node methods only)

Some code has been refactored to be more coehsive or to remove
redundancies:

  1. All Runtime specific code from backend.ts (and functions API code + pacakge.json parser) has been deduplicated in runtimes/index.ts
  2. Multiple places loaded the current firebase-functions SDK. This is now called by the RuntimeDelegate and passed where it is needed
  3. Context no longer needs anything to do with runtimes. All Runtime-dependent code is handled in prepare
  4. prepareFunctionsUplaod did a lot more than just packaging source. It was previously getting the backend (and storing it in context so it could be reused), getting env vars, getting runtime config, etc. It now just uploads source and everything else is in prepare directly.
  5. The min-SDK version check has been moved from getRuntimeChoice() to checkFunctionsSDKVersion in versioning.ts, which always did other checks. This saved an exec to npm.

Some small fixes/improvements along the way:

  1. The log line we print when a runtime is not specified now tells customers to use the latest nodejs runtime
  2. We warn customers of breaking changes for any breaking change, not just 0.x to 1.x.

@inlined inlined requested a review from joehan June 5, 2021 01:03
@google-cla google-cla bot added the cla: yes Manual indication that this has passed CLA. label Jun 5, 2021
@@ -79,7 +78,6 @@ module.exports = new Command("deploy")
}
})
.before(checkValidTargetFilters)
.before(checkFunctionsSDKVersion)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: This check was redundant with other functions deploy code. It's now in deploy/functions/runtimes/node/index.ts:Delegate#validate

@@ -116,18 +115,6 @@ export function memoryOptionDisplayName(option: MemoryOptions): string {

export const SCHEDULED_FUNCTION_LABEL = Object.freeze({ deployment: "firebase-schedule" });

/** Supported runtimes for new Cloud Functions. */
export type Runtime = "nodejs10" | "nodejs12" | "nodejs14";
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

de-duplciated in deploy/functions/runtimes

clc.bold("npm i --save firebase-functions@latest") +
" in the functions folder.";

function functionsSDKTooOld(sourceDir: string, minRange: string): boolean {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check moved to versioning.ts

@@ -49,41 +46,6 @@ export function functionIdsAreValid(functions: { id: string }[]): void {
}
}

/**
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved to deploy/functions/runtimes/node/validate.ts

let SDKVersionStub: sinon.SinonStub;

beforeEach(() => {
cjsonStub = sandbox.stub(cjson, "load");
warningSpy = sandbox.spy(utils, "logWarning");
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These parts of tests are moved to /test/deploy/functions/runtimes/node/versioning.spec.ts


const cjson = require("cjson");

describe("validate", () => {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tests ripped from test/deploy/functions/validate.spec.ts

Node JS code is now behind /deploy/functions/runtimes/node. The rest
of the codebase now only interacts with the runtime through a
RuntimeDelegate interface exposed in /deploy/functions/runtimes.

All Runtime specific code from backend.ts (and functions API code +
pacakge.json parser) has been deduplicated in runtimes/index.ts

The following files/functions have been renamed:
checkFirebaseSDKVersions.ts -> deploy/functions/runtimes/node/versioning.ts
deploy/functions/discovery/jsexports/* -> deploy/functions/runtimes/node
deploy/functions/checkRuntimeDependencies.ts -> deploy/functions/ensureCloudBuildEnabled.ts
deploy/functions/validate.ts ->
deploy/functions/runtimes/node/validate.ts (Node methods only)

Some code has been refactored to be more coehsive or to remove
redundancies:

1. Multiple places loaded the current firebase-functions SDK. This is
   now called by the RuntimeDelegate and passed where it is needed
2. Context no longer needs anything to do with runtimes. All
   Runtime-dependent code is handled in prepare
3. prepareFunctionsUplaod did a _lot_ more than just pacakaging source.
   It was previously getting the backend (and storing it in context so
   it could be reused), getting env vars, getting runtime config, etc.
   It now just uploads source and everything else is in prepare
   direclty.
4. The min-SDK version check has been moved from getRuntimeChoice()
   to a versioning.ts:checkFunctionsSDKVersion, which always did
   other checks. This saved an exec to npm.

Some small fixes/improvements along the way:

1. The log line we print when a runtime is not specified now tells
   customers to use the latest nodejs runtime
2. We warn customers of breaking changes for any breaking change,
   not just 0.x to 1.x.
@inlined inlined force-pushed the inlined.language-specs branch from 180a16d to 5a947b3 Compare June 5, 2021 01:25
@@ -2,6 +2,7 @@ import { ReadStream } from "fs";

import * as backend from "./backend";
import * as gcfV2 from "../../gcp/cloudfunctionsv2";
import * as runtimes from "./runtimes";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused

Copy link
Contributor

@joehan joehan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, with a few test and logging nits.

): void {
const packageJsonFile = path.join(sourceDir, "package.json");
if (!fsutils.fileExistsSync(packageJsonFile)) {
const msg = `No npm package found in functions source directory. Please run 'npm init' inside ${sourceDirName}`;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this error message should recommend running npm init, for 2 reasons:

  • I think the most common cause of this would be having an incorrect functions.source listed in firebase.json
  • In general, we should push people toward using firebase init over npm init.
    I'd suggest changing this to No npm package found in functions source directory '${sourceDirName}'

await expect(checkRuntimeDependencies("test-project", runtime)).to.eventually.be.rejected;
});
});
await expect(ensureCloudBuildEnabled("test-project")).to.eventually.be.rejected;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit since you weren't really changing this code: This probably should be calling rejectedWith() and asserting that we throw an error that mentions billing. Same applies for the permissions error test

it("Should give an upgrade warning", () => {
latestVersion.returns("5.0.1");
versioning.checkFunctionsSDKVersion("5.0.0");
expect(warningSpy).to.have.been.calledWith(sinon.match("Please upgrade"));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit - This test could also assert that the breaking change warning isn't shown

@inlined inlined merged commit 0052e72 into master Jun 7, 2021
fredzqm added a commit that referenced this pull request Jun 7, 2021
devpeerapong pushed a commit to devpeerapong/firebase-tools that referenced this pull request Dec 14, 2021
Node JS code is now behind /deploy/functions/runtimes/node. The rest
of the codebase now only interacts with the runtime through a
RuntimeDelegate interface exposed in /deploy/functions/runtimes.

All Runtime specific code from backend.ts (and functions API code +
pacakge.json parser) has been deduplicated in runtimes/index.ts

The following files/functions have been renamed:
checkFirebaseSDKVersions.ts -> deploy/functions/runtimes/node/versioning.ts
deploy/functions/discovery/jsexports/* -> deploy/functions/runtimes/node
deploy/functions/checkRuntimeDependencies.ts -> deploy/functions/ensureCloudBuildEnabled.ts
deploy/functions/validate.ts ->
deploy/functions/runtimes/node/validate.ts (Node methods only)

Some code has been refactored to be more coehsive or to remove
redundancies:

1. Multiple places loaded the current firebase-functions SDK. This is
   now called by the RuntimeDelegate and passed where it is needed
2. Context no longer needs anything to do with runtimes. All
   Runtime-dependent code is handled in prepare
3. prepareFunctionsUplaod did a _lot_ more than just pacakaging source.
   It was previously getting the backend (and storing it in context so
   it could be reused), getting env vars, getting runtime config, etc.
   It now just uploads source and everything else is in prepare
   direclty.
4. The min-SDK version check has been moved from getRuntimeChoice()
   to a versioning.ts:checkFunctionsSDKVersion, which always did
   other checks. This saved an exec to npm.

Some small fixes/improvements along the way:

1. The log line we print when a runtime is not specified now tells
   customers to use the latest nodejs runtime
2. We warn customers of breaking changes for any breaking change,
   not just 0.x to 1.x.
@bkendall bkendall deleted the inlined.language-specs branch March 18, 2022 23:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes Manual indication that this has passed CLA.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants