Skip to content

Commit 184d210

Browse files
authored
BREAKING: hide functions:config:* commands by default (#9340)
We'll gate all mutating functions:config:* commands behind the new `legacyRuntimeConfigCommands` experiment. We'll keep functions:config:{get,export} available for inspection. Includes some minor refactoring to align deprecation message across all surfaces. ```shell $ firebase functions:config:set FOO=bar Error: DEPRECATION NOTICE: Action required before March 2026 The functions.config() API and the Cloud Runtime Config service are deprecated. Deploys that rely on functions.config() will fail once Runtime Config shuts down in March 2026. The legacy functions:config:* CLI commands are deprecated and will be removed before March 2026. Migrate configuration to the Firebase Functions params APIs: import { defineJsonSecret } from "firebase-functions/params"; const config = defineJsonSecret("RUNTIME_CONFIG"); exports.myFunction = functions .runWith({ secrets: [config] }) .https.onRequest((req, res) => { const apiKey = config.value().service.key; // ... }); To convert existing runtime config values, try the interactive migration command: firebase functions:config:export Learn more: https://firebase.google.com/docs/functions/config-env#migrate-config To run this legacy command temporarily, run the following command and try again: firebase experiments:enable legacyRuntimeConfigCommands ```
1 parent 80a7aeb commit 184d210

File tree

10 files changed

+57
-40
lines changed

10 files changed

+57
-40
lines changed

src/commands/functions-config-clone.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ import { requirePermissions } from "../requirePermissions";
88
import * as functionsConfig from "../functionsConfig";
99
import { functionsConfigClone } from "../functionsConfigClone";
1010
import * as utils from "../utils";
11-
import { logFunctionsConfigDeprecationWarning } from "../functions/deprecationWarnings";
1211

1312
export const command = new Command("functions:config:clone")
1413
.description("clone environment config from another project")
1514
.option("--from <projectId>", "the project from which to clone configuration")
1615
.option("--only <keys>", "a comma-separated list of keys to clone")
1716
.option("--except <keys>", "a comma-separated list of keys to not clone")
17+
.before(functionsConfig.ensureLegacyRuntimeConfigCommandsEnabled)
1818
.before(requirePermissions, [
1919
"runtimeconfig.configs.list",
2020
"runtimeconfig.configs.create",
@@ -57,5 +57,5 @@ export const command = new Command("functions:config:clone")
5757
"firebase deploy --only functions",
5858
)}\n`,
5959
);
60-
logFunctionsConfigDeprecationWarning();
60+
functionsConfig.logFunctionsConfigDeprecationWarning();
6161
});

src/commands/functions-config-get.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { logger } from "../logger";
66
import { needProjectId } from "../projectUtils";
77
import { requirePermissions } from "../requirePermissions";
88
import * as functionsConfig from "../functionsConfig";
9-
import { logFunctionsConfigDeprecationWarning } from "../functions/deprecationWarnings";
109

1110
async function materialize(projectId: string, path?: string): Promise<any> {
1211
if (path === undefined) {
@@ -32,6 +31,6 @@ export const command = new Command("functions:config:get [path]")
3231
.action(async (path, options) => {
3332
const result = await materialize(needProjectId(options), path);
3433
logger.info(JSON.stringify(result, null, 2));
35-
logFunctionsConfigDeprecationWarning();
34+
functionsConfig.logFunctionsConfigDeprecationWarning();
3635
return result;
3736
});

src/commands/functions-config-set.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ import { needProjectId } from "../projectUtils";
77
import { requirePermissions } from "../requirePermissions";
88
import * as functionsConfig from "../functionsConfig";
99
import * as utils from "../utils";
10-
import { logFunctionsConfigDeprecationWarning } from "../functions/deprecationWarnings";
1110

1211
export const command = new Command("functions:config:set [values...]")
1312
.description("set environment config with key=value syntax")
13+
.before(functionsConfig.ensureLegacyRuntimeConfigCommandsEnabled)
1414
.before(requirePermissions, [
1515
"runtimeconfig.configs.list",
1616
"runtimeconfig.configs.create",
@@ -50,5 +50,5 @@ export const command = new Command("functions:config:set [values...]")
5050
"firebase deploy --only functions",
5151
)}\n`,
5252
);
53-
logFunctionsConfigDeprecationWarning();
53+
functionsConfig.logFunctionsConfigDeprecationWarning();
5454
});

src/commands/functions-config-unset.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ import * as functionsConfig from "../functionsConfig";
88
import * as runtimeconfig from "../gcp/runtimeconfig";
99
import * as utils from "../utils";
1010
import { FirebaseError } from "../error";
11-
import { logFunctionsConfigDeprecationWarning } from "../functions/deprecationWarnings";
1211

