import test from "node:test"; import assert from "node:assert/strict"; import { execFileSync, spawnSync } from "node:child_process"; import { lstatSync, readFileSync, readlinkSync } from "node:fs"; const UPSTREAM = "dc4c398d5167865b84b0ccb3ec809eb88bf8f65f"; const FORK_HEAD = "83f5f590155fe349f80a0e09ba10295e7bbee5d0"; const LOCAL_TAG = "b7f41a6b76578427d2d121ada02f80da49297423"; const LOCAL_TAG_COMMIT = "2da091d6e9df841476fe0812c5b3baee163e196c"; const git = (...args) => execFileSync("git", args, { encoding: "utf8", timeout: 30_000 }); const isProjectPath = (path) => !/(^|\/)(?:\.gsd|\.planning|\.audits|\.gitignore|node_modules)(?:\/|$)/.test(path); const tracked = new Set(git("ls-files", "-z").split("\0").filter((path) => path && isProjectPath(path))); function source(path) { assert.ok(tracked.has(path), `Not a tracked project file: ${path}`); return readFileSync(path, "utf8"); } const marker = /^(?:<{7}(?: |$)|={7}$|>{7}(?: |$)|\|{7}(?: |$))/m; function assertRelease(manifest, lock) { assert.equal(manifest.version, "0.6.0"); assert.equal(lock.version, "0.6.0"); assert.equal(lock.packages[""].version, "0.6.0"); const command = manifest.scripts["desktop:release:linux"]; assert.match(command, /electron-builder --config electron-builder\.gitea\.yml --linux --x64 --publish never(?:\s|$)/); } function assertUpstream(commit) { assert.equal(commit, UPSTREAM); assert.equal(git("cat-file", "-t", commit).trim(), "commit"); } test("merge has no unmerged index entries", () => { assert.equal(git("ls-files", "-u"), ""); }); test("tracked project files have no conflict marker lines", () => { // Scan only tracked project files, never workflow or ignored local artifacts. for (const path of tracked) { // Git tracks a symlink's target text, not the directory/file it points // into. Never follow skill links into ignored or external artifacts. const data = lstatSync(path).isSymbolicLink() ? Buffer.from(readlinkSync(path)) : readFileSync(path); if (data.includes(0)) continue; // binary assets are not source marker candidates assert.equal(marker.test(data.toString("utf8")), false, `Conflict marker in ${path}`); } }); test("release retains fork version and local-only Linux/Gitea command", () => { assertRelease(JSON.parse(source("package.json")), JSON.parse(source("package-lock.json"))); }); test("Gitea updater identity and release tooling are preserved", () => { const config = source("electron-builder.gitea.yml"); assert.match(config, /extends: \.\/electron-builder\.yml/); assert.match(config, /provider: generic/); assert.match(config, /url: https:\/\/git\.sorokin-oleg-edu\.xyz\/sorokin\.oleg\.edu\/learnharness\/releases\/download\/latest/); assert.ok(tracked.has("scripts/gitea-release.mjs")); }); test("exact upstream exists without moving the distinct local v0.4.0 tag", () => { assertUpstream(UPSTREAM); assert.equal(git("rev-parse", "refs/tags/v0.4.0").trim(), LOCAL_TAG); assert.equal(git("rev-parse", "refs/tags/v0.4.0^{}").trim(), LOCAL_TAG_COMMIT); assert.notEqual(LOCAL_TAG_COMMIT, UPSTREAM); }); function assertParents(parents) { assert.deepEqual(parents, [FORK_HEAD, UPSTREAM]); } test("pending or committed merge targets exactly the approved histories", () => { const pending = spawnSync("git", ["rev-parse", "-q", "--verify", "MERGE_HEAD"], { encoding: "utf8", timeout: 30_000 }); if (pending.status === 0) { assertParents([git("rev-parse", "HEAD").trim(), pending.stdout.trim()]); } else { assert.equal(pending.status, 1, pending.stderr || pending.error?.message); // Keep this regression valid after later commits: the exact two-parent // integration commit must remain in HEAD's ancestry, not be HEAD forever. const parents = git("log", "--ancestry-path", "--merges", "--format=%P", `${FORK_HEAD}..HEAD`).trim().split("\n"); assert.ok(parents.includes(`${FORK_HEAD} ${UPSTREAM}`), "Exact upstream merge missing from HEAD ancestry"); git("merge-base", "--is-ancestor", UPSTREAM, "HEAD"); } }); test("audit guards reject markers, wrong versions and wrong targets using inline fixtures", () => { for (const line of ["<<<<<<< ours", "=======", ">>>>>>> theirs", "||||||| base"]) assert.ok(marker.test(line)); assert.equal(marker.test("ordinary source"), false); const manifest = { version: "0.6.0", scripts: { "desktop:release:linux": "electron-builder --config electron-builder.gitea.yml --linux --x64 --publish never" } }; const lock = { version: "0.6.0", packages: { "": { version: "0.6.0" } } }; assertRelease(manifest, lock); assert.throws(() => assertRelease({ ...manifest, version: "0.4.0" }, lock)); assert.throws(() => assertRelease(manifest, { ...lock, version: "0.4.0" })); assert.throws(() => assertRelease(manifest, { ...lock, packages: { "": { version: "0.4.0" } } })); assert.throws(() => assertRelease({ ...manifest, scripts: { "desktop:release:linux": "electron-builder --publish always" } }, lock)); assert.throws(() => assertUpstream(LOCAL_TAG_COMMIT)); assert.throws(() => assertParents([FORK_HEAD, LOCAL_TAG_COMMIT])); assert.throws(() => assertParents([UPSTREAM, FORK_HEAD])); assert.throws(() => assertParents([FORK_HEAD])); assert.throws(() => source(".gsd/not-a-project-file")); });