SPB Git

Repository Public MIT

global-setup.ts 2.4 KB 36 lines typescript

1import { execFileSync } from "node:child_process";2import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";3import { randomBytes } from "node:crypto";45/** Creates a disposable publisher through the server console and ensures demo content exists. */6export default async function globalSetup() {7  const base = process.env.E2E_BASE_URL ?? "http://localhost:8570";8  if (/skills\.spboucher\.ai/.test(base) && process.env.E2E_READONLY !== "1") throw new Error("Refusing to run mutating E2E tests against production. Set E2E_READONLY=1 for the public-only subset.");9  mkdirSync("test-results", { recursive: true });10  const stateFile = "test-results/e2e-state.json";11  if (process.env.E2E_READONLY === "1") {12    writeFileSync(stateFile, JSON.stringify({ readonly: true, namespace: process.env.E2E_NAMESPACE ?? "spboucher" }));13    return;14  }15  const id = randomBytes(4).toString("hex");16  const pwFile = `test-results/e2e-pw-${id}.txt`;17  const email = `e2e-${id}@example.test`;18  const namespace = `e2e-${id}`;19  execFileSync("pnpm", ["-s", "admin", "user", "create", "--email", email, "--name", "E2E Publisher", "--namespace", namespace, "--password-out", pwFile], { stdio: "pipe" });20  const initialPassword = readFileSync(pwFile, "utf8").trim();21  rmSync(pwFile);22  // Demo content: publish the registry's own examples into the dev database when missing.23  const res = await fetch(`${base}/api/v1/artifacts/spboucher/hello-skill`);24  if (res.status === 404 && existsSync("/tmp/skills-dev-cred.json")) {25    for (const e of ["hello-skill", "citation-check", "echo-mcp-server"]) {26      execFileSync("pnpm", ["-s", "skills", "publish", `examples/${e}`, "--visibility", "public", "--yes"], { stdio: "pipe", env: { ...process.env, SKILLS_REGISTRY: base, SKILLS_CREDENTIAL_STORE: "file:/tmp/skills-dev-cred.json" } });27    }28  }29  // A publisher token for specs that publish through the HTTP API (never printed, never committed).30  const tokenFile = `test-results/e2e-token-${id}.txt`;31  execFileSync("pnpm", ["-s", "admin", "token", "create", "--user", email, "--name", "e2e-api", "--namespace", namespace, "--expires-in", "1d", "--token-out", tokenFile], { stdio: "pipe" });32  const token = readFileSync(tokenFile, "utf8").trim();33  rmSync(tokenFile);34  writeFileSync(stateFile, JSON.stringify({ email, namespace, initialPassword, token, password: `e2e-${randomBytes(12).toString("hex")}` }), { mode: 0o600 });35}36
Files main
Menu

Theme