#!/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")); // #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; })(); if (current.build === build) { // 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. console.log(`[update-version] build unchanged: ${build}`); } else { deployCount += 1; const version = `${baseVersion}.${deployCount}`; const next = { baseVersion, version, build, deployCount }; writeFileSync(versionPath, JSON.stringify(next, null, 2) + "\n"); console.log( `[update-version] ${current.build} -> ${build} | ${current.version ?? ""} -> ${version}`, ); }