Skip to content

feat(web): display app version in the sidebar, sourced from version.txt - #459

Merged
mforce merged 2 commits into
mainfrom
feat/458-app-version-display
Aug 8, 2026
Merged

feat(web): display app version in the sidebar, sourced from version.txt#459
mforce merged 2 commits into
mainfrom
feat/458-app-version-display

Conversation

@mforce

@mforce mforce commented Aug 8, 2026

Copy link
Copy Markdown
Owner

Closes #458.

Problem

No visible version identifier anywhere in the app — no way to say "which build am I on" from a screenshot or support conversation.

A latent bug found along the way

web/src/api/errorReport.ts has always read import.meta.env.VITE_APP_VERSION for crash reports (the comment there says "set at build time... absent in dev builds"), but nothing ever actually set it — not in CI's npm run build, not in the Dockerfile's RUN npm run build. So every crash report, including from production, has been silently sending appVersion: undefined. Fixed as part of this change, not separately, since the fix is the same plumbing.

Design

Per discussion: extend release-please rather than invent new CI plumbing.

  • web/.env.production (new) carries VITE_APP_VERSION=0.0.2. Vite loads .env.production automatically for a production-mode build (vite build defaults to mode: production) — no Dockerfile/CI changes needed beyond the file existing; COPY web/ ./ in the Dockerfile already picks it up, and it isn't excluded by .dockerignore (**/.env matches only the exact filename .env).
  • .gitignore negates it (!web/.env.production) — the root .gitignore's .env.* pattern would otherwise block committing it. VITE_APP_VERSION is a public string baked into the client bundle regardless of whether it's committed, not a secret.
  • release-please-config.json gains an extra-files entry using release-please's generic updater, anchored by an x-release-please-version marker comment on the line above the value (not a trailing same-line comment — dotenv-style .env parsing doesn't strip inline # comments the way YAML/generic key:value formats do, so a trailing marker would have become part of the value). This makes future release PRs bump web/.env.production in lockstep with version.txt/the manifest, same PR, same commit.
  • AppLayout.tsx renders v{{version}} in the sidebar footer, next to the theme toggle/sign-out — the existing .sidebar-foot chrome. Absent entirely when the var is unset (dev/test builds), rather than rendering something broken.

Verification

  • npm run typecheck / npm run i18n:scan (COUNT: 3, unchanged baseline) / npm test (1412/1412, +1 new) all green.
  • Verified end-to-end with a real npm run build, not just the unit test: grepped the built bundle and confirmed 0.0.2 is correctly baked into both errorReport.ts's appVersion and AppLayout.tsx's APP_VERSION — proves the whole .env.production → Vite substitution pipeline actually works, not just that the code compiles.
  • New test mutation-checked properly, including catching my own first mistake: I initially wrote the "no version shown when unset" test assuming i18next would render a missing {{version}} interpolation as "vundefined" (JS string-concat style) — wrong. Printed the actual DOM and found i18next renders it as a bare "v" (empty interpolation). Rewrote the test against the real behavior, then mutation-tested it (temporarily removed the APP_VERSION && guard) and confirmed it now correctly goes red.

What's unverified

I could not test the release-please-config.json extra-files wiring against a real release-please dry run (no network access to invoke the action here). This is the one part of the change that needs confirming on the next actual release PR — that web/.env.production's version line moves in lockstep with version.txt. If it doesn't, the marker-comment placement is the first thing to check.

Docs

Added a short note to docs/decisions/351-releases.md documenting the extra-files addition and why the marker comment is placed where it is (dotenv inline-comment gotcha).

Closes #458.

Fixes a latent bug along the way: web/src/api/errorReport.ts has always
read import.meta.env.VITE_APP_VERSION for crash reports, but nothing ever
set it — in CI or the Dockerfile — so every crash report, including from
production, silently sent appVersion: undefined.

- web/.env.production (new, .gitignore negated — VITE_APP_VERSION is a
  public string baked into the client bundle regardless of whether it's
  committed) carries VITE_APP_VERSION, loaded automatically by Vite for a
  production build. No Dockerfile/CI plumbing needed beyond the file
  itself existing.
- release-please-config.json gains an extra-files entry (the `generic`
  updater, anchored by an x-release-please-version marker on the line
  above the value — not a trailing comment, since dotenv-style parsers
  don't strip inline # comments) so future release PRs bump this file in
  the same PR as version.txt/the manifest.
- AppLayout.tsx renders "v{{version}}" in the sidebar footer, alongside
  the theme toggle/sign-out — absent entirely in dev/test builds (the var
  is unset there), rather than showing a broken "v" or "vundefined".

Verified end-to-end via a real `npm run build`: the built bundle contains
`0.0.2` baked into both errorReport.ts's appVersion and AppLayout.tsx's
APP_VERSION, confirming the whole pipeline works, not just the unit test.

New test mutation-checked: the guard against a missing VITE_APP_VERSION
was verified against the ACTUAL i18next behavior (a bare "v" — i18next
renders a missing interpolation as empty, not string-concatenated
"vundefined" as first assumed and tested for, which would have silently
passed against the real bug).

Could not verify the release-please extra-files wiring itself against a
real release-please dry run (no network access to test the action) — this
is the one part of the change that needs confirming on the next actual
release PR: that web/.env.production's version line moves in lockstep
with version.txt.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d1a52a66e0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread web/.env.production Outdated
…eview)

version.txt/the manifest moved to 0.0.3 on main since this branch was cut;
0.0.2 would have shipped in every image built from this commit until a
later release PR happened to correct it (affects CI's per-merge images,
not just a local build).
@mforce

mforce commented Aug 8, 2026

Copy link
Copy Markdown
Owner Author

@codex address that feedback

@chatgpt-codex-connector

Copy link
Copy Markdown

Summary

  • The review feedback was already addressed in commit a096192: the production Vite version is 0.0.3, matching both version.txt and the release-please manifest. web/.env.productionL1-L2 version.txtL1 .release-please-manifest.jsonL1-L3
  • No additional changes or PR were created because the requested fix is already committed on the current PR branch and the working tree is clean.

Testing

  • cd web && npm run typecheck
  • cd web && npm run build
  • cd web && rg -q '0\.0\.3' dist
  • git status --porcelain (clean working tree)

View task →

@mforce
mforce merged commit abdcb98 into main Aug 8, 2026
10 checks passed
@mforce
mforce deleted the feat/458-app-version-display branch August 8, 2026 07:30
@mforce

mforce commented Aug 13, 2026

Copy link
Copy Markdown
Owner Author

Reopening: the extra-files sync this issue shipped didn't actually fire on the first real release (#461, v0.0.4). Root cause: release-please's generic updater matches a semver pattern only on the same line as the x-release-please-version marker — this PR put the marker on the line above the value, so it silently never matched. Filing the fix as a follow-up PR.

mforce added a commit that referenced this pull request Aug 13, 2026
release-please's generic updater only matches a semver pattern on the
same line as the x-release-please-version marker, not the line below
it. #459 placed the marker above the value, so it silently never
matched — v0.0.4 (#461) bumped version.txt but left
web/.env.production at 0.0.3, caught by review.

Move the marker to a trailing comment on the value's own line.
dotenv (Vite's env loader) strips inline # comments on unquoted
values, so the runtime value stays clean — verified via a real
npm run build and a grep of the bundled output.

Fixes #458

Co-authored-by: mforce <>
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.

Display app version in the SPA, sourced from release-please's version.txt

2 participants