diff --git a/.gitignore b/.gitignore
index c49ef32f..b2e0bbc2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,6 +10,10 @@ obj/
.env
.env.*
!deploy/.env.example
+# #458 — VITE_APP_VERSION only, a public string baked into the client bundle
+# regardless of whether it's committed; release-please bumps it in lockstep
+# with version.txt (see release-please-config.json's extra-files).
+!web/.env.production
appsettings.Development.local.json
# OS/editor noise
diff --git a/docs/decisions/351-releases.md b/docs/decisions/351-releases.md
index eb641f12..02fd2edc 100644
--- a/docs/decisions/351-releases.md
+++ b/docs/decisions/351-releases.md
@@ -362,6 +362,15 @@ Two stages, deliberately separate: **CI publishes, the release PR versions.**
`.release-please-manifest.json`, and `version.txt`. **Never hand-edit the manifest
or `version.txt`**; release-please owns them and a manual edit desynchronises the
version it believes from the tags that exist.
+- **`extra-files` (#458) extends that ownership to `web/.env.production`'s
+ `VITE_APP_VERSION`** — release-please's `generic` updater bumps it in the same
+ release PR as `version.txt`/the manifest, anchored by an `x-release-please-version`
+ marker comment on the line above (not a same-line trailing comment — dotenv-style
+ parsers don't strip inline `#` comments the way YAML/generic key:value formats do,
+ so a trailing marker would have become part of the value). Vite loads
+ `.env.production` automatically for a production build; no Dockerfile/CI plumbing
+ needed beyond the file itself. Same "never hand-edit" rule applies to the value —
+ only the marker's presence and the file's existence are this repo's to maintain.
- **The release PR is opened with a GitHub App token, not `GITHUB_TOKEN`** — and
both reasons are load-bearing, so do not "simplify" it back.
1. `GITHUB_TOKEN` **cannot open a pull request at all** unless the repo-wide
diff --git a/release-please-config.json b/release-please-config.json
index f4dde593..5c127128 100644
--- a/release-please-config.json
+++ b/release-please-config.json
@@ -11,6 +11,12 @@
"bump-patch-for-minor-pre-major": true,
"changelog-path": "CHANGELOG.md",
"include-component-in-tag": false,
+ "extra-files": [
+ {
+ "type": "generic",
+ "path": "web/.env.production"
+ }
+ ],
"changelog-sections": [
{ "type": "feat", "section": "Features" },
{ "type": "fix", "section": "Bug fixes" },
diff --git a/web/.env.production b/web/.env.production
new file mode 100644
index 00000000..16acae7f
--- /dev/null
+++ b/web/.env.production
@@ -0,0 +1,2 @@
+# x-release-please-version
+VITE_APP_VERSION=0.0.3
diff --git a/web/src/i18n/en.ts b/web/src/i18n/en.ts
index e6e5b148..ec480a23 100644
--- a/web/src/i18n/en.ts
+++ b/web/src/i18n/en.ts
@@ -170,6 +170,10 @@ export const en = {
skipToContent: "Skip to main content",
primaryNavAriaLabel: "Primary",
signOut: "Sign out",
+ // {{version}} is a bare semver string (e.g. "0.0.2"), never itself
+ // translated — only the surrounding "v" template varies by locale in
+ // principle, though every catalog currently agrees on it (#458).
+ versionLabel: "v{{version}}",
farmLoadFailedNeverLoaded:
"Could not load this farm's settings, so dates follow this device rather than the farm.",
farmLoadFailedStale:
diff --git a/web/src/i18n/es.ts b/web/src/i18n/es.ts
index 8b03b2cd..d96749ed 100644
--- a/web/src/i18n/es.ts
+++ b/web/src/i18n/es.ts
@@ -138,6 +138,7 @@ export const es = {
skipToContent: "Saltar al contenido principal",
primaryNavAriaLabel: "Principal",
signOut: "Cerrar sesión",
+ versionLabel: "v{{version}}",
farmLoadFailedNeverLoaded:
"No se pudo cargar la configuración de esta granja, así que las "
+ "fechas siguen a este dispositivo en lugar de a la granja.",
diff --git a/web/src/i18n/tl.ts b/web/src/i18n/tl.ts
index 18cd702b..39eaefd4 100644
--- a/web/src/i18n/tl.ts
+++ b/web/src/i18n/tl.ts
@@ -148,6 +148,7 @@ export const tl = {
skipToContent: "Lumaktaw papunta sa pangunahing content",
primaryNavAriaLabel: "Pangunahin",
signOut: "Mag-sign out",
+ versionLabel: "v{{version}}",
farmLoadFailedNeverLoaded:
"Hindi na-load ang mga setting ng bukid na ito, kaya susundin ng mga "
+ "petsa ang device na ito sa halip na ang bukid.",
diff --git a/web/src/routes/AppLayout.test.tsx b/web/src/routes/AppLayout.test.tsx
index 4f38758f..bdd703a8 100644
--- a/web/src/routes/AppLayout.test.tsx
+++ b/web/src/routes/AppLayout.test.tsx
@@ -103,6 +103,21 @@ describe("AppLayout sidebar", () => {
expect(screen.queryByRole("alert")).not.toBeInTheDocument();
});
+ it("shows no version line when VITE_APP_VERSION is unset (#458 — dev/test builds)", () => {
+ // import.meta.env.VITE_APP_VERSION is read once at module scope
+ // (AppLayout.tsx), matching errorReport.ts's own "absent in dev builds"
+ // contract — this test environment never sets it, so this proves the
+ // component renders nothing rather than a literal "vundefined".
+ renderWithProviders(
{t("versionLabel", { version: APP_VERSION })}
} diff --git a/web/src/styles.css b/web/src/styles.css index 69dce497..39db25d0 100644 --- a/web/src/styles.css +++ b/web/src/styles.css @@ -1223,6 +1223,14 @@ input.cell { text-decoration: none; } +.sidebar-version { + margin: 0.35rem 0 0.6rem; + padding: 0 0.25rem; + font-size: 0.75rem; + color: var(--on-brand-mute); + opacity: 0.7; +} + /* -------------------------------------------- Bottom nav (mobile) */ /* The tab bar and its More sheet own navigation below 900px; the sidebar owns