Files
purpur-sentinel/scripts/publish-release.test.ts
T
dmg b211e9d337
CI / build (pull_request) Successful in 1m16s
CI / build (push) Successful in 3m24s
feat(sentinel): alert on repeated suspicious movement
2026-10-29 08:28:27 -04:00

81 lines
3.7 KiB
TypeScript

import assert from "node:assert/strict";
import { spawnSync } from "node:child_process";
import { test } from "node:test";
import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from "node:fs";
import { tmpdir } from "node:os";
import { join, resolve } from "node:path";
const fixture = "synthetic-cli-fixture";
const entrypoint = resolve("build/release-tools/publish-release.js");
function runPublication(mode: "success" | "transport" | "missing") {
const dir = mkdtempSync(join(tmpdir(), "sentinel-cli-"));
try {
mkdirSync(join(dir, "build/libs"), { recursive: true });
if (mode !== "missing") writeFileSync(join(dir, "build/libs/purpur-sentinel-1.2.3.jar"), Buffer.from([80, 75, 3, 4]));
// A process-local fake at the HTTP boundary: these tests must never contact Gitea.
const preload = join(dir, "http-fixture.mjs");
writeFileSync(preload, `
import assert from 'node:assert/strict';
let calls = 0;
globalThis.fetch = async (url, init) => {
calls++;
assert.equal(new Headers(init.headers).get('authorization'), 'token ' + process.env.RELEASE_CREDENTIAL);
assert.equal(init.redirect, 'error');
assert.ok(!url.includes(process.env.RELEASE_CREDENTIAL));
if (process.env.FIXTURE_MODE === 'transport') throw new Error(process.env.RELEASE_CREDENTIAL);
if (calls === 1) {
const body = JSON.parse(init.body);
assert.equal(body.target_commitish, 'a'.repeat(40));
assert.equal(body.body, 'Fixture notes');
assert.equal(body.draft, true);
} else if (calls === 2) {
assert.deepEqual(new Uint8Array(init.body), new Uint8Array([80, 75, 3, 4]));
assert.ok(url.endsWith('/42/assets?name=purpur-sentinel-1.2.3.jar'));
} else {
assert.equal(calls, 3);
assert.equal(init.method, 'PATCH');
}
return Response.json({id:42, draft: calls !== 3, tag_name:'v1.2.3', name:'purpur-sentinel-1.2.3.jar', size:4});
};
if (process.env.FIXTURE_MODE === 'success') process.on('exit', () => assert.equal(calls, 3));
`);
return spawnSync(process.execPath, ["--import", preload, entrypoint], {
cwd: dir, encoding: "utf8", env: {
VERSION: "1.2.3", RELEASE_COMMIT: "a".repeat(40), RELEASE_CREDENTIAL: fixture,
RELEASE_NOTES: "Fixture notes", FIXTURE_MODE: mode,
},
});
} finally { rmSync(dir, { recursive: true, force: true }); }
}
test("CLI reads only the exact versioned JAR and reports completed publication", () => {
const child = runPublication("success");
assert.equal(child.status, 0, child.stderr);
assert.equal(child.stdout, "Published purpur-sentinel v1.2.3.\n");
assert.equal(child.stderr, "");
});
for (const mode of ["transport", "missing"] as const) {
test(`CLI sanitizes ${mode} failures and never claims publication`, () => {
const child = runPublication(mode);
assert.equal(child.status, 1);
assert.equal(child.stdout, "");
assert.equal(child.stderr, "Release publication failed; inspect the release state before retrying.\n");
});
}
for (const environment of [
{ VERSION: "1.2.3", RELEASE_COMMIT: "a".repeat(40) },
{ VERSION: "../../outside", RELEASE_CREDENTIAL: "synthetic-cli-fixture", RELEASE_COMMIT: "a".repeat(40) },
]) {
test(`CLI fails closed on invalid input without echoing environment: ${Object.keys(environment)}`, () => {
const child = spawnSync(process.execPath, ["build/release-tools/publish-release.js"], {
encoding: "utf8", env: environment,
});
assert.equal(child.status, 1);
assert.equal(child.stdout, "");
assert.equal(child.stderr, "Release publication failed; inspect the release state before retrying.\n");
});
}