Files
copilotkit__copilotkit/showcase/scripts/__tests__/emit-railway-envs-json.test.ts
Jordan Ritter ec4be53bdb fix(showcase): register showcase-crewai-conversational-flows in Railway SSOT
The verify-image-refs gate (verify-railway-image-refs.ts) failed because the
live Railway service `showcase-crewai-conversational-flows` had no entry in the
SERVICES map, tripping the Railway->SSOT drift check (1 untracked service).

Add the service as a STAGING-ONLY entry: the live Railway service currently has
a serviceInstance in staging only (no prod instance is provisioned), so the
env-map schema declares only the env that exists. All values (serviceId,
staging instanceId, domain, healthcheckPath) are read verbatim from the live
Railway API, not guessed. ciBuilt:false because the integration is wired only
into the PR-check build (showcase_build_check.yml), not showcase_build.yml's
ALL_SERVICES matrix, so it stays out of CI_BUILT_SERVICES.

Regenerate railway-envs.generated.json and update the count/coverage
assertions in the affected tests (SSOT now has 42 services; findMissingServices
is intentionally asymmetric for the staging-only entry: 41 prod, 42 staging).
2026-08-15 09:45:36 -07:00

75 lines
3.0 KiB
TypeScript

import { execFileSync, spawnSync } from "node:child_process";
import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { resolve, join } from "node:path";
import { afterEach, beforeEach, describe, expect, it } from "vitest";
const SCRIPT = resolve(__dirname, "..", "emit-railway-envs-json.ts");
describe("emit-railway-envs-json", () => {
let workDir: string;
let outPath: string;
beforeEach(() => {
workDir = mkdtempSync(join(tmpdir(), "emit-railway-envs-"));
outPath = join(workDir, "railway-envs.generated.json");
});
afterEach(() => {
rmSync(workDir, { recursive: true, force: true });
});
it("emits canonical JSON containing every SSOT service", () => {
execFileSync("npx", ["tsx", SCRIPT, `--out=${outPath}`], { stdio: "pipe" });
const json = JSON.parse(readFileSync(outPath, "utf8"));
expect(json.projectId).toBe("6f8c6bff-a80d-4f8f-b78d-50b32bcf4479");
expect(json.envIds.staging).toBe("8edfef02-ea09-4a20-8689-261f21cc2849");
expect(json.envIds.prod).toBe("b14919f4-6417-429f-848d-c6ae2201e04f");
expect(json.services.length).toBe(42);
const docs = json.services.find((s: { name: string }) => s.name === "docs");
expect(docs.domains.staging).toBe("docs.staging.copilotkit.ai");
expect(docs.domains.prod).toBe("docs.copilotkit.ai");
expect(docs.probe.driver).toBe("docs");
});
it("--check passes when on-disk JSON matches SSOT", () => {
execFileSync("npx", ["tsx", SCRIPT, `--out=${outPath}`], { stdio: "pipe" });
const out = execFileSync(
"npx",
["tsx", SCRIPT, "--check", `--out=${outPath}`],
{ stdio: "pipe" },
).toString();
expect(out).toMatch(/up to date/);
});
it("--check FAILS with a staleness diagnostic when on-disk JSON is stale", () => {
execFileSync("npx", ["tsx", SCRIPT, `--out=${outPath}`], { stdio: "pipe" });
const original = readFileSync(outPath, "utf8");
writeFileSync(outPath, original.replace(/docs.copilotkit.ai/g, "x"));
const result = spawnSync(
"npx",
["tsx", SCRIPT, "--check", `--out=${outPath}`],
{ encoding: "utf8" },
);
expect(result.status).toBe(1);
expect(result.stderr).toMatch(/stale/);
});
it("--check FAILS LOUD on non-ENOENT read errors (e.g. EISDIR)", () => {
// Point --out at a directory so readFileSync raises EISDIR (not ENOENT).
// The script must NOT silently treat this as drift; it must exit non-zero
// with a real error written to stderr, distinct from the staleness exit
// (we use exit code 2 vs 1 to make the distinction observable).
const subdir = mkdtempSync(join(workDir, "isdir-"));
const result = spawnSync(
"npx",
["tsx", SCRIPT, "--check", `--out=${subdir}`],
{ encoding: "utf8" },
);
expect(result.status).toBe(2);
expect(result.stderr).toMatch(/EISDIR|illegal operation on a directory/i);
// Must NOT be the staleness message
expect(result.stderr).not.toMatch(/is stale/);
});
});