mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-18 12:52:25 +03:00
The packaged artifact stamped dist/BUILD_SHA but nothing verified the SHA belonged to the release line, so a tarball built from a feature branch installed and served traffic indistinguishably from a release build. That is how the internal gateway ended up running a build that predated #10373 and answered every request with 502 'Executor result must contain a Response' — identifying it required SSH plus grepping the compiled chunks. scripts/build/buildProvenance.ts classifies a build SHA against the release ref (pure functions, injected git probe). A missing SHA fails even with the canary override: an unidentifiable artifact cannot be vouched for. validate-pack-artifact enforces it on real packs (skipped under --policy-only, which runs without a build); OMNIROUTE_ALLOW_CANARY_BUILD=1 records a deliberate off-release-line build instead of failing it. /api/monitoring/health now exposes system.buildSha — absent when unknown, never fabricated. Closes #10427
53 lines
1.6 KiB
TypeScript
53 lines
1.6 KiB
TypeScript
/**
|
|
* Runtime build identity (#10427).
|
|
*
|
|
* `scripts/build/write-build-sha.mjs` stamps the git SHA into `dist/BUILD_SHA` and
|
|
* `.build/next/standalone/BUILD_SHA` at release-build time. Reading it back at runtime is
|
|
* what lets an operator answer "what code is this box actually running?" over HTTP.
|
|
*
|
|
* Before this existed, answering that question during the 2026-08-14 gateway outage meant
|
|
* SSH-ing into the host and grepping the compiled Next chunks — the deployed package
|
|
* turned out to be built from a feature branch that predated the fix it was supposed to
|
|
* carry.
|
|
*
|
|
* Resolution order: explicit env var (containers can inject it without the sentinel file),
|
|
* then the sentinel files relative to the working directory. Unknown → `null`, never a
|
|
* fabricated or guessed value.
|
|
*/
|
|
|
|
import fs from "node:fs";
|
|
import path from "node:path";
|
|
|
|
const SENTINEL_PATHS = [
|
|
["dist", "BUILD_SHA"],
|
|
[".build", "next", "standalone", "BUILD_SHA"],
|
|
["BUILD_SHA"],
|
|
];
|
|
|
|
let cached: string | null | undefined;
|
|
|
|
export function readRunningBuildSha(cwd: string = process.cwd()): string | null {
|
|
if (cached !== undefined) return cached;
|
|
|
|
const fromEnv = process.env.OMNIROUTE_BUILD_SHA?.trim();
|
|
if (fromEnv) {
|
|
cached = fromEnv;
|
|
return cached;
|
|
}
|
|
|
|
for (const segments of SENTINEL_PATHS) {
|
|
try {
|
|
const value = fs.readFileSync(path.join(cwd, ...segments), "utf8").trim();
|
|
if (value) {
|
|
cached = value;
|
|
return cached;
|
|
}
|
|
} catch {
|
|
// Sentinel absent at this location — try the next one. A dev run has none of them.
|
|
}
|
|
}
|
|
|
|
cached = null;
|
|
return cached;
|
|
}
|