feat(build): pass the commit to the image as a build arg (#248)
The admin version stamp has reported commit "unknown" everywhere. #233 read it out of .git during the build and #235 removed that, because Portainer's build context has no repository history and the COPY failed every deploy — the version stamp became the thing that stopped deployments. #237 then established that building in Gitea Actions does not help: the Dockerfile no longer copies .git, so where the build runs is irrelevant. So the builder hands the commit over rather than the build going to look for it. ARG GIT_COMMIT, empty by default, passed through to writeBuildInfo, which prefers it and still falls back to reading .git so a local build stamps itself with no argument needed. An empty value is treated as absent rather than stamped. `--build-arg GIT_COMMIT=` is what an unset shell variable expands to, and a blank commit reads as one that happens to be empty rather than one nobody supplied. Nothing regresses for Portainer. It cannot pass the argument, so its images keep saying "unknown" exactly as today, and they still deploy — the property #235 was bought with. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -37,9 +37,32 @@ function findGitDir(explicit?: string): string | null {
|
||||
return candidates.find((candidate) => existsSync(candidate)) ?? null;
|
||||
}
|
||||
|
||||
export function buildStamp(gitDir: string | null): BuildInfo {
|
||||
/**
|
||||
* A commit passed in by whoever is building, or null.
|
||||
*
|
||||
* This is the half that actually works in the environments that matter. The
|
||||
* Dockerfile deliberately does not copy `.git` — doing so broke every Portainer
|
||||
* deploy (#235) — and #237 established that building in CI changes nothing,
|
||||
* because the copy is what was missing rather than the history. So the builder
|
||||
* has to hand the commit over rather than the build going to look for it (#248).
|
||||
*
|
||||
* Empty is treated as absent. A `--build-arg GIT_COMMIT=` with nothing after it
|
||||
* is what an unset shell variable expands to, and stamping the image with an
|
||||
* empty string would be worse than saying "unknown" — it reads as a commit that
|
||||
* happens to be blank rather than as one nobody supplied.
|
||||
*/
|
||||
function passedCommit(value: string | undefined): string | null {
|
||||
return value !== undefined && value.trim() !== '' ? value.trim() : null;
|
||||
}
|
||||
|
||||
export function buildStamp(gitDir: string | null, passed?: string): BuildInfo {
|
||||
const supplied = passedCommit(passed);
|
||||
|
||||
return {
|
||||
commit: gitDir ? resolveCommit(gitSourceAt(gitDir)) : UNKNOWN_COMMIT,
|
||||
// The passed value wins. It is the only one available where this matters,
|
||||
// and reading .git remains the fallback so a local build still stamps
|
||||
// itself without anyone having to remember the argument.
|
||||
commit: supplied ?? (gitDir ? resolveCommit(gitSourceAt(gitDir)) : UNKNOWN_COMMIT),
|
||||
// Whole seconds: this is read by a person comparing it to when they
|
||||
// pressed a button, not by anything that needs precision.
|
||||
builtAt: new Date().toISOString().replace(/\.\d{3}Z$/, 'Z')
|
||||
@@ -50,15 +73,16 @@ export function buildStamp(gitDir: string | null): BuildInfo {
|
||||
// deployment — the same reasoning as backfillImageReencode.ts (#231).
|
||||
if (require.main === module) {
|
||||
const gitDir = findGitDir(process.argv[2]);
|
||||
const stamp = buildStamp(gitDir);
|
||||
const stamp = buildStamp(gitDir, process.env.GIT_COMMIT);
|
||||
|
||||
if (stamp.commit === UNKNOWN_COMMIT) {
|
||||
// Loud, because a deploy that cannot say what it is defeats the point of
|
||||
// the stamp — but a warning, not a failure.
|
||||
const where = gitDir ? ` at ${gitDir}` : '';
|
||||
console.warn(
|
||||
`[build-info] no readable .git found${where} — ` +
|
||||
`the admin will report the commit as "${UNKNOWN_COMMIT}"`
|
||||
`[build-info] no GIT_COMMIT passed and no readable .git found${where} — ` +
|
||||
`the admin will report the commit as "${UNKNOWN_COMMIT}". ` +
|
||||
`Pass --build-arg GIT_COMMIT="$(git rev-parse --short HEAD)" to stamp it.`
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user