Skip to content

feat: pin runtimes to latest supported version on functions init. #8553

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

Open
wants to merge 2 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
- Changed artifact registry cleanup policy error to warn for CI/CD workloads #8513
- Enhance firebase init apphosting to support local source deploys. (#8479)
- Add GCP API client functions to support App Hosting deploy from source feature. (#8545)
- Changed firebase init template for functions to pin runtime version on init. (#8553)
2 changes: 2 additions & 0 deletions src/deploy/functions/runtimes/supported/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,5 @@ export type DecommissionedRuntime = {
? R
: never;
}[keyof typeof RUNTIMES];

export type ActiveRuntime = Exclude<Runtime, DecommissionedRuntime>;
4 changes: 2 additions & 2 deletions src/firebaseConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import type { HttpsOptions } from "firebase-functions/v2/https";
import { IngressSetting, MemoryOption, VpcEgressSetting } from "firebase-functions/v2/options";
import { Runtime, DecommissionedRuntime } from "./deploy/functions/runtimes/supported/types";
import { ActiveRuntime } from "./deploy/functions/runtimes/supported/types";

/**
* Creates a type that requires at least one key to be present in an interface
Expand Down Expand Up @@ -167,7 +167,7 @@ export type FirestoreConfig = FirestoreSingle | FirestoreMultiple;
export type FunctionConfig = {
source?: string;
ignore?: string[];
runtime?: Exclude<Runtime, DecommissionedRuntime>;
runtime?: ActiveRuntime;
codebase?: string;
} & Deployable;

Expand Down
4 changes: 4 additions & 0 deletions src/init/features/functions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,26 @@
} from "../../../functions/projectConfig";
import { FirebaseError } from "../../../error";
import { functionsOrigin, runtimeconfigOrigin } from "../../../api";
import * as supported from "../../../deploy/functions/runtimes/supported";

const MAX_ATTEMPTS = 5;

/**
* Set up a new firebase project for functions.
*/
export async function doSetup(setup: any, config: Config, options: Options): Promise<any> {

Check warning on line 24 in src/init/features/functions/index.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unexpected any. Specify a different type

Check warning on line 24 in src/init/features/functions/index.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unexpected any. Specify a different type
const projectId = setup?.rcfile?.projects?.default;

Check warning on line 25 in src/init/features/functions/index.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe member access .rcfile on an `any` value

Check warning on line 25 in src/init/features/functions/index.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe assignment of an `any` value
if (projectId) {
await requirePermissions({ ...options, project: projectId });

Check warning on line 27 in src/init/features/functions/index.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe assignment of an `any` value
await Promise.all([
ensure(projectId, functionsOrigin(), "unused", true),

Check warning on line 29 in src/init/features/functions/index.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe argument of type `any` assigned to a parameter of type `string`
ensure(projectId, runtimeconfigOrigin(), "unused", true),

Check warning on line 30 in src/init/features/functions/index.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe argument of type `any` assigned to a parameter of type `string`
]);
}
setup.functions = {};

Check warning on line 33 in src/init/features/functions/index.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe member access .functions on an `any` value
// check if functions have been initialized yet
if (!config.src.functions) {
setup.config.functions = [];

Check warning on line 36 in src/init/features/functions/index.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe member access .config on an `any` value
return initNewCodebase(setup, config);
}
setup.config.functions = normalizeAndValidate(setup.config.functions);
Expand Down Expand Up @@ -198,6 +199,9 @@
break;
case "python":
cbconfig.ignore = ["venv", ".git", "firebase-debug.log", "firebase-debug.*.log", "*.local"];
// In practical sense, latest supported runtime will not be a decomissioned runtime,
// but in theory this doesn't have to be the case.
cbconfig.runtime = supported.latest("python") as supported.ActiveRuntime;
break;
}
setup.functions.languageChoice = language;
Expand Down
11 changes: 9 additions & 2 deletions src/init/features/functions/javascript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { askInstallDependencies } from "./npm-dependencies";
import { confirm } from "../../../prompt";
import { configForCodebase } from "../../../functions/projectConfig";
import { readTemplateSync } from "../../../templates";
import * as supported from "../../../deploy/functions/runtimes/supported";

const INDEX_TEMPLATE = readTemplateSync("init/functions/javascript/index.js");
const PACKAGE_LINTING_TEMPLATE = readTemplateSync("init/functions/javascript/package.lint.json");
Expand All @@ -20,13 +21,19 @@ export async function setup(setup: any, config: any): Promise<any> {
cbconfig.predeploy = ['npm --prefix "$RESOURCE_DIR" run lint'];
await config.askWriteProjectFile(
`${setup.functions.source}/package.json`,
PACKAGE_LINTING_TEMPLATE,
PACKAGE_LINTING_TEMPLATE.replace(
"{{RUNTIME}}",
supported.latest("nodejs").replace("nodejs", ""),
),
);
await config.askWriteProjectFile(`${setup.functions.source}/.eslintrc.js`, ESLINT_TEMPLATE);
} else {
await config.askWriteProjectFile(
`${setup.functions.source}/package.json`,
PACKAGE_NO_LINTING_TEMPLATE,
PACKAGE_NO_LINTING_TEMPLATE.replace(
"{{RUNTIME}}",
supported.latest("nodejs").replace("nodejs", ""),
),
);
}

Expand Down
11 changes: 9 additions & 2 deletions src/init/features/functions/typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { askInstallDependencies } from "./npm-dependencies";
import { confirm } from "../../../prompt";
import { configForCodebase } from "../../../functions/projectConfig";
import { readTemplateSync } from "../../../templates";
import * as supported from "../../../deploy/functions/runtimes/supported";

const PACKAGE_LINTING_TEMPLATE = readTemplateSync("init/functions/typescript/package.lint.json");
const PACKAGE_NO_LINTING_TEMPLATE = readTemplateSync(
Expand All @@ -28,7 +29,10 @@ export async function setup(setup: any, config: any): Promise<any> {
cbconfig.predeploy.push('npm --prefix "$RESOURCE_DIR" run build');
await config.askWriteProjectFile(
`${setup.functions.source}/package.json`,
PACKAGE_LINTING_TEMPLATE,
PACKAGE_LINTING_TEMPLATE.replace(
"{{RUNTIME}}",
supported.latest("nodejs").replace("nodejs", ""),
),
);
await config.askWriteProjectFile(`${setup.functions.source}/.eslintrc.js`, ESLINT_TEMPLATE);
// TODO: isn't this file out of date now?
Expand All @@ -40,7 +44,10 @@ export async function setup(setup: any, config: any): Promise<any> {
cbconfig.predeploy.push('npm --prefix "$RESOURCE_DIR" run build');
await config.askWriteProjectFile(
`${setup.functions.source}/package.json`,
PACKAGE_NO_LINTING_TEMPLATE,
PACKAGE_NO_LINTING_TEMPLATE.replace(
"{{RUNTIME}}",
supported.latest("nodejs").replace("nodejs", ""),
),
);
}

Expand Down
2 changes: 1 addition & 1 deletion templates/init/functions/javascript/package.lint.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"logs": "firebase functions:log"
},
"engines": {
"node": "22"
"node": "{{RUNTIME}}"
},
"main": "index.js",
"dependencies": {
Expand Down
2 changes: 1 addition & 1 deletion templates/init/functions/javascript/package.nolint.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"logs": "firebase functions:log"
},
"engines": {
"node": "22"
"node": "{{RUNTIME}}"
},
"main": "index.js",
"dependencies": {
Expand Down
2 changes: 1 addition & 1 deletion templates/init/functions/typescript/package.lint.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"logs": "firebase functions:log"
},
"engines": {
"node": "22"
"node": "{{RUNTIME}}"
},
"main": "lib/index.js",
"dependencies": {
Expand Down
4 changes: 2 additions & 2 deletions templates/init/functions/typescript/package.nolint.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"logs": "firebase functions:log"
},
"engines": {
"node": "22"
"node": "{{RUNTIME}}"
},
"main": "lib/index.js",
"dependencies": {
Expand All @@ -22,4 +22,4 @@
"firebase-functions-test": "^3.1.0"
},
"private": true
}
}
Loading