fix(ci): write dist build stamp after builds

This commit is contained in:
Peter Steinberger
2026-03-22 22:22:29 -07:00
parent ea579ef858
commit 7fcbf383d8
5 changed files with 116 additions and 30 deletions

22
scripts/build-stamp.d.mts Normal file
View File

@@ -0,0 +1,22 @@
export function resolveGitHead(params?: {
cwd?: string;
spawnSync?: (
cmd: string,
args: string[],
options: unknown,
) => { status: number | null; stdout?: string | null };
}): string | null;
export function writeBuildStamp(params?: {
cwd?: string;
fs?: {
mkdirSync(path: string, options?: { recursive?: boolean }): void;
writeFileSync(path: string, data: string, encoding?: string): void;
};
now?: () => number;
spawnSync?: (
cmd: string,
args: string[],
options: unknown,
) => { status: number | null; stdout?: string | null };
}): string;

50
scripts/build-stamp.mjs Normal file
View File

@@ -0,0 +1,50 @@
#!/usr/bin/env node
import { spawnSync } from "node:child_process";
import fs from "node:fs";
import path from "node:path";
import process from "node:process";
import { pathToFileURL } from "node:url";
export function resolveGitHead(params = {}) {
const cwd = params.cwd ?? process.cwd();
const spawnSyncImpl = params.spawnSync ?? spawnSync;
try {
const result = spawnSyncImpl("git", ["rev-parse", "HEAD"], {
cwd,
encoding: "utf8",
stdio: ["ignore", "pipe", "ignore"],
});
if (result.status !== 0) {
return null;
}
const head = (result.stdout ?? "").trim();
return head || null;
} catch {
return null;
}
}
export function writeBuildStamp(params = {}) {
const cwd = params.cwd ?? process.cwd();
const fsImpl = params.fs ?? fs;
const now = params.now ?? Date.now;
const distRoot = path.join(cwd, "dist");
const buildStampPath = path.join(distRoot, ".buildstamp");
const head = resolveGitHead({
cwd,
spawnSync: params.spawnSync,
});
fsImpl.mkdirSync(distRoot, { recursive: true });
fsImpl.writeFileSync(buildStampPath, `${JSON.stringify({ builtAt: now(), head })}\n`, "utf8");
return buildStampPath;
}
if (import.meta.url === pathToFileURL(process.argv[1] ?? "").href) {
try {
writeBuildStamp();
} catch (error) {
console.error(error);
process.exit(1);
}
}

View File

@@ -4,6 +4,7 @@ import fs from "node:fs";
import path from "node:path";
import process from "node:process";
import { pathToFileURL } from "node:url";
import { resolveGitHead, writeBuildStamp as writeDistBuildStamp } from "./build-stamp.mjs";
import { runRuntimePostBuild } from "./runtime-postbuild.mjs";
const buildScript = "scripts/tsdown-build.mjs";
@@ -121,27 +122,6 @@ const findLatestMtime = (dirPath, shouldSkip, deps) => {
return latest;
};
const runGit = (gitArgs, deps) => {
try {
const result = deps.spawnSync("git", gitArgs, {
cwd: deps.cwd,
encoding: "utf8",
stdio: ["ignore", "pipe", "ignore"],
});
if (result.status !== 0) {
return null;
}
return (result.stdout ?? "").trim();
} catch {
return null;
}
};
const resolveGitHead = (deps) => {
const head = runGit(["rev-parse", "HEAD"], deps);
return head || null;
};
const readGitStatus = (deps) => {
try {
const result = deps.spawnSync(
@@ -291,12 +271,11 @@ const syncRuntimeArtifacts = (deps) => {
const writeBuildStamp = (deps) => {
try {
deps.fs.mkdirSync(deps.distRoot, { recursive: true });
const stamp = {
builtAt: Date.now(),
head: resolveGitHead(deps),
};
deps.fs.writeFileSync(deps.buildStampPath, `${JSON.stringify(stamp)}\n`);
writeDistBuildStamp({
cwd: deps.cwd,
fs: deps.fs,
spawnSync: deps.spawnSync,
});
} catch (error) {
// Best-effort stamp; still allow the runner to start.
logRunner(`Failed to write build stamp: ${error?.message ?? "unknown error"}`, deps);