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

Skip creating env variables with undefined values #7047

Open
wants to merge 4 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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
@@ -0,0 +1 @@
- Fixes issue where `firebase functions:config:export` fails when an env value is `undefined`. (#7047)
9 changes: 6 additions & 3 deletions src/functions/runtimeConfigExport.ts
Expand Up @@ -19,7 +19,7 @@
export interface EnvMap {
origKey: string;
newKey: string;
value: string;
value?: string;
err?: string;
}

Expand Down Expand Up @@ -81,7 +81,7 @@
})
.catch((err) => {
logger.debug(
`Failed to fetch runtime config for project ${info.projectId}: ${err.message}`,

Check warning on line 84 in src/functions/runtimeConfigExport.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Invalid type "any" of template literal expression

Check warning on line 84 in src/functions/runtimeConfigExport.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe member access .message on an `any` value
);
});
});
Expand All @@ -104,7 +104,7 @@
let envKey = baseKey;
try {
env.validateKey(envKey);
} catch (err: any) {

Check warning on line 107 in src/functions/runtimeConfigExport.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unexpected any. Specify a different type
if (err instanceof env.KeyValidationError) {
envKey = prefix + envKey;
env.validateKey(envKey);
Expand All @@ -123,19 +123,19 @@
for (const [configKey, value] of flatten(configs)) {
try {
const envKey = convertKey(configKey, prefix);
success.push({ origKey: configKey, newKey: envKey, value: value as string });

Check warning on line 126 in src/functions/runtimeConfigExport.ts

View workflow job for this annotation

GitHub Actions / lint (20)

This assertion is unnecessary since it does not change the type of the expression
} catch (err: any) {

Check warning on line 127 in src/functions/runtimeConfigExport.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unexpected any. Specify a different type
if (err instanceof env.KeyValidationError) {
errors.push({
origKey: configKey,
newKey: err.key,
err: err.message,
value: value as string,

Check warning on line 133 in src/functions/runtimeConfigExport.ts

View workflow job for this annotation

GitHub Actions / lint (20)

This assertion is unnecessary since it does not change the type of the expression
});
} else {
throw new FirebaseError("Unexpected error while converting config", {
exit: 2,
original: err,

Check warning on line 138 in src/functions/runtimeConfigExport.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe assignment of an `any` value
});
}
}
Expand All @@ -144,14 +144,14 @@
}

/**
* Fill in environment variables for each project by converting project's runtime config.

Check warning on line 147 in src/functions/runtimeConfigExport.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Expected only 0 line after block description
*
* @return {ConfigToEnvResult} Collection of successful and errored conversion.
*/
export function hydrateEnvs(pInfos: ProjectConfigInfo[], prefix: string): string {
let errMsg = "";
for (const pInfo of pInfos) {
const { success, errors } = configToEnv(pInfo.config!, prefix);

Check warning on line 154 in src/functions/runtimeConfigExport.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Forbidden non-null assertion
if (errors.length > 0) {
const msg =
`${pInfo.projectId} ` +
Expand Down Expand Up @@ -185,11 +185,14 @@
* Convert env var mapping to dotenv compatible string.
*/
export function toDotenvFormat(envs: EnvMap[], header = ""): string {
const lines = envs.map(({ newKey, value }) => `${newKey}="${escape(value)}"`);
const filteredEnvs = envs.filter((env) => env.value !== undefined);
const lines = filteredEnvs.map(({ newKey, value }) => `${newKey}="${escape(value!)}"`);

Check warning on line 189 in src/functions/runtimeConfigExport.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Forbidden non-null assertion
const maxLineLen = Math.max(...lines.map((l) => l.length));
return (
`${header}\n` +
lines.map((line, idx) => `${line.padEnd(maxLineLen)} # from ${envs[idx].origKey}`).join("\n")
lines
.map((line, idx) => `${line.padEnd(maxLineLen)} # from ${filteredEnvs[idx].origKey}`)
.join("\n")
);
}

Expand Down
12 changes: 12 additions & 0 deletions src/test/functions/runtimeConfigExport.spec.ts
Expand Up @@ -131,6 +131,18 @@ describe("functions-config-export", () => {
expect(errors).to.be.empty;
});

it("should produce valid dotenv file with keys and skip undefined values", () => {
const dotenv = configExport.toDotenvFormat([
{ origKey: "service.api.url", newKey: "SERVICE_API_URL", value: "hello" },
{ origKey: "service.api.name", newKey: "SERVICE_API_NAME", value: undefined },
]);
const { envs, errors } = env.parse(dotenv);
expect(envs).to.be.deep.equal({
SERVICE_API_URL: "hello",
});
expect(errors).to.be.empty;
});

it("should preserve newline characters", () => {
const dotenv = configExport.toDotenvFormat([
{ origKey: "service.api.url", newKey: "SERVICE_API_URL", value: "hello\nthere\nworld" },
Expand Down