fix: use event-driven renderer for build progress

This commit is contained in:
2026-10-04 21:23:33 +00:00 Unverified
parent aeac740f29
commit 6dd9cbc629
2 changed files with 59 additions and 3 deletions
+50
View File
@@ -26,6 +26,56 @@ const snapshot = {
};
describe("up API pipeline", () => {
test("does not append queued build frames on repeated TTY progress ticks", async () => {
const root = await mkdtemp(join(tmpdir(), "kuber-up-api-"));
const previousCwd = process.cwd();
const tty = Object.getOwnPropertyDescriptor(process.stdout, "isTTY");
const rendered: string[] = [];
const writes = spyOn(process.stdout, "write").mockImplementation(((chunk: string | Uint8Array) => {
rendered.push(String(chunk));
return true;
}) as typeof process.stdout.write);
let polls = 0;
try {
Object.defineProperty(process.stdout, "isTTY", { configurable: true, value: true });
await writeFile(join(root, "compose.yml"), "services:\n app:\n build: .\n");
await writeFile(join(root, ".kuberrc.ts"), 'export default { project: "shop" };\n');
process.chdir(root);
const trust = await resolveTrustIdentity("shop", root);
const request: ApiRequester = async <T>(path: string) => {
if (path === "/snapshots/negotiate") return { ready: true } as T;
if (path === "/builds") return { state: "queued" } as T;
if (path.includes("/events"))
return [{ type: "status", status: {
state: "queued",
phase: ["queued", "preparing", "waiting", "waiting"][polls],
} }] as T;
if (path.endsWith("/reconcile")) {
polls++;
await Bun.sleep(110);
return polls < 3
? { state: "queued" } as T
: { state: "failed", error: "build stopped" } as T;
}
throw new Error(path);
};
await expect(provideContext(() => runUp(true, request, { trust }))).rejects.toThrow("build stopped");
const output = rendered.join("");
expect(polls).toBe(3);
expect(output.match(/Build app/g)).toHaveLength(1);
expect(output.match(/Build queued/g)).toHaveLength(1);
expect(output).toContain("Build preparing");
expect(output).toContain("Build waiting");
expect(output).toContain("build stopped");
} finally {
writes.mockRestore();
if (tty) Object.defineProperty(process.stdout, "isTTY", tty);
else Reflect.deleteProperty(process.stdout, "isTTY");
process.chdir(previousCwd);
await rm(root, { recursive: true, force: true });
}
}, 5_000);
test("attaches each build log to its started image child", async () => {
const root = await mkdtemp(join(tmpdir(), "kuber-up-api-"));
const previousCwd = process.cwd();