2026-05-17 15:16:02 +00:00
|
|
|
#!/usr/bin/env node
|
|
|
|
|
import { execSync } from "node:child_process";
|
|
|
|
|
import { readFileSync, writeFileSync } from "node:fs";
|
|
|
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
|
import { dirname, resolve } from "node:path";
|
|
|
|
|
|
|
|
|
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
|
|
|
const versionPath = resolve(__dirname, "..", "version.json");
|
|
|
|
|
|
|
|
|
|
function git(args) {
|
|
|
|
|
return execSync(`git ${args}`, { encoding: "utf8" }).trim();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let commit = "unknown";
|
|
|
|
|
let date = new Date().toISOString().slice(0, 10).replace(/-/g, "");
|
|
|
|
|
try {
|
|
|
|
|
commit = git("log -1 --format=%h");
|
|
|
|
|
date = git("log -1 --format=%cd --date=format:%Y%m%d");
|
|
|
|
|
} catch (err) {
|
|
|
|
|
console.warn(`[update-version] git unavailable, using fallback: ${err.message}`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const build = `${date}.${commit}`;
|
|
|
|
|
const current = JSON.parse(readFileSync(versionPath, "utf8"));
|
2026-05-18 12:24:05 +00:00
|
|
|
|
|
|
|
|
// #597: derive the stable base from the existing `version` field on
|
|
|
|
|
// first run so older repos migrate cleanly. e.g. "0.1.0-dev.5" -> base
|
|
|
|
|
// "0.1.0-dev", count 5. A bare "0.1.0-dev" (no trailing .N) just stays
|
|
|
|
|
// the base and starts counting from the current deployCount (or 0).
|
|
|
|
|
const TRAILING_COUNTER = /\.(\d+)$/;
|
|
|
|
|
function deriveBase(versionStr) {
|
|
|
|
|
if (typeof versionStr !== "string" || versionStr.length === 0) {
|
|
|
|
|
return "0.1.0-dev";
|
|
|
|
|
}
|
|
|
|
|
const m = versionStr.match(TRAILING_COUNTER);
|
|
|
|
|
return m ? versionStr.slice(0, -m[0].length) : versionStr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const baseVersion =
|
|
|
|
|
typeof current.baseVersion === "string" && current.baseVersion.length > 0
|
|
|
|
|
? current.baseVersion
|
|
|
|
|
: deriveBase(current.version);
|
|
|
|
|
|
|
|
|
|
let deployCount = Number.isInteger(current.deployCount)
|
|
|
|
|
? current.deployCount
|
|
|
|
|
: (() => {
|
|
|
|
|
// Seed from the trailing counter on the existing version string
|
|
|
|
|
// so first migration doesn't reset progress to 0 if the user had
|
|
|
|
|
// already been numbering manually (e.g. "0.1.0-dev.12").
|
|
|
|
|
const m =
|
|
|
|
|
typeof current.version === "string"
|
|
|
|
|
? current.version.match(TRAILING_COUNTER)
|
|
|
|
|
: null;
|
|
|
|
|
return m ? parseInt(m[1], 10) : 0;
|
|
|
|
|
})();
|
2026-05-17 15:16:02 +00:00
|
|
|
|
|
|
|
|
if (current.build === build) {
|
2026-05-18 12:24:05 +00:00
|
|
|
// No new commit since last run -> nothing to do. Don't bump the
|
|
|
|
|
// counter and don't rewrite the file. This matches pre-#597 behaviour
|
|
|
|
|
// so re-running the build twice in CI doesn't inflate the counter.
|
2026-05-17 15:16:02 +00:00
|
|
|
console.log(`[update-version] build unchanged: ${build}`);
|
|
|
|
|
} else {
|
2026-05-18 12:24:05 +00:00
|
|
|
deployCount += 1;
|
|
|
|
|
const version = `${baseVersion}.${deployCount}`;
|
|
|
|
|
const next = { baseVersion, version, build, deployCount };
|
2026-05-17 15:16:02 +00:00
|
|
|
writeFileSync(versionPath, JSON.stringify(next, null, 2) + "\n");
|
2026-05-18 12:24:05 +00:00
|
|
|
console.log(
|
|
|
|
|
`[update-version] ${current.build} -> ${build} | ${current.version ?? "<none>"} -> ${version}`,
|
|
|
|
|
);
|
2026-05-17 15:16:02 +00:00
|
|
|
}
|