import { expect, test } from "bun:test"; import { createHash } from "node:crypto"; import { spawnSync } from "node:child_process"; import { readFileSync } from "node:fs"; import { resolve } from "node:path"; import { renderGiteaRemotePayloadMaterializer, summarizeGiteaRemotePayloads } from "./platform-infra-gitea-payload"; import { renderGiteaWebhookSyncDesiredManifest } from "./platform-infra-gitea"; const remoteScriptPath = resolve(import.meta.dir, "platform-infra-gitea-remote.sh"); test("stdin file envelope materializes a payload larger than the current Gitea manifest without argv or env", () => { const currentManifest = renderGiteaWebhookSyncDesiredManifest("NC01"); const oversizedManifest = `${currentManifest}\n${"payload-$HOME-'quote'-$(command)\n".repeat(8192)}`; expect(Buffer.byteLength(oversizedManifest)).toBeGreaterThan(Buffer.byteLength(currentManifest)); expect(Buffer.byteLength(Buffer.from(oversizedManifest).toString("base64"))).toBeGreaterThan(128 * 1024); const payloads = { manifest: oversizedManifest, repositories: JSON.stringify([{ key: "sentinel", branch: "master" }]), statusEvaluator: "print('ok')\n", frpcToml: "serverAddr = '127.0.0.1'\n", }; const materializer = renderGiteaRemotePayloadMaterializer(payloads); const result = spawnSync("sh", ["-s"], { encoding: "utf8", input: [ "set -eu", 'tmp="$(mktemp -d)"', 'trap \'rm -rf "$tmp"\' EXIT', materializer, 'unidesk_gitea_materialize_payloads "$tmp"', "python3 - \"$tmp\" <<'PY'", "import hashlib, json, pathlib, sys", "root = pathlib.Path(sys.argv[1])", "print(json.dumps({p.name: {'bytes': p.stat().st_size, 'sha256': hashlib.sha256(p.read_bytes()).hexdigest()} for p in root.iterdir()}, sort_keys=True))", "PY", ].join("\n"), }); expect(result.status).toBe(0); expect(result.stderr).toBe(""); const observed = JSON.parse(result.stdout) as Record; expect(observed["gitea.k8s.yaml"]).toEqual({ bytes: Buffer.byteLength(oversizedManifest), sha256: createHash("sha256").update(oversizedManifest).digest("hex"), }); expect(materializer).not.toContain("UNIDESK_GITEA_MANIFEST_B64"); const summary = summarizeGiteaRemotePayloads(payloads) as any; expect(summary.kind).toBe("trans-stdin-file-envelope"); expect(summary.valuesPrinted).toBe(false); expect(JSON.stringify(summary)).not.toContain("payload-$HOME"); }); test("Gitea remote runner consumes materialized files instead of base64 environment variables", () => { const source = readFileSync(remoteScriptPath, "utf8"); expect(source).toContain('unidesk_gitea_materialize_payloads "$tmp"'); expect(source).toContain('$tmp/gitea.k8s.yaml'); expect(source).toContain('$tmp/repos.json'); expect(source).not.toContain("UNIDESK_GITEA_MANIFEST_B64"); expect(source).not.toContain("UNIDESK_GITEA_STATUS_EVALUATOR_B64"); expect(source).not.toContain("UNIDESK_GITEA_REPOS_B64"); expect(source).not.toContain("UNIDESK_GITEA_FRPC_TOML_B64"); expect(source).toContain("kubectl apply --server-side --force-conflicts --dry-run=server"); expect(source).toContain("target server dry-run failed; manifest apply skipped"); expect(source.indexOf("kubectl apply --server-side --force-conflicts --dry-run=server")).toBeLessThan( source.lastIndexOf('timeout "$UNIDESK_GITEA_WAIT_TIMEOUT_SECONDS" kubectl apply --server-side --force-conflicts'), ); });