fix(telegram): stage full proof artifacts safely

This commit is contained in:
Vincent Koc
2026-06-20 18:47:02 +02:00
parent 1989726eb6
commit 32cbaecd09
2 changed files with 64 additions and 1 deletions

View File

@@ -1930,6 +1930,35 @@ function writeSession(pathname: string, session: SessionFile) {
fs.chmodSync(pathname, 0o600);
}
const FULL_ARTIFACT_JSON_NAMES = new Set([
"probe.json",
"status.json",
"telegram-user-crabbox-proof-summary.json",
"telegram-user-crabbox-session-summary.json",
]);
const FULL_ARTIFACT_FILE_EXTENSIONS = new Set([".gif", ".log", ".md", ".mp4", ".png"]);
export function stageFullSessionArtifacts(outputDir: string) {
const publishDir = path.join(outputDir, "publish-full-artifacts");
fs.rmSync(publishDir, { force: true, recursive: true });
fs.mkdirSync(publishDir, { recursive: true });
for (const entry of fs.readdirSync(outputDir, { withFileTypes: true })) {
if (!entry.isFile()) {
continue;
}
const extension = path.extname(entry.name);
const isPublishableArtifact =
FULL_ARTIFACT_FILE_EXTENSIONS.has(extension) || FULL_ARTIFACT_JSON_NAMES.has(entry.name);
if (!isPublishableArtifact) {
continue;
}
fs.copyFileSync(path.join(outputDir, entry.name), path.join(publishDir, entry.name));
}
return publishDir;
}
function readSession(root: string, opts: Options, outputDir: string) {
const pathname = sessionPath(root, opts, outputDir);
if (!fs.existsSync(pathname)) {
@@ -2462,7 +2491,7 @@ async function publishSessionArtifacts(root: string, opts: Options, outputDir: s
);
const publishGifPath = fs.existsSync(croppedMotionGifPath) ? croppedMotionGifPath : motionGifPath;
const publishDir = opts.publishFullArtifacts
? session.outputDir
? stageFullSessionArtifacts(session.outputDir)
: path.join(session.outputDir, "publish-gif-only");
if (!opts.publishFullArtifacts) {
if (!fs.existsSync(publishGifPath)) {

View File

@@ -18,6 +18,7 @@ import {
renderRemoteSetup,
renderSelectDesktopChat,
runCommand,
stageFullSessionArtifacts,
startLocalSut,
waitForLog,
} from "../../scripts/e2e/telegram-user-crabbox-proof.ts";
@@ -210,6 +211,39 @@ describe("telegram user Crabbox proof log polling", () => {
expect(renderSelectDesktopChat({ chatTitle: payload })).toContain(`chat_title='${payload}'`);
});
it("stages full publish artifacts without session control files", () => {
const outputDir = makeTempDir();
const publishDir = path.join(outputDir, "publish-full-artifacts");
fs.mkdirSync(publishDir);
fs.writeFileSync(path.join(publishDir, "stale.txt"), "stale");
fs.mkdirSync(path.join(outputDir, "publish-gif-only"));
fs.writeFileSync(path.join(outputDir, "session.json"), '{"sshKey":"/private/tmp/openclaw/key"}');
fs.writeFileSync(path.join(outputDir, "lease.json"), '{"token":"secret"}');
fs.writeFileSync(path.join(outputDir, "status.json"), '{"ok":true}');
fs.writeFileSync(path.join(outputDir, "probe.json"), '{"ok":true}');
fs.writeFileSync(path.join(outputDir, "telegram-user-crabbox-session-summary.json"), "{}");
fs.writeFileSync(path.join(outputDir, "telegram-user-crabbox-proof.md"), "report");
fs.writeFileSync(path.join(outputDir, "telegram-desktop.log"), "log");
fs.writeFileSync(path.join(outputDir, "telegram-user-crabbox-session-motion.gif"), "gif");
fs.writeFileSync(path.join(outputDir, "telegram-user-crabbox-session.mp4"), "video");
const stagedDir = stageFullSessionArtifacts(outputDir);
expect(stagedDir).toBe(publishDir);
expect(fs.readdirSync(stagedDir).sort()).toEqual([
"probe.json",
"status.json",
"telegram-desktop.log",
"telegram-user-crabbox-proof.md",
"telegram-user-crabbox-session-motion.gif",
"telegram-user-crabbox-session-summary.json",
"telegram-user-crabbox-session.mp4",
]);
expect(fs.existsSync(path.join(stagedDir, "session.json"))).toBe(false);
expect(fs.existsSync(path.join(stagedDir, "lease.json"))).toBe(false);
expect(fs.existsSync(path.join(stagedDir, "stale.txt"))).toBe(false);
});
posixIt("does not expand generated remote probe arguments in the shell", () => {
const root = makeTempDir();
const fakePython = path.join(root, "python3");