1312
export const command = new Command("functions:config:unset [keys...]")
1413
.description("unset environment config at the specified path(s)")
14+
.before(functionsConfig.ensureLegacyRuntimeConfigCommandsEnabled)
1515
.before(requirePermissions, [
1616
"runtimeconfig.configs.list",
1717
"runtimeconfig.configs.create",
@@ -45,5 +45,5 @@ export const command = new Command("functions:config:unset [keys...]")
4545
"firebase deploy --only functions",
4646
)}\n`,
4747
);
48-
logFunctionsConfigDeprecationWarning();
48+
functionsConfig.logFunctionsConfigDeprecationWarning();
4949
});

src/commands/internaltesting-functions-discover.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export const command = new Command("internaltesting:functions:discover")
2424
}
2525

2626
let runtimeConfig: Record<string, unknown> = { firebase: firebaseConfig };
27-
const allowFunctionsConfig = experiments.isEnabled("dangerouslyAllowFunctionsConfig");
27+
const allowFunctionsConfig = experiments.isEnabled("legacyRuntimeConfigCommands");
2828

2929
if (allowFunctionsConfig) {
3030
try {

src/deploy/functions/prepare.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ export async function prepare(
9494

9595
// ===Phase 1. Load codebases from source with optional runtime config.
9696
let runtimeConfig: Record<string, unknown> = { firebase: firebaseConfig };
97-
const allowFunctionsConfig = experiments.isEnabled("dangerouslyAllowFunctionsConfig");
97+
const allowFunctionsConfig = experiments.isEnabled("legacyRuntimeConfigCommands");
9898

9999
// Load runtime config if experiment allows it and API is enabled
100100
if (allowFunctionsConfig && checkAPIsEnabled[1]) {

src/deploy/functions/prepareFunctionsUpload.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import * as functionsConfig from "../../functionsConfig";
1313
import * as utils from "../../utils";
1414
import * as fsAsync from "../../fsAsync";
1515
import * as projectConfig from "../../functions/projectConfig";
16-
import { logFunctionsConfigDeprecationWarning } from "../../functions/deprecationWarnings";
1716

1817
const CONFIG_DEST_FILE = ".runtimeconfig.json";
1918

@@ -104,7 +103,7 @@ async function packageSource(
104103
// Only warn about deprecated runtime config if there are user-defined values
105104
// (i.e., keys other than the default 'firebase' key)
106105
if (Object.keys(runtimeConfig).some((k) => k !== "firebase")) {
107-
logFunctionsConfigDeprecationWarning();
106+
functionsConfig.logFunctionsConfigDeprecationWarning();
108107
}
109108
}
110109
await pipeAsync(archive, fileStream);

src/experiments.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export const ALL_EXPERIMENTS = experiments({
3939
"of deploys. This has been made an experiment due to backend bugs that are " +
4040
"temporarily causing failures in some regions with this optimization enabled",
4141
public: true,
42-
default: true,
42+
default: false,
4343
},
4444
deletegcfartifacts: {
4545
shortDescription: `Add the ${bold(
@@ -55,13 +55,13 @@ export const ALL_EXPERIMENTS = experiments({
5555
`Registry. The ${bold("functions:deletegcfartifacts")} command ` +
5656
"will delete all Docker images created by Google Cloud Functions irrespective " +
5757
"of how that image was created.",
58-
public: true,
58+
public: false,
5959
},
60-
dangerouslyAllowFunctionsConfig: {
61-
shortDescription: "Allows the use of deprecated functions.config() API",
60+
legacyRuntimeConfigCommands: {
61+
shortDescription: "Expose legacy functions.config() CLI commands",
6262
fullDescription:
63-
"The functions.config() API is deprecated and will be removed on December 31, 2025. " +
64-
"This experiment allows continued use of the API during the migration period.",
63+
"The Cloud Runtime Config API is deprecated. Enable this experiment to continue using the " +
64+
"`functions:config:*` commands while you migrate to the Firebase Functions params APIs.",
6565
default: true,
6666
public: true,
6767
},

src/functions/deprecationWarnings.ts

Lines changed: 0 additions & 22 deletions
This file was deleted.

src/functionsConfig.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,52 @@ import { FirebaseError } from "./error";
88
import { needProjectId } from "./projectUtils";
99
import * as runtimeconfig from "./gcp/runtimeconfig";
1010
import * as args from "./deploy/functions/args";
11+
import * as experiments from "./experiments";
12+
import { logWarningToStderr } from "./utils";
1113

1214
export const RESERVED_NAMESPACES = ["firebase"];
1315

1416
const apiClient = new Client({ urlPrefix: firebaseApiOrigin() });
1517

18+
const LEGACY_RUNTIME_CONFIG_EXPERIMENT = "legacyRuntimeConfigCommands";
19+
20+
const FUNCTIONS_CONFIG_DEPRECATION_MESSAGE = `DEPRECATION NOTICE: Action required before March 2026
21+
22+
The functions.config() API and the Cloud Runtime Config service are deprecated. Deploys that rely on functions.config() will fail once Runtime Config shuts down in March 2026.
23+
24+
The legacy functions:config:* CLI commands are deprecated and will be removed before March 2026.
25+
26+
Learn how to migrate from functions.config() to the params package:
27+
28+
https://firebase.google.com/docs/functions/config-env#migrate-config
29+
30+
To convert existing functions.config() values to params, try the interactive migration command:
31+
32+
firebase functions:config:export
33+
`;
34+
35+
const LEGACY_GUIDANCE_MESSAGE = `${FUNCTIONS_CONFIG_DEPRECATION_MESSAGE}
36+
37+
To run this legacy command temporarily, run the following command and try again:
38+
39+
firebase experiments:enable ${LEGACY_RUNTIME_CONFIG_EXPERIMENT}
40+
`;
41+
42+
export function getFunctionsConfigDeprecationMessage(): string {
43+
return FUNCTIONS_CONFIG_DEPRECATION_MESSAGE;
44+
}
45+
46+
export function logFunctionsConfigDeprecationWarning(): void {
47+
logWarningToStderr(FUNCTIONS_CONFIG_DEPRECATION_MESSAGE);
48+
}
49+
50+
export function ensureLegacyRuntimeConfigCommandsEnabled(): void {
51+
if (experiments.isEnabled(LEGACY_RUNTIME_CONFIG_EXPERIMENT)) {
52+
return;
53+
}
54+
throw new FirebaseError(LEGACY_GUIDANCE_MESSAGE, { exit: 1 });
55+
}
56+
1657
interface Id {
1758
config: string;
1859
variable: string;

0 commit comments

Comments
 (0)