The version is the checkout's HEAD commit (short hash + commit time), read once at startup — updates arrive as `git pull`, so there is no release number to bump. It rides on the socket hello, socket reports, and the HTTP report fallback; the field is optional in the protocol so older masters ignore it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
44 lines
1.6 KiB
TypeScript
44 lines
1.6 KiB
TypeScript
/**
|
|
* The version of the running build.
|
|
*
|
|
* Updates arrive as `git pull` (scripts/update-check.mjs), so the checkout's
|
|
* HEAD commit *is* the version — there is no release number to bump and
|
|
* nothing for anyone to forget. The commit time rides along because hashes
|
|
* don't order: it is what lets the master say which of two different
|
|
* versions is the stale one.
|
|
*
|
|
* Read once and cached: the update task restarts the process after every
|
|
* pull, so HEAD cannot move under a running build — and when it briefly does
|
|
* (pull landed, restart pending), the cached value still describes the code
|
|
* that is actually executing.
|
|
*/
|
|
|
|
import { execFileSync } from 'node:child_process';
|
|
|
|
export interface BuildVersion {
|
|
/** Short commit hash of HEAD, e.g. "c493796". */
|
|
commit: string;
|
|
/** ISO commit time of HEAD — orders versions, which hashes cannot. */
|
|
time: string;
|
|
}
|
|
|
|
let cached: BuildVersion | null | undefined;
|
|
|
|
/** null when this isn't a git checkout or git isn't installed — both mean
|
|
* "no version to report", and the master shows the machine as an old build. */
|
|
export function getBuildVersion(): BuildVersion | null {
|
|
if (cached !== undefined) return cached;
|
|
try {
|
|
const out = execFileSync('git', ['log', '-1', '--format=%h %cI'], {
|
|
cwd: process.cwd(),
|
|
encoding: 'utf8',
|
|
stdio: ['ignore', 'pipe', 'ignore'],
|
|
}).trim();
|
|
const [commit, time] = out.split(' ');
|
|
cached = commit && time ? { commit, time } : null;
|
|
} catch {
|
|
cached = null;
|
|
}
|
|
return cached;
|
|
}
|