Skip to content

feat: display deploy version - #271

Merged
sabinem merged 5 commits into
mainfrom
feat/display-deploy-version
Aug 28, 2026
Merged

feat: display deploy version#271
sabinem merged 5 commits into
mainfrom
feat/display-deploy-version

Conversation

@sabinem

@sabinem sabinem commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator

Show the deployed commit in the footer

Anyone reporting a bug in Hackagon can now read the exact commit the running
app was built from, straight off the footer — v0.0.1+c608984. Signed-in users
can see it too, which they never could before.

Before

Every deployed image showed v0.0.0-dirty. Not the version, not the commit,
and not even true — three separate failures stacked into one string, identical
on every image ever shipped. There was no way to tell which code a screenshot
came from, or to tell a release build from a branch build.

The cause was the Nix build. It hands the frontend a source tree containing only
components/frontend/, then runs git init . on it. So the root VERSION file
was unreadable (fell back to 0.0.0), there was no HEAD to read a commit from,
and git status saw 456 untracked files and concluded the tree was dirty. The
footer's build-time stamp worked perfectly on a laptop and could never have
worked in a real build.

The existing test asserted /^v\d+\.\d+\.\d+/, which v0.0.0-dirty satisfies.
That is why it survived.

What changed

The question is split in two: the version comes from the build, the
commit now comes from the image, which carries it as an environment variable
the app reads at runtime.

  • VERSION is now in the Nix fileset, and the stamp requires a real HEAD before
    it will call a tree dirty
  • The flake already knew its own revision (self.rev) — nothing was reading it.
    It now flows into the image as HACKAGON_BUILD_COMMIT and the standard
    org.opencontainers.image.revision label, so skopeo inspect answers the
    same question without running the image
  • The commit rides in the image layer, not the compiled bundle, so the expensive
    pnpm/vite derivation stays cache-stable across commits that don't touch the
    frontend
  • The (app) shell gained a footer; it had none, so signed-in users saw no
    version at all
  • A runtime value that does not look like a git object name is ignored rather
    than shown — it crosses a deployment boundary, and a plausible-but-wrong
    identifier in the field people quote in bug reports is worse than falling back
  • Also on this branch: 10b916d bumps the root .component.yaml to 0.1.0 to
    match the backend's

No Helm change is needed. The image describes itself, so a chart pinning
tag: latest still yields a footer naming the real commit.

Safety

Every failure mode degrades to "the version is not shown", never to a broken
build or app. If Nix cannot determine the revision, the image builds without the
env var. If the env var is missing, the footer falls back to the build stamp. If
it is junk, it is rejected. No schema change, no API change, no new required
config; rollback is redeploying the previous image.

Known gaps

  • The version numbers still disagree. The footer shows VERSION (0.0.1);
    the frontend image is tagged from components/frontend/.component.yaml
    (0.7.0), which 10b916d did not touch. package.json also still says
    0.0.1. So the footer and the image tag continue to name different things — a
    separate decision about which is authoritative.
  • No version tag exists. git tag --list 'v*' is empty, so the stamp's
    "clean checkout on the matching tag → bare v0.0.1" branch is unreachable.
    Until someone runs just version::tag, releases will carry a +commit suffix
    like any other build.
  • No /version endpoint. Routes are protected by default, so it would need a
    new entry in PUBLIC_ROUTE_PATTERNS — an auth-boundary change I did not want
    to make unasked.
  • The backend image has no revision label. One line, same pattern, but it
    lives under components/backend/.
  • No CI assertion that the built image's revision label matches

The Nix build feeds the frontend a fileset holding only
`components/frontend`, then runs `git init .` on it. So `VERSION` was
unreadable (declaredVersion fell back to 0.0.0), HEAD did not exist (no
commit), and `git status --porcelain` listed 456 untracked files (dirty).
Every image ever built stamped `v0.0.0-dirty` into its footer.

Put `VERSION` in the fileset, and require a real HEAD before trusting
`--porcelain` so an empty repo stops reading as dirty. Verified against a
real `nix build ./tools/nix#frontend-service`, which produced
`"v0.0.0-dirty"` before and reads the declared version after.

The old test asserted `/^v\d+\.\d+\.\d+/`, which `v0.0.0-dirty` satisfies —
which is why this survived. Pin the placeholder out explicitly.
`nix build ./tools/nix#...` resolves to git+file://<repo>?dir=tools/nix,
so the flake already knows its revision — `self.rev` on a clean tree,
`self.dirtyRev` otherwise. Nothing was reading it.

Thread it through mkExtendedLib as `cnLib.rev`/`shortRev` and put it in
the frontend image as `HACKAGON_BUILD_COMMIT` plus the standard
`org.opencontainers.image.revision` label.

It goes in the image layer, not the vite bundle, so the expensive
pnpm/vite derivation stays cache-stable across commits that don't touch
the frontend. The app reads it at runtime; that arrives next.

Both null-guarded: an image built from an unknown revision says nothing
rather than claiming a wrong one.
@sabinem sabinem changed the title Feat/display deploy version feat: display deploy version Aug 28, 2026
The image now carries HACKAGON_BUILD_COMMIT (see the preceding commit).
Read it in the root layout load and let it supersede the build-time
stamp, which in a Nix-built image can only ever know the declared
version.

Also render the footer in the (app) shell. It had none, so a signed-in
user — the one most likely to be reporting a bug — could not see which
build they were on at all.

A runtime value that does not look like a git object name is ignored
rather than displayed: it crosses a deployment boundary, and a plausible
but wrong identifier in the field people quote in bug reports is worse
than falling back to the build stamp.
@sabinem
sabinem merged commit 57c959d into main Aug 28, 2026
2 checks passed
@sabinem
sabinem deleted the feat/display-deploy-version branch August 28, 2026 08:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant