Files
periscope/frontend/scripts/sync-version.mjs
T
Siddharth Kothari 6672d2be57 Pinscope open-source core
Agentic schematic validation: datasheet extraction via Claude Console
Skills, netlist/BOM design graph, per-IC direct datasheet review with
page citations, capacitor derating, Next.js report UI.

Extracted from the Pinscope cloud codebase. Auth and billing live in the
private gateway repo behind stable seams (billing_hook.py, adapter files
listed in CLAUDE.md).
2026-07-16 21:29:45 -07:00

69 lines
2.3 KiB
JavaScript

#!/usr/bin/env node
/**
* Single source of truth for the app version: content/changelog.md.
*
* Parses the topmost `## X.Y.Z — <date>` heading and propagates it to:
* - src/lib/version.ts (APP_VERSION, shown in the UI sidebar)
* - package.json ("version" field)
*
* Runs automatically via the `predev` / `prebuild` npm hooks, so the
* sidebar version, package.json, and the changelog can never drift.
* To cut a release, just add a new `## X.Y.Z — <date>` section at the
* top of content/changelog.md.
*/
import { readFileSync, writeFileSync } from "node:fs";
import { fileURLToPath } from "node:url";
import { dirname, join } from "node:path";
const root = join(dirname(fileURLToPath(import.meta.url)), "..");
const changelogPath = join(root, "content", "changelog.md");
const versionTsPath = join(root, "src", "lib", "version.ts");
const pkgPath = join(root, "package.json");
const changelog = readFileSync(changelogPath, "utf-8");
const match = changelog.match(
/^##\s+(\d+\.\d+\.\d+)(?:\s+[—-]\s+(\d{4}-\d{2}-\d{2}))?/m,
);
if (!match) {
console.error(
`[sync-version] No "## X.Y.Z" heading found in ${changelogPath}`,
);
process.exit(1);
}
const version = match[1];
const versionDate = match[2] ?? "";
// --- src/lib/version.ts (generated; do not edit by hand) ---------------
const versionTs = `// AUTO-GENERATED by scripts/sync-version.mjs from content/changelog.md.
// Do not edit by hand — change the top "## X.Y.Z" heading in the changelog.
export const APP_VERSION = "${version}";
export const APP_VERSION_DATE = "${versionDate}";
`;
let tsChanged = false;
try {
tsChanged = readFileSync(versionTsPath, "utf-8") !== versionTs;
} catch {
tsChanged = true;
}
if (tsChanged) writeFileSync(versionTsPath, versionTs);
// --- package.json "version" -------------------------------------------
const pkgRaw = readFileSync(pkgPath, "utf-8");
const pkg = JSON.parse(pkgRaw);
const pkgChanged = pkg.version !== version;
if (pkgChanged) {
pkg.version = version;
writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
}
if (tsChanged || pkgChanged) {
console.log(
`[sync-version] Synced to ${version} (` +
`${tsChanged ? "version.ts" : ""}` +
`${tsChanged && pkgChanged ? " + " : ""}` +
`${pkgChanged ? "package.json" : ""}).`,
);
} else {
console.log(`[sync-version] Already at ${version}.`);
}