feat: reuse Cloudflare Pages production configuration for exact-release dashboard builds and cover safe runtime imports in CI

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
Matthew Meszaros
2026-10-05 09:14:37 +00:00
co-authored by Devin AI
parent e7b6877ba4
commit 94cd8b1692
5 changed files with 244 additions and 31 deletions
@@ -0,0 +1,58 @@
import { randomUUID } from "node:crypto";
import { appendFileSync, readFileSync } from "node:fs";
const runtimeVariables = [
"WARMBLY_API_URL",
"WARMBLY_APP_URL",
"WARMBLY_TURNSTILE_KEY",
"WARMBLY_BETA_NOTICE",
"WARMBLY_SENTRY_DSN",
"WARMBLY_SENTRY_ENVIRONMENT",
"WARMBLY_POSTHOG_KEY",
"WARMBLY_POSTHOG_HOST",
"WARMBLY_POSTHOG_UI_HOST",
"WARMBLY_POSTHOG_ERROR_TRACKING",
"WARMBLY_POSTHOG_SESSION_REPLAY",
"WARMBLY_COMPANY_LOGOS",
];
const requiredVariables = new Set([
"WARMBLY_API_URL",
"WARMBLY_APP_URL",
"WARMBLY_TURNSTILE_KEY",
]);
class ConfigurationError extends Error {}
try {
const project = JSON.parse(readFileSync(0, "utf8"));
const branch = project.result?.production_branch;
if (project.success !== true || typeof branch !== "string" || !branch.trim() || /[\r\n]/.test(branch)) {
throw new ConfigurationError("Cloudflare did not return a valid Pages production branch.");
}
const variables = project.result.deployment_configs?.production?.env_vars ?? {};
const entries = runtimeVariables.map((name) => {
const variable = variables[name];
if (variable != null && (variable.type !== "plain_text" || typeof variable.value !== "string")) {
throw new ConfigurationError(`Set ${name} as a plaintext production variable in Pages; it is public browser configuration.`);
}
const value = variable?.value ?? "";
if (requiredVariables.has(name) && !value.trim()) {
throw new ConfigurationError(`Set ${name} in the Pages project's production environment before enabling release deployments.`);
}
let delimiter;
do {
delimiter = randomUUID();
} while (value.includes(delimiter));
return `${name}<<${delimiter}\n${value}\n${delimiter}\n`;
});
appendFileSync(process.env.GITHUB_ENV, entries.join(""));
appendFileSync(process.env.GITHUB_OUTPUT, `production_branch=${branch}\n`);
} catch (error) {
const message = error instanceof ConfigurationError
? error.message
: "Failed to read Cloudflare Pages production configuration.";
console.error(`::error::${message}`);
process.exitCode = 1;
}
@@ -0,0 +1,149 @@
import assert from "node:assert/strict";
import { spawnSync } from "node:child_process";
import { mkdtempSync, readFileSync, rmSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { test } from "node:test";
import { fileURLToPath } from "node:url";
import { runInNewContext } from "node:vm";
const script = fileURLToPath(new URL("./pages-production-config.mjs", import.meta.url));
const entrypoint = readFileSync(new URL("../../web/docker-entrypoint.sh", import.meta.url), "utf8");
const names = [...new Set([...entrypoint.matchAll(/\$\{(WARMBLY_[A-Z_]+)/g)].map((match) => match[1]))]
.filter((name) => name !== "WARMBLY_CONFIG_OUT");
function fixture() {
return {
success: true,
result: {
production_branch: "production",
deployment_configs: {
production: {
env_vars: Object.fromEntries(names.map((name) => [name, { type: "plain_text", value: `production-${name}` }])),
},
preview: { env_vars: { WARMBLY_API_URL: { type: "plain_text", value: "preview-only" } } },
},
},
};
}
function run(project) {
const work = mkdtempSync(join(tmpdir(), "pages-config-"));
try {
const envFile = join(work, "env");
const outputFile = join(work, "output");
const result = spawnSync(process.execPath, [script], {
input: typeof project === "string" ? project : JSON.stringify(project),
env: { ...process.env, GITHUB_ENV: envFile, GITHUB_OUTPUT: outputFile },
encoding: "utf8",
});
const read = (file) => {
try { return readFileSync(file, "utf8"); } catch { return ""; }
};
return { ...result, env: read(envFile), output: read(outputFile) };
} finally {
rmSync(work, { recursive: true, force: true });
}
}
function decode(text) {
const lines = text.split("\n");
const values = {};
while (lines[0]) {
const [name, delimiter] = lines.shift().split("<<");
const end = lines.indexOf(delimiter);
assert.ok(end >= 0);
values[name] = lines.splice(0, end).join("\n");
lines.shift();
}
return values;
}
test("imports every runtime key from production only and discovers the production branch", () => {
const project = fixture();
project.result.deployment_configs.production.env_vars.NODE_OPTIONS = { type: "plain_text", value: "untrusted" };
project.result.deployment_configs.production.env_vars.SENTRY_AUTH_TOKEN = { type: "secret_text", value: "private-value" };
const result = run(project);
assert.equal(result.status, 0, result.stderr);
assert.equal(result.output, "production_branch=production\n");
const values = decode(result.env);
assert.deepEqual(Object.keys(values).sort(), names.sort());
for (const name of names) assert.equal(values[name], `production-${name}`);
assert.equal(result.stdout + result.stderr, "");
});
test("preserves multiline values without injecting additional runner variables", () => {
const project = fixture();
const value = 'logos "quoted"\\path\r\nNODE_OPTIONS=untrusted\n::error::not-a-command';
project.result.deployment_configs.production.env_vars.WARMBLY_COMPANY_LOGOS.value = value;
const result = run(project);
assert.equal(result.status, 0, result.stderr);
assert.equal(decode(result.env).WARMBLY_COMPANY_LOGOS, value);
assert.equal(result.stdout + result.stderr, "");
});
test("defaults absent optional runtime settings to empty strings", () => {
const project = fixture();
delete project.result.deployment_configs.production.env_vars.WARMBLY_POSTHOG_KEY;
const result = run(project);
assert.equal(result.status, 0, result.stderr);
assert.equal(decode(result.env).WARMBLY_POSTHOG_KEY, "");
});
test("renders the imported production settings with the real dashboard entrypoint", () => {
const project = fixture();
project.result.deployment_configs.production.env_vars.WARMBLY_COMPANY_LOGOS.value = 'logos "quoted"\\path';
const imported = run(project);
assert.equal(imported.status, 0, imported.stderr);
const work = mkdtempSync(join(tmpdir(), "pages-render-"));
try {
const output = join(work, "config.js");
const rendered = spawnSync("sh", [fileURLToPath(new URL("../../web/docker-entrypoint.sh", import.meta.url))], {
env: { ...process.env, ...decode(imported.env), WARMBLY_CONFIG_OUT: output },
encoding: "utf8",
});
assert.equal(rendered.status, 0, rendered.stderr);
const window = {};
runInNewContext(readFileSync(output, "utf8"), { window });
assert.equal(window.__WARMBLY_ENV__.API_URL, "production-WARMBLY_API_URL");
assert.equal(window.__WARMBLY_ENV__.TURNSTILE_KEY, "production-WARMBLY_TURNSTILE_KEY");
assert.equal(window.__WARMBLY_ENV__.COMPANY_LOGOS, 'logos "quoted"\\path');
} finally {
rmSync(work, { recursive: true, force: true });
}
});
test("rejects missing required variables and encrypted runtime settings without writing config", () => {
for (const name of ["WARMBLY_API_URL", "WARMBLY_APP_URL", "WARMBLY_TURNSTILE_KEY"]) {
for (const setting of [undefined, { type: "plain_text", value: " " }, { type: "secret_text", value: "hidden" }]) {
const project = fixture();
project.result.deployment_configs.production.env_vars[name] = setting;
const result = run(project);
assert.equal(result.status, 1);
assert.ok(result.stderr.includes(name));
assert.ok(!result.stderr.includes("hidden"));
assert.equal(result.env + result.output, "");
}
}
const project = fixture();
project.result.deployment_configs.production.env_vars.WARMBLY_POSTHOG_KEY.type = "secret_text";
assert.equal(run(project).status, 1);
});
test("rejects malformed API responses, missing production config, and runner output injection", () => {
const inputs = ["invalid-private-response", { success: false }, { success: true, result: {} }, null];
for (const branch of ["", "main\nother=value", "main\rother=value"]) {
const project = fixture();
project.result.production_branch = branch;
inputs.push(project);
}
const noProduction = fixture();
delete noProduction.result.deployment_configs.production;
inputs.push(noProduction);
for (const input of inputs) {
const result = run(input);
assert.equal(result.status, 1);
assert.equal(result.env + result.output, "");
assert.ok(!result.stderr.includes("invalid-private-response"));
}
});