Files
openclaw/test/scripts/apple-release-source-check.test.ts
Peter Steinberger 7fe004d852 feat: show build identity in About screens (#103595)
* feat: show build identity in About screens

* chore: leave root changelog to release automation

* fix: translate Control UI About build details
2026-07-10 10:42:36 +01:00

93 lines
3.4 KiB
TypeScript

import { execFileSync, spawnSync } from "node:child_process";
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import path from "node:path";
import { afterEach, describe, expect, it } from "vitest";
const SCRIPT = path.join(process.cwd(), "scripts", "apple-release-source-check.sh");
const BASH_BIN = process.platform === "win32" ? "bash" : "/bin/bash";
const tempDirs: string[] = [];
function makeRepository(): { root: string; commit: string } {
const root = mkdtempSync(path.join(tmpdir(), "openclaw-apple-release-source-"));
tempDirs.push(root);
execFileSync("git", ["init", "--quiet"], { cwd: root });
execFileSync("git", ["config", "user.email", "release-test@openclaw.test"], { cwd: root });
execFileSync("git", ["config", "user.name", "OpenClaw Release Test"], { cwd: root });
writeFileSync(path.join(root, "tracked.txt"), "clean\n", "utf8");
execFileSync("git", ["add", "tracked.txt"], { cwd: root });
execFileSync("git", ["-c", "commit.gpgsign=false", "commit", "--quiet", "-m", "initial"], {
cwd: root,
});
const commit = execFileSync("git", ["rev-parse", "HEAD"], {
cwd: root,
encoding: "utf8",
}).trim();
return { root, commit };
}
function runCheck(root: string, commit: string) {
const args = process.platform === "win32" ? [SCRIPT] : ["--noprofile", "--norc", SCRIPT];
return spawnSync(BASH_BIN, [...args, "--root", root, "--expected-commit", commit], {
cwd: process.cwd(),
encoding: "utf8",
});
}
afterEach(() => {
for (const dir of tempDirs.splice(0)) {
rmSync(dir, { recursive: true, force: true });
}
});
describe("Apple release source check", () => {
it("accepts a matching full commit from a clean checkout", () => {
const repository = makeRepository();
const result = runCheck(repository.root, repository.commit.toUpperCase());
expect(result.status).toBe(0);
expect(result.stdout).toContain(
`Verified Apple release source: commit=${repository.commit} clean=true`,
);
});
it("rejects release metadata from a different commit", () => {
const repository = makeRepository();
const mismatch = `${repository.commit[0] === "a" ? "b" : "a"}${repository.commit.slice(1)}`;
const result = runCheck(repository.root, mismatch);
expect(result.status).toBe(1);
expect(result.stderr).toContain(
`Apple release commit mismatch: metadata ${mismatch}, checkout ${repository.commit}.`,
);
});
it("rejects tracked, staged, and untracked release checkout changes", () => {
const fixtures = [
() => {
const repository = makeRepository();
writeFileSync(path.join(repository.root, "tracked.txt"), "dirty\n", "utf8");
return repository;
},
() => {
const repository = makeRepository();
writeFileSync(path.join(repository.root, "staged.txt"), "staged\n", "utf8");
execFileSync("git", ["add", "staged.txt"], { cwd: repository.root });
return repository;
},
() => {
const repository = makeRepository();
writeFileSync(path.join(repository.root, "untracked.txt"), "untracked\n", "utf8");
return repository;
},
];
for (const makeFixture of fixtures) {
const repository = makeFixture();
const result = runCheck(repository.root, repository.commit);
expect(result.status).toBe(1);
expect(result.stderr).toContain("Apple release builds require a clean Git checkout.");
}
});
});