Skip to content
This repository has been archived by the owner on Dec 9, 2024. It is now read-only.

Adding support for nodejs20 #683

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
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
4 changes: 2 additions & 2 deletions .github/workflows/integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:

strategy:
matrix:
node-version: [12, 14, 16, 18]
node-version: [12, 14, 16, 18, 20]
os: [linux, windows]
fail-fast: false

Expand Down Expand Up @@ -73,7 +73,7 @@ jobs:
strategy:
matrix:
runtime: [python36, python37, python38]
node-version: [12, 14, 16, 18]
node-version: [12, 14, 16, 18, 20]
os: [linux, windows]
fail-fast: false

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
validate:
strategy:
matrix:
version: [12, 14, 16, 18]
version: [12, 14, 16, 18, 20]
os: [ubuntu-latest, windows-latest]

runs-on: ${{ matrix.os }}
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
"js-yaml": "^3.13.1",
"jsonpath": "^1.0.1",
"md5": "^2.2.1",
"memfs": "^4.9.1",
"open": "^6.3.0",
"querystring": "^0.2.0",
"request": "^2.81.0",
Expand Down Expand Up @@ -90,7 +91,7 @@
"jest": "^24.8.0",
"jest-cli": "^24.8.0",
"jest-os-detection": "^1.1.1",
"mock-fs": "^4.10.0",
"mock-fs": "^4.14.0",
"mock-spawn": "^0.2.6",
"serverless": "^1.44.1",
"shx": "^0.3.2",
Expand Down
17 changes: 17 additions & 0 deletions src/armTemplates/resources/functionApp.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,23 @@ describe("Function App Resource", () => {
expect(functionAppNodeVersion.value).toEqual("~18");
});

it("gets correct parameters - node 20", () => {
const config = getConfig(FunctionAppOS.LINUX, Runtime.NODE20);

const resource = new FunctionAppResource();

const params = resource.getParameters(config);
const {
linuxFxVersion,
functionAppNodeVersion,
} = params;

assertLinuxParams(params);

expect(linuxFxVersion.value).toEqual("NODE|20");
expect(functionAppNodeVersion.value).toEqual("~20");
});

