mirror of
https://github.com/openclaw/openclaw.git
synced 2026-10-03 17:53:39 +00:00
* feat(telegram): add isolated Test Server proof workflow Add maintainer-only exact-head admission, durable at-most-once QA lease consumption, isolated candidate execution, and normalized trusted Telegram Test Server observations. Co-authored-by: brokemac79 <255583030+brokemac79@users.noreply.github.com> * feat(proof): bind named Web UI and canonical Telegram QA evidence Reuse the existing formatting QA recipe, preserve isolated exact-candidate execution and produce the consumer request-bound receipt. Keep named smoke scenarios distinct and protect stationary harness ancestry. Co-authored-by: brokemac79 <255583030+brokemac79@users.noreply.github.com> * fix(proof): complete isolated QA execution and bounded failure capture Reuse canonical ephemeral device pairing and QA RPC scopes, preserve strict startup probes and recorder locks, and retain bounded wrong-text attempts without Telegram delivery. Co-authored-by: brokemac79 <255583030+brokemac79@users.noreply.github.com> * fix(mantis): revoke proof forwarding and enforce lease roles * fix(mantis): close proof producer CI gates * test(mantis): consolidate related proof suites within CI budget * test(mantis): preserve fast QA ownership when grouping integration cases * fix(mantis): accept exact branch-qualified workflow paths * fix(mantis): align live admission workflow path checks * feat(mantis): collect selected proof inside the originating review * fix(mantis): bound proof storage and preserve failure evidence Reuse verified storage across request-bound candidates, reserve backing capacity, retain sanitized rejection evidence, and repair cleanup and observation finalization. Scoped checks and dirty review pass; full Gateway and sandboxed browser runtime proof remain required before publication. * fix(mantis): retain bridge identity before startup * fix(mantis): keep candidate config readable under private umask * fix(qa): use verified rootless networking and join candidate shutdown * fix(qa): repair proof tooling checks and deterministic recorder fixture --------- Co-authored-by: brokemac79 <255583030+brokemac79@users.noreply.github.com>
125 lines
3 KiB
TypeScript
125 lines
3 KiB
TypeScript
#!/usr/bin/env node
|
|
// Secretless exact-source preparation; never acquire a Telegram credential here.
|
|
import { execFileSync } from "node:child_process";
|
|
import { randomUUID } from "node:crypto";
|
|
const [
|
|
candidate,
|
|
baseImage = "localhost/mantis-telegram-proof",
|
|
targetImage = "localhost/mantis-telegram-runtime",
|
|
] = process.argv.slice(2);
|
|
if (
|
|
!candidate ||
|
|
!/^[a-f0-9]{40}$/.test(candidate) ||
|
|
![baseImage, targetImage].every((name) => /^[a-z0-9][a-z0-9/.:@-]*$/.test(name))
|
|
) {
|
|
throw new Error(
|
|
"Usage: prepare-request-telegram.mts <sha> [trusted-telegram-image] [output-image]",
|
|
);
|
|
}
|
|
execFileSync(
|
|
"git",
|
|
[
|
|
"diff",
|
|
"--quiet",
|
|
"HEAD",
|
|
candidate,
|
|
"--",
|
|
"package.json",
|
|
":(glob)**/package.json",
|
|
"pnpm-lock.yaml",
|
|
"pnpm-workspace.yaml",
|
|
".npmrc",
|
|
".pnpmfile.cjs",
|
|
"patches",
|
|
],
|
|
{ stdio: "pipe" },
|
|
);
|
|
const name = `mantis-telegram-build-${randomUUID()}`;
|
|
const versionName = `mantis-telegram-version-${randomUUID()}`;
|
|
const podman = (args: string[], input?: Buffer) =>
|
|
execFileSync("podman", args, { input, maxBuffer: 1024 * 1024 * 1024, timeout: 1200_000 });
|
|
try {
|
|
podman([
|
|
"create",
|
|
"--name",
|
|
name,
|
|
"--network",
|
|
"none",
|
|
"--cap-drop",
|
|
"ALL",
|
|
"--security-opt",
|
|
"no-new-privileges",
|
|
"--pids-limit",
|
|
"1024",
|
|
"--memory",
|
|
"16g",
|
|
"--cpus",
|
|
"2",
|
|
"--env",
|
|
`GITHUB_SHA=${candidate}`,
|
|
"--env",
|
|
"OPENCLAW_BUILD_PRIVATE_QA=1",
|
|
"--env",
|
|
"OPENCLAW_TSDOWN_MAX_OLD_SPACE_MB=8192",
|
|
"--workdir",
|
|
"/candidate",
|
|
baseImage,
|
|
"sh",
|
|
"-c",
|
|
"corepack pnpm install --offline --frozen-lockfile && corepack pnpm build && test -s dist/entry.js",
|
|
]);
|
|
podman(
|
|
["cp", "-", `${name}:/candidate`],
|
|
execFileSync("git", ["archive", "--format=tar", candidate], { maxBuffer: 1024 * 1024 * 1024 }),
|
|
);
|
|
podman(["start", "--attach", name]);
|
|
const state = JSON.parse(podman(["inspect", "--format", "{{json .State}}", name]).toString());
|
|
if (state.Running || state.ExitCode !== 0) {
|
|
throw new Error("Candidate runtime build failed");
|
|
}
|
|
podman([
|
|
"commit",
|
|
"--change",
|
|
`LABEL org.openclaw.mantis.candidate-sha=${candidate}`,
|
|
"--change",
|
|
"WORKDIR /candidate",
|
|
name,
|
|
targetImage,
|
|
]);
|
|
podman([
|
|
"run",
|
|
"--name",
|
|
versionName,
|
|
"--memory",
|
|
"8g",
|
|
"--cpus",
|
|
"2",
|
|
"--pids-limit",
|
|
"512",
|
|
"--network",
|
|
"none",
|
|
"--cap-drop",
|
|
"ALL",
|
|
"--security-opt",
|
|
"no-new-privileges",
|
|
targetImage,
|
|
"node",
|
|
"dist/entry.js",
|
|
"--version",
|
|
]);
|
|
console.log(
|
|
JSON.stringify({
|
|
candidate_sha: candidate,
|
|
image: targetImage,
|
|
image_id: podman(["image", "inspect", "--format", "{{.Id}}", targetImage]).toString().trim(),
|
|
runtime_entry: "/candidate/dist/entry.js",
|
|
lease_acquired: false,
|
|
}),
|
|
);
|
|
} finally {
|
|
try {
|
|
podman(["rm", "--force", "--ignore", versionName]);
|
|
} finally {
|
|
podman(["rm", "--force", "--ignore", name]);
|
|
}
|
|
}
|