From 1a59b8e3dccf80f765e8caaf928cbf68fbf928ab Mon Sep 17 00:00:00 2001 From: Roger Chappel Date: Wed, 9 Sep 2026 15:25:00 +1000 Subject: [PATCH 1/3] test: require manifest-derived CLI versions --- tests/version.test.mjs | 45 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 tests/version.test.mjs diff --git a/tests/version.test.mjs b/tests/version.test.mjs new file mode 100644 index 0000000..5266b3d --- /dev/null +++ b/tests/version.test.mjs @@ -0,0 +1,45 @@ +import assert from "node:assert/strict"; +import { spawnSync } from "node:child_process"; +import { cpSync, mkdtempSync, readFileSync, writeFileSync } from "node:fs"; +import os from "node:os"; +import path from "node:path"; +import test from "node:test"; +import { fileURLToPath } from "node:url"; + +const repo = path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."); + +test("built CLI reads its version from the package manifest", () => { + const fixture = mkdtempSync(path.join(os.tmpdir(), "scriptaudit-version-")); + cpSync(path.join(repo, "dist"), path.join(fixture, "dist"), { recursive: true }); + cpSync(path.join(repo, "node_modules"), path.join(fixture, "node_modules"), { recursive: true }); + writeFileSync(path.join(fixture, "package.json"), JSON.stringify({ type: "module", version: "9.8.7" })); + + const result = spawnSync(process.execPath, [path.join(fixture, "dist", "cli.js"), "--version"], { + encoding: "utf8" + }); + + assert.equal(result.status, 0, result.stderr); + assert.equal(result.stdout, "9.8.7\n"); +}); + +test("packed and installed CLI version matches the packed manifest", () => { + const fixture = mkdtempSync(path.join(os.tmpdir(), "scriptaudit-package-version-")); + const packed = spawnSync("npm", ["pack", "--json", "--pack-destination", fixture], { + cwd: repo, + encoding: "utf8" + }); + assert.equal(packed.status, 0, packed.stderr); + const tarball = path.join(fixture, JSON.parse(packed.stdout)[0].filename); + + const installed = spawnSync("npm", ["install", "--ignore-scripts", "--no-audit", "--no-fund", tarball], { + cwd: fixture, + encoding: "utf8" + }); + assert.equal(installed.status, 0, installed.stderr); + + const manifest = JSON.parse(readFileSync(path.join(fixture, "node_modules", "scriptaudit", "package.json"), "utf8")); + const cli = path.join(fixture, "node_modules", "scriptaudit", "dist", "cli.js"); + const version = spawnSync(process.execPath, [cli, "--version"], { encoding: "utf8" }); + assert.equal(version.status, 0, version.stderr); + assert.equal(version.stdout.trim(), manifest.version); +}); From bd817dd1ae30f1573d2e7a824c021ec59801d206 Mon Sep 17 00:00:00 2001 From: Roger Chappel Date: Wed, 9 Sep 2026 15:25:21 +1000 Subject: [PATCH 2/3] fix: read CLI version from package manifest --- src/cli.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cli.ts b/src/cli.ts index 42e2ec1..3d633e3 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -1,5 +1,6 @@ #!/usr/bin/env node import { promises as fs } from "node:fs"; +import { createRequire } from "node:module"; import path from "node:path"; import { Command } from "commander"; import { scanProject } from "./core/audit.js"; @@ -8,11 +9,12 @@ import { renderReport, type OutputFormat } from "./render/index.js"; import type { RiskLevel } from "./types.js"; const program = new Command(); +const { version } = createRequire(import.meta.url)("../package.json") as { version: string }; program .name("scriptaudit") .description("Audit local scripts and command docs without executing them.") - .version("0.1.0"); + .version(version); program .command("scan") From 2fd2a658dbd213e3d3ff751e38087174937c8753 Mon Sep 17 00:00:00 2001 From: Roger Chappel Date: Wed, 9 Sep 2026 15:25:38 +1000 Subject: [PATCH 3/3] docs: define single-source version verification --- docs/release-readiness.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/release-readiness.md b/docs/release-readiness.md index a05d0d9..67592db 100644 --- a/docs/release-readiness.md +++ b/docs/release-readiness.md @@ -23,6 +23,8 @@ The release workflow uses npm trusted publishing (GitHub Actions OIDC) and requi The release dry-run workflow exercises the same npm preparation and artifact handoff on relevant pull requests: it packs once and runs `npm publish --dry-run --access public`. `npm run release:workflow-check` guards both workflows against omitting or downgrading the pinned trusted-publishing npm version, repacking, or failing to reuse the artifact. +The CLI reads its version from `package.json`; there is no second version literal to update. After `npm version patch --no-git-tag-version`, `npm run release:check` verifies that the built CLI and the installed packed artifact both report the packed manifest version. + ## Notes - Keep README examples aligned with the fixture-backed smoke command.