mirror of
https://github.com/CopilotKit/CopilotKit.git
synced 2026-09-14 16:26:20 +08:00
734294155a
PR #6130 added `src/middleware.ts`, which sets the `x-pathname` header that `src/app/demos/layout.tsx`'s `generateMetadata()` reads. That header is what makes the layout actually call `loadDemoIndex()` — a request-time `readFileSync(process.cwd()/manifest.yaml)`. The Dockerfile's runner stage never copied `manifest.yaml`, so every `/demos/*` route now 500s with "An error occurred in the Server Components render" (ENOENT), while the statically-prerendered home page keeps returning 200. On the dashboard that reads as "service is up, every cell pinned at D3": D4 fails on `page.type` waiting for `textarea`, D5 times out, D6 fails on `waitForSelector('[role="textbox"]')` — the chat input never mounts because the page is an error boundary. langgraph-python hit this exact bug and fixed it with the same one-line COPY; ms-agent-dotnet is the only integration shipping `middleware.ts` without it. Adds a ratchet test over that invariant (mutation-verified: fails with the COPY removed).
50 lines
1.9 KiB
TypeScript
50 lines
1.9 KiB
TypeScript
import { existsSync, readFileSync } from "node:fs";
|
|
import { resolve } from "node:path";
|
|
|
|
import { globSync } from "glob";
|
|
import { expect, test } from "vitest";
|
|
|
|
const repositoryRoot = resolve(import.meta.dirname, "../../..");
|
|
|
|
/**
|
|
* `src/app/demos/layout.tsx` reads `manifest.yaml` from `process.cwd()` inside
|
|
* `generateMetadata()`, but only once `headers()` returns an `x-pathname` — and
|
|
* only `src/middleware.ts` sets that header. So an integration that ships the
|
|
* middleware opts every `/demos/*` route into dynamic rendering AND into a
|
|
* request-time `readFileSync` of `manifest.yaml`. If the Dockerfile's runner
|
|
* stage doesn't copy the manifest, every demo page 500s with "An error occurred
|
|
* in the Server Components render" (ENOENT) while the statically-prerendered
|
|
* home page keeps returning 200 — which reads on the dashboard as "UI is up,
|
|
* every cell stuck at D3". This bit langgraph-python once and ms-agent-dotnet
|
|
* once (PR #6130); this test is the ratchet.
|
|
*/
|
|
const integrationsWithMiddleware = globSync(
|
|
"showcase/integrations/*/src/middleware.ts",
|
|
{
|
|
cwd: repositoryRoot,
|
|
posix: true,
|
|
},
|
|
).map((match) => match.split("/")[2]);
|
|
|
|
test("integrations that ship middleware.ts exist", () => {
|
|
expect(integrationsWithMiddleware.length).toBeGreaterThan(0);
|
|
});
|
|
|
|
test.each(integrationsWithMiddleware)(
|
|
"%s copies manifest.yaml into the runtime image",
|
|
(integration) => {
|
|
const dir = resolve(repositoryRoot, "showcase/integrations", integration);
|
|
// Only integrations whose demos layout actually reads the manifest need it.
|
|
const layout = resolve(dir, "src/app/demos/layout.tsx");
|
|
if (
|
|
!existsSync(layout) ||
|
|
!readFileSync(layout, "utf8").includes("manifest.yaml")
|
|
) {
|
|
return;
|
|
}
|
|
|
|
const dockerfile = readFileSync(resolve(dir, "Dockerfile"), "utf8");
|
|
expect(dockerfile).toMatch(/^COPY .*manifest\.yaml/m);
|
|
},
|
|
);
|