mirror of
https://github.com/CopilotKit/CopilotKit.git
synced 2026-09-14 16:26:20 +08:00
ec4be53bdb
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).
75 lines
3.0 KiB
TypeScript
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/);
|
|
});
|
|
});
|