fix(staging): bootstrap database model key
Staging Backend Quality Gate / validate (push) Successful in 17m40s
Staging Backend Quality Gate / publish (push) Successful in 23m46s

This commit is contained in:
Jesse_Chen
2026-08-07 20:10:27 +08:00
parent 3089316d2e
commit 508f3db9c6
6 changed files with 72 additions and 0 deletions
+28
View File
@@ -4,6 +4,7 @@ import {
mkdtempSync,
readFileSync,
rmSync,
statSync,
writeFileSync,
} from "node:fs";
import { tmpdir } from "node:os";
@@ -222,6 +223,33 @@ test("staging deploy consumes only the isolated staging environment and tested r
assert.match(syncController, /--exclude='\/backups\/'/);
});
test("staging model provider env preparation removes legacy settings and keeps one stable key", () => {
const prepare = fileURLToPath(
new URL("../../deploy/prepare-staging-model-provider-env.sh", import.meta.url),
);
const root = mkdtempSync(join(tmpdir(), "jyotisha-staging-model-env-"));
const envFile = join(root, ".env.staging");
try {
writeFileSync(envFile, "APP_ENV_FILE=../.env.staging\nOPENAI_API_KEY=legacy\nLLM_MODEL=legacy\n");
chmodSync(envFile, 0o600);
const first = spawnSync("bash", [prepare, envFile], { encoding: "utf8" });
assert.equal(first.status, 0, first.stderr);
const prepared = readFileSync(envFile, "utf8");
assert.match(prepared, /^APP_ENV_FILE=\.\.\/\.env\.staging$/m);
assert.doesNotMatch(prepared, /^(OPENAI_API_KEY|LLM_MODEL)=/m);
const key = prepared.match(/^MODEL_PROVIDER_CONFIG_ENCRYPTION_KEY=([A-Za-z0-9+/]{43}=)$/m)?.[1];
assert.ok(key);
assert.equal(statSync(envFile).mode & 0o777, 0o600);
const second = spawnSync("bash", [prepare, envFile], { encoding: "utf8" });
assert.equal(second.status, 0, second.stderr);
const secondKey = readFileSync(envFile, "utf8").match(/^MODEL_PROVIDER_CONFIG_ENCRYPTION_KEY=([A-Za-z0-9+/]{43}=)$/m)?.[1];
assert.equal(secondKey, key);
} finally {
rmSync(root, { recursive: true, force: true });
}
});
test("staging env validator rejects selector drift, duplicates, and unsafe permissions", () => {
const validator = fileURLToPath(
new URL("../../deploy/validate-staging-env.sh", import.meta.url),
@@ -649,6 +649,7 @@ test("first immutable deployment rolls back to validated local image IDs", () =>
writeFileSync(join(deploymentPath, ".state", "deployed-revision"), `${previousSha}\n`);
for (const script of [
join(incomingDeploy, "sync-staging-tree.sh"),
join(liveDeploy, "prepare-staging-model-provider-env.sh"),
join(liveDeploy, "validate-staging-env.sh"),
join(liveDeploy, "validate-staging-database-env.sh"),
]) {
@@ -726,6 +727,7 @@ test("normal deployment checks migrations but never applies them", () => {
assert.match(runner, /^#!\/usr\/bin\/env bash\nset -euo pipefail\nset \+x\n/);
assert.match(runner, /-f deploy\/docker-compose\.staging\.yml/);
assertOrder(runner, [
"prepare-staging-model-provider-env.sh",
"validate-staging-env.sh",
"validate-staging-database-env.sh",
"compose=(",