Deploy / validate-dispatch (push) Successful in 43s
Deploy / scheduled-rebuild-dev (push) Skipped
Deploy / scheduled-rebuild-master (push) Skipped
Deploy / rollback-dev (push) Skipped
Deploy / rollback-master (push) Skipped
Deploy / changes (push) Successful in 13s
Deploy / secret-scan (push) Successful in 9s
Deploy / app-quality (push) Successful in 11m21s
Deploy / security-deps (push) Successful in 14s
Deploy / context (push) Failing after 1s
Deploy / app-image (push) Skipped
Deploy / deploy-dev (push) Skipped
Deploy / deploy-master (push) Skipped
87 lines
2.8 KiB
JavaScript
87 lines
2.8 KiB
JavaScript
import { spawn } from "node:child_process";
|
|
import fs from "node:fs/promises";
|
|
import path from "node:path";
|
|
|
|
const root = path.resolve(import.meta.dirname, "..");
|
|
const appPort = Number(process.env.E2E_PORT ?? 3100);
|
|
const fixturePort = Number(process.env.FIXTURE_PORT ?? 3101);
|
|
const baseUrl = `http://127.0.0.1:${appPort}`;
|
|
const children = [];
|
|
|
|
function run(command, args, options = {}) {
|
|
return new Promise((resolve, reject) => {
|
|
const child = spawn(command, args, { cwd: root, env: process.env, stdio: "inherit", ...options });
|
|
child.once("error", reject);
|
|
child.once("exit", (code) => code === 0
|
|
? resolve()
|
|
: reject(new Error(`${command} ${args.join(" ")} exited with code ${code ?? "null"}`)));
|
|
});
|
|
}
|
|
|
|
function start(command, args, env = {}) {
|
|
const child = spawn(command, args, {
|
|
cwd: root,
|
|
env: { ...process.env, ...env },
|
|
stdio: "inherit",
|
|
});
|
|
children.push(child);
|
|
return child;
|
|
}
|
|
|
|
async function waitFor(url) {
|
|
for (let attempt = 0; attempt < 60; attempt += 1) {
|
|
try {
|
|
const response = await fetch(url);
|
|
if (response.ok) return;
|
|
} catch {
|
|
// The process is still starting.
|
|
}
|
|
await new Promise((resolve) => setTimeout(resolve, 250));
|
|
}
|
|
throw new Error(`Timed out waiting for ${url}`);
|
|
}
|
|
|
|
async function stopChildren() {
|
|
await Promise.all(children.map((child) => new Promise((resolve) => {
|
|
if (child.exitCode !== null) return resolve();
|
|
child.once("exit", resolve);
|
|
child.kill("SIGTERM");
|
|
setTimeout(() => {
|
|
if (child.exitCode === null) child.kill("SIGKILL");
|
|
}, 3_000).unref();
|
|
})));
|
|
}
|
|
|
|
async function prepareStandaloneServer() {
|
|
const standaloneRoot = path.join(root, ".next", "standalone");
|
|
await fs.rm(path.join(standaloneRoot, "public"), { recursive: true, force: true });
|
|
await fs.rm(path.join(standaloneRoot, ".next", "static"), { recursive: true, force: true });
|
|
await fs.cp(path.join(root, "public"), path.join(standaloneRoot, "public"), { recursive: true });
|
|
await fs.cp(
|
|
path.join(root, ".next", "static"),
|
|
path.join(standaloneRoot, ".next", "static"),
|
|
{ recursive: true },
|
|
);
|
|
}
|
|
|
|
const npm = process.platform === "win32" ? "npm.cmd" : "npm";
|
|
|
|
try {
|
|
await run(npm, ["run", "build"]);
|
|
await prepareStandaloneServer();
|
|
start(process.execPath, ["e2e/fixture-server.mjs"], { FIXTURE_PORT: String(fixturePort) });
|
|
start(process.execPath, [".next/standalone/server.js"], {
|
|
CALENDAR_URL: `http://127.0.0.1:${fixturePort}/calendar.ics`,
|
|
APP_URL: baseUrl,
|
|
CORS_ORIGIN: baseUrl,
|
|
PORT: String(appPort),
|
|
HOSTNAME: "127.0.0.1",
|
|
});
|
|
await waitFor(`${baseUrl}/api/events`);
|
|
await run(process.execPath, ["--test", "e2e/smoke.e2e.mjs"], {
|
|
env: { ...process.env, E2E_BASE_URL: baseUrl },
|
|
});
|
|
} finally {
|
|
await stopChildren();
|
|
}
|