fix(e2e): clean failed tarball extracts

This commit is contained in:
Vincent Koc
2026-06-03 11:18:54 +02:00
parent 84dca54ef2
commit 1e4ff80604
3 changed files with 53 additions and 2 deletions

View File

@@ -59,6 +59,7 @@ Docs: https://docs.openclaw.ai
- Release/CI/E2E: write package Telegram Docker artifacts to unique per-run directories by default so parallel live/RTT runs cannot overwrite evidence.
- Release/CI/E2E: fail secret-provider proof runs when temporary state cleanup still fails after retries instead of hiding the cleanup error.
- Release/CI/E2E: fail package-candidate ref proofs when temporary source worktree cleanup fails instead of leaving stale worktrees behind.
- Release/CI/E2E: remove package tarball extract directories when tar extraction fails before validation can continue.
- Release/CI/E2E: retry generated temp-state cleanup after removal failures and route plugin lifecycle measurement edits to their owner tests.
- Release/CI/E2E: close parent gateway log handles after spawning RPC RTT probes so repeated measurements do not leak file descriptors.
- Release/CI/E2E: fail RPC RTT probes when temporary state cleanup fails instead of hiding leftover scratch directories.

View File

@@ -63,6 +63,7 @@ try {
}),
);
if (extract.status !== 0) {
fs.rmSync(extractDir, { recursive: true, force: true });
fail(`tar -xf failed for ${tarball}: ${extract.stderr || extract.status}`);
}
} catch (error) {

View File

@@ -1,7 +1,15 @@
import { spawnSync } from "node:child_process";
import { mkdtempSync, rmSync, mkdirSync, writeFileSync } from "node:fs";
import {
chmodSync,
existsSync,
mkdtempSync,
mkdirSync,
readFileSync,
rmSync,
writeFileSync,
} from "node:fs";
import { tmpdir } from "node:os";
import { dirname, join } from "node:path";
import { delimiter, dirname, join } from "node:path";
import { describe, expect, it } from "vitest";
import { LOCAL_BUILD_METADATA_DIST_PATHS } from "../../scripts/lib/local-build-metadata-paths.mjs";
@@ -67,6 +75,47 @@ function withTarball(
}
describe("check-openclaw-package-tarball", () => {
it.runIf(process.platform !== "win32")("removes the extract dir when tar extraction fails", () => {
const root = mkdtempSync(join(tmpdir(), "openclaw-package-tarball-extract-fail-"));
try {
const fakeBin = join(root, "bin");
mkdirSync(fakeBin);
const extractDirFile = join(root, "extract-dir.txt");
const fakeTar = join(fakeBin, "tar");
writeFileSync(
fakeTar,
[
"#!/usr/bin/env node",
"const fs = require('node:fs');",
"const args = process.argv.slice(2);",
"if (args[0] === '-tf') { console.log('package/package.json'); process.exit(0); }",
"const outputDir = args[args.indexOf('-C') + 1];",
"fs.writeFileSync(process.env.OPENCLAW_TEST_EXTRACT_DIR_FILE, outputDir);",
"console.error('extract denied');",
"process.exit(7);",
].join("\n"),
);
chmodSync(fakeTar, 0o755);
const tarball = join(root, "openclaw.tgz");
writeFileSync(tarball, "not used by fake tar");
const result = spawnSync("node", [CHECK_SCRIPT, tarball], {
encoding: "utf8",
env: {
...process.env,
OPENCLAW_TEST_EXTRACT_DIR_FILE: extractDirFile,
PATH: `${fakeBin}${delimiter}${process.env.PATH ?? ""}`,
},
});
expect(result.status).not.toBe(0);
expect(result.stderr).toContain("extract denied");
expect(existsSync(readFileSync(extractDirFile, "utf8"))).toBe(false);
} finally {
rmSync(root, { recursive: true, force: true });
}
});
it("allows legacy private QA inventory entries omitted from shipped tarballs through 2026.4.25", () => {
withTarball(
["dist/index.js", "dist/extensions/qa-channel/runtime-api.js"],