fix: make packaged updater handshake Windows-safe
ForgeFlow quality gate / quality (push) Canceled after 0s

This commit is contained in:
NuklearRabbit
2026-08-01 15:09:47 +02:00
parent 44aa452a76
commit acad1f8932
10 changed files with 91 additions and 25 deletions
+27 -1
View File
@@ -6,7 +6,11 @@ import path from "node:path";
import { createRequire } from "node:module";
import { EventEmitter } from "node:events";
import { createHash } from "node:crypto";
import { execFile } from "node:child_process";
import { promisify } from "node:util";
import { fileURLToPath } from "node:url";
const require = createRequire(import.meta.url);
const execFileAsync = promisify(execFile);
const {
UpdateService,
waitForUpdaterStarted,
@@ -318,7 +322,7 @@ test("PowerShell helper replaces an existing launching status with a Windows-saf
);
assert.match(
script,
/System\.IO\.File\]::Replace\(\$temporary, \$StatusPath, \$null\)/,
/System\.IO\.File\]::Replace\(\$temporary, \$StatusPath, \$backup\)/,
);
assert.match(
script,
@@ -332,6 +336,28 @@ test("PowerShell helper replaces an existing launching status with a Windows-saf
assert.match(script, /Handshake-only verification completed successfully/);
});
test("binary helper confirms startup through real Windows PowerShell", { skip: process.platform !== "win32" }, async () => {
const temp = await mkdtemp(path.join(os.tmpdir(), "forgeflow-binary-handshake-"));
const statusPath = path.join(temp, "status.json");
const logPath = path.join(temp, "helper.log");
await writeFile(statusPath, JSON.stringify({ state: "launching", updateId: "binary-handshake" }));
const powershell = path.join(process.env.SystemRoot || process.env.WINDIR, "System32", "WindowsPowerShell", "v1.0", "powershell.exe");
const scriptPath = fileURLToPath(new URL("../scripts/apply-binary-update.ps1", import.meta.url));
const { stdout, stderr } = await execFileAsync(powershell, [
"-NoLogo", "-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-File", scriptPath,
"-BinaryPath", path.join(temp, "unused.exe"), "-ExpectedSha256", "0".repeat(64),
"-ExpectedVersion", "9.9.9", "-CurrentExecutable", path.join(temp, "unused-current.exe"),
"-Portable", "False", "-ParentPid", "999999", "-LogPath", logPath,
"-StatusPath", statusPath, "-UpdateId", "binary-handshake", "-HandshakeOnly"
], { windowsHide: true });
assert.equal(stdout, "");
assert.equal(stderr, "");
const status = JSON.parse(await readFile(statusPath, "utf8"));
assert.equal(status.updateId, "binary-handshake");
assert.equal(status.state, "started");
assert.match(await readFile(logPath, "utf8"), /Handshake-only verification completed successfully/);
await rm(temp, { recursive: true, force: true });
});
test("early helper exit reports the helper log instead of only an exit code", async () => {
const temp = await mkdtemp(
path.join(os.tmpdir(), "forgeflow-update-log-tail-"),