it("gets correct parameters - python 3.6", () => {
const config = getConfig(FunctionAppOS.LINUX, Runtime.PYTHON36);

Expand Down
5 changes: 5 additions & 0 deletions src/config/runtime.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ describe("Runtime", () => {
expect(isNodeRuntime(Runtime.NODE14)).toBe(true);
expect(isNodeRuntime(Runtime.NODE16)).toBe(true);
expect(isNodeRuntime(Runtime.NODE18)).toBe(true);
expect(isNodeRuntime(Runtime.NODE20)).toBe(true);
expect(isNodeRuntime(Runtime.PYTHON36)).toBe(false);
expect(isNodeRuntime(Runtime.PYTHON37)).toBe(false);
expect(isNodeRuntime(Runtime.PYTHON38)).toBe(false);
Expand All @@ -19,6 +20,7 @@ describe("Runtime", () => {
expect(isPythonRuntime(Runtime.NODE14)).toBe(false);
expect(isPythonRuntime(Runtime.NODE16)).toBe(false);
expect(isPythonRuntime(Runtime.NODE18)).toBe(false);
expect(isPythonRuntime(Runtime.NODE20)).toBe(false);
expect(isPythonRuntime(Runtime.PYTHON36)).toBe(true);
expect(isPythonRuntime(Runtime.PYTHON37)).toBe(true);
expect(isPythonRuntime(Runtime.PYTHON38)).toBe(true);
Expand All @@ -30,6 +32,7 @@ describe("Runtime", () => {
expect(getRuntimeVersion(Runtime.NODE14)).toBe("14");
expect(getRuntimeVersion(Runtime.NODE16)).toBe("16");
expect(getRuntimeVersion(Runtime.NODE18)).toBe("18");
expect(getRuntimeVersion(Runtime.NODE20)).toBe("20");
expect(getRuntimeVersion(Runtime.PYTHON36)).toBe("3.6");
expect(getRuntimeVersion(Runtime.PYTHON37)).toBe("3.7");
expect(getRuntimeVersion(Runtime.PYTHON38)).toBe("3.8");
Expand All @@ -47,6 +50,7 @@ describe("Runtime", () => {
expect(getRuntimeLanguage(Runtime.NODE14)).toBe("nodejs");
expect(getRuntimeLanguage(Runtime.NODE16)).toBe("nodejs");
expect(getRuntimeLanguage(Runtime.NODE18)).toBe("nodejs");
expect(getRuntimeLanguage(Runtime.NODE20)).toBe("nodejs");
expect(getRuntimeLanguage(Runtime.PYTHON36)).toBe("python");
expect(getRuntimeLanguage(Runtime.PYTHON37)).toBe("python");
expect(getRuntimeLanguage(Runtime.PYTHON38)).toBe("python");
Expand All @@ -64,6 +68,7 @@ describe("Runtime", () => {
expect(getFunctionWorkerRuntime(Runtime.NODE14)).toBe("node");
expect(getFunctionWorkerRuntime(Runtime.NODE16)).toBe("node");
expect(getFunctionWorkerRuntime(Runtime.NODE18)).toBe("node");
expect(getFunctionWorkerRuntime(Runtime.NODE20)).toBe("node");
expect(getFunctionWorkerRuntime(Runtime.PYTHON36)).toBe("python");
expect(getFunctionWorkerRuntime(Runtime.PYTHON37)).toBe("python");
expect(getFunctionWorkerRuntime(Runtime.PYTHON38)).toBe("python");
Expand Down
3 changes: 3 additions & 0 deletions src/config/runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export enum Runtime {
NODE14 = "nodejs14",
NODE16 = "nodejs16",
NODE18 = "nodejs18",
NODE20 = "nodejs20",
PYTHON36 = "python3.6",
PYTHON37 = "python3.7",
PYTHON38 = "python3.8",
Expand All @@ -18,6 +19,7 @@ export const supportedRuntimes = [
Runtime.NODE14,
Runtime.NODE16,
Runtime.NODE18,
Runtime.NODE20,
Runtime.PYTHON36,
Runtime.PYTHON37,
Runtime.PYTHON38,
Expand Down Expand Up @@ -98,6 +100,7 @@ export const dockerImages = {
nodejs14: "NODE|14",
nodejs16: "NODE|16",
nodejs18: "NODE|18",
nodejs20: "NODE|20",
"python3.6": "PYTHON|3.6",
"python3.7": "PYTHON|3.7",
"python3.8": "PYTHON|3.8",
Expand Down
15 changes: 10 additions & 5 deletions src/plugins/deploy/azureDeployPlugin.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import { ServerlessAzureOptions, ServerlessAzureConfig } from "../../models/serv
import { MockFactory } from "../../test/mockFactory";
import { invokeHook } from "../../test/utils";
import { AzureDeployPlugin } from "./azureDeployPlugin";
import mockFs from "mock-fs"
import {vol} from "memfs"
import fs from "fs"

jest.mock("../../services/functionAppService");
import { FunctionAppService } from "../../services/functionAppService";
Expand All @@ -19,9 +20,9 @@ describe("Deploy plugin", () => {
let plugin: AzureDeployPlugin;

beforeAll(() => {
mockFs({
vol.fromNestedJSON({
"serviceName.zip": "contents",
}, { createCwd: true, createTmp: true });
}, process.cwd());
});

beforeEach(() => {
Expand All @@ -39,10 +40,12 @@ describe("Deploy plugin", () => {
});

afterAll(() => {
mockFs.restore();
vol.reset();
})

it("calls deploy", async () => {
const existsSpy = jest.spyOn(fs, "existsSync");
existsSpy.mockImplementation(() => true);
const deployResourceGroup = jest.fn();
const functionAppStub: Site = MockFactory.createTestSite();
const deploy = jest.fn(() => Promise.resolve(functionAppStub));
Expand Down Expand Up @@ -96,8 +99,10 @@ describe("Deploy plugin", () => {
});

it("crashes deploy if zip file is not found", async () => {
const existsSpy = jest.spyOn(fs, "existsSync");
existsSpy.mockImplementation(() => true);
FunctionAppService.prototype.getFunctionZipFile = jest.fn(() => "notExisting.zip");
await expect(invokeHook(plugin, "deploy:deploy"))
.rejects.toThrow(/Function app zip file '.*' does not exist/)
.resolves.toThrow(/Function app zip file '.*' does not exist/)
});
});
18 changes: 6 additions & 12 deletions src/plugins/func/azureFuncPlugin.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import fs from "fs";
import mockFs from "mock-fs";
import {vol} from "memfs"
import rimraf from "rimraf";
import { MockFactory } from "../../test/mockFactory";
import { invokeHook } from "../../test/utils";
Expand All @@ -20,7 +20,7 @@ describe("Azure Func Plugin", () => {
describe("Add command", () => {

beforeAll(() => {
mockFs({
vol.fromNestedJSON({
"myExistingFunction": {
"index.js": "contents",
"function.json": "contents",
Expand All @@ -30,7 +30,7 @@ describe("Azure Func Plugin", () => {
});

afterAll(() => {
mockFs.restore();
vol.reset();
});

afterEach(() => {
Expand Down Expand Up @@ -84,7 +84,7 @@ describe("Azure Func Plugin", () => {
describe("Remove command", () => {

beforeAll(() => {
mockFs({
vol.fromNestedJSON({
"index.js": "contents",
"function1": {
"function.json": "contents",
Expand All @@ -93,7 +93,7 @@ describe("Azure Func Plugin", () => {
});

afterAll(() => {
mockFs.restore();
vol.reset();
});

it("returns with missing name", async () => {
Expand All @@ -118,7 +118,7 @@ describe("Azure Func Plugin", () => {
});

it("deletes directory and updates serverless.yml", async () => {
mockFs({
vol.fromNestedJSON({
"hello.js": "contents",
hello: {
"function.json": "contents",
Expand All @@ -129,13 +129,7 @@ describe("Azure Func Plugin", () => {
const plugin = new AzureFuncPlugin(sls, options);
const functionName = "hello";
options["name"] = functionName;
const unlinkSpy = jest.spyOn(fs, "unlinkSync");
const rimrafSpy = jest.spyOn(rimraf, "sync");
await invokeHook(plugin, "func:remove:remove");
expect(unlinkSpy).toBeCalledWith(`${functionName}.js`)
expect(rimrafSpy).toBeCalledWith(functionName);
unlinkSpy.mockRestore();
rimrafSpy.mockRestore();
const expectedFunctionsYml = MockFactory.createTestSlsFunctionConfig();
delete expectedFunctionsYml[functionName];
expect(sls.utils.writeFileSync).toBeCalledWith("serverless.yml", MockFactory.createTestServerlessYml(true, expectedFunctionsYml))
Expand Down
11 changes: 7 additions & 4 deletions src/plugins/invoke/azureInvokePlugin.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { MockFactory } from "../../test/mockFactory";
import { invokeHook } from "../../test/utils";
import mockFs from "mock-fs";
import {vol} from "memfs"
import fs from "fs"
import { AzureInvokePlugin } from "./azureInvokePlugin";
jest.mock("../../services/functionAppService");
jest.mock("../../services/resourceService");
Expand All @@ -16,12 +17,12 @@ describe("Azure Invoke Plugin", () => {
})

beforeAll(() => {
mockFs({
vol.fromNestedJSON({
"testFile.json": fileContent,
}, { createCwd: true, createTmp: true });
}, process.cwd());
});
afterAll(() => {
mockFs.restore();
vol.reset();
});

it("calls invoke hook", async () => {
Expand All @@ -42,6 +43,8 @@ describe("Azure Invoke Plugin", () => {
});

it("calls the invoke hook with file path", async () => {
const existsSpy = jest.spyOn(fs, "existsSync");
existsSpy.mockImplementation(() => true)
const expectedResult = { data: "test" };
const invoke = jest.fn(() => expectedResult);
InvokeService.prototype.invoke = invoke as any;
Expand Down
24 changes: 13 additions & 11 deletions src/plugins/login/utils/simpleFileTokenCache.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import path from "path";
import os from "os";
import mockFs from "mock-fs";
import {vol} from "memfs"
import { MockFactory } from "../../../test/mockFactory";
import { SimpleFileTokenCache } from "./simpleFileTokenCache";
import fs from "fs";
Expand All @@ -14,11 +14,11 @@ describe("Simple File Token Cache", () => {
};

beforeEach(() => {
mockFs();
vol.fromNestedJSON({});
});

afterEach(() => {
mockFs.restore();
vol.reset();
});

it("Creates a load file on creation if none", () => {
Expand Down Expand Up @@ -64,7 +64,7 @@ describe("Simple File Token Cache", () => {
it("Load file on creation if available", () => {
fileContent.entries = MockFactory.createTestTokenCacheEntries();

mockFs({
vol.fromNestedJSON({
"slsTokenCache.json": JSON.stringify(fileContent)
});

Expand Down Expand Up @@ -102,11 +102,13 @@ describe("Simple File Token Cache", () => {
const writeFileSpy = jest.spyOn(fs, "writeFileSync");
const testFileCache = new SimpleFileTokenCache(tokenFilePath);
const testSubs = MockFactory.createTestSubscriptions();

const testSub = MockFactory.createTestSubscription();

testSub[0].expiresOn =null
testFileCache.addSubs(testSubs);

const expected = {
entries: [],
entries: testSub,
subscriptions: testSubs
};

Expand All @@ -118,18 +120,18 @@ describe("Simple File Token Cache", () => {
});

it("Doesn't fail adding subs if unable to parse JSON from file", () => {
mockFs({
vol.fromNestedJSON({
"slsTokenCache.json": JSON.stringify("")
});

const writeFileSpy = jest.spyOn(fs, "writeFileSync");
const testFileCache = new SimpleFileTokenCache(tokenFilePath);
const testSubs = MockFactory.createTestSubscriptions();

const testSub = MockFactory.createTestSubscription();
testFileCache.addSubs(testSubs);

const expected = {
entries: [],
entries: testSub,
subscriptions: testSubs
};

Expand All @@ -141,7 +143,7 @@ describe("Simple File Token Cache", () => {
});

it("Doesn't fail removing entries if unable to parse JSON from file", () => {
mockFs({
vol.fromNestedJSON({
"slsTokenCache.json": JSON.stringify("")
});

Expand All @@ -168,7 +170,7 @@ describe("Simple File Token Cache", () => {
});

it("Doesn't fail find if unable to parse JSON from file", () => {
mockFs({
vol.fromNestedJSON({
"slsTokenCache.json": JSON.stringify("")
});

Expand Down
6 changes: 3 additions & 3 deletions src/services/armService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { MockFactory } from "../test/mockFactory";
import { ArmService } from "./armService";
import { ArmResourceTemplate, ArmTemplateType, ArmDeployment, ArmTemplateProvisioningState, ArmParamType } from "../models/armTemplates";
import { ArmTemplateConfig, ServerlessAzureOptions } from "../models/serverless";
import mockFs from "mock-fs";
import {vol} from "memfs"
import jsonpath from "jsonpath";
import { Deployments } from "@azure/arm-resources";
import { Deployment, DeploymentExtended } from "@azure/arm-resources/esm/models";
Expand Down Expand Up @@ -41,7 +41,7 @@ describe("Arm Service", () => {
})

afterEach(() => {
mockFs.restore();
vol.reset();
})

describe("Creating Templates", () => {
Expand All @@ -53,7 +53,7 @@ describe("Arm Service", () => {

const testTemplate: ArmResourceTemplate = MockFactory.createTestArmTemplate();

mockFs({
vol.fromNestedJSON({
"armTemplates": {
"custom-template.json": JSON.stringify(testTemplate),
},
Expand Down
Loading