From b4ed4812fc69058a4703d4b91d0084965a17e1ba Mon Sep 17 00:00:00 2001 From: Claudio Schaad Date: Thu, 30 Jul 2026 12:12:30 +0200 Subject: [PATCH] Show the deployed build version in the app Bakes the git short commit hash into the client bundle at build time and exposes the same info from the server via GET /api/version. The header displays the loaded build's commit and flags when it no longer matches what the server is running, so a stale open tab is easy to spot after a deploy. The Docker build now includes .git so the hash can be resolved during the image build. Co-Authored-By: Claude Sonnet 5 --- .dockerignore | 1 - Dockerfile | 4 +++ client/src/api/version.ts | 6 ++++ client/src/components/layout/AppShell.tsx | 2 ++ client/src/components/layout/AppVersion.tsx | 31 +++++++++++++++++++++ client/src/styles/global.css | 10 +++++++ client/src/vite-env.d.ts | 2 ++ client/vite.config.ts | 12 ++++++++ server/package.json | 2 +- server/scripts/write-version.js | 20 +++++++++++++ server/src/app.ts | 2 ++ server/src/config.ts | 22 +++++++++++++++ shared/src/types.ts | 5 ++++ 13 files changed, 117 insertions(+), 2 deletions(-) create mode 100644 client/src/api/version.ts create mode 100644 client/src/components/layout/AppVersion.tsx create mode 100644 server/scripts/write-version.js diff --git a/.dockerignore b/.dockerignore index a7fb9a9..744faae 100644 --- a/.dockerignore +++ b/.dockerignore @@ -2,7 +2,6 @@ node_modules **/node_modules **/dist **/*.tsbuildinfo -.git .tools data data-dev diff --git a/Dockerfile b/Dockerfile index 48b06c7..02e8317 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,7 @@ # ---- Stage 1: build shared + client (static assets) ---- FROM node:20-bookworm-slim AS build-client WORKDIR /app +RUN apt-get update && apt-get install -y --no-install-recommends git && rm -rf /var/lib/apt/lists/* COPY package.json ./ COPY shared/package.json shared/package.json COPY server/package.json server/package.json @@ -8,11 +9,13 @@ COPY client/package.json client/package.json RUN npm install COPY shared shared COPY client client +COPY .git .git RUN npm run build -w shared && npm run build -w client # ---- Stage 2: build shared + server (compiled JS) ---- FROM node:20-bookworm-slim AS build-server WORKDIR /app +RUN apt-get update && apt-get install -y --no-install-recommends git && rm -rf /var/lib/apt/lists/* COPY package.json ./ COPY shared/package.json shared/package.json COPY server/package.json server/package.json @@ -20,6 +23,7 @@ COPY client/package.json client/package.json RUN npm install COPY shared shared COPY server server +COPY .git .git RUN npm run build -w shared && npm run build -w server # ---- Stage 3: runtime ---- diff --git a/client/src/api/version.ts b/client/src/api/version.ts new file mode 100644 index 0000000..c61c889 --- /dev/null +++ b/client/src/api/version.ts @@ -0,0 +1,6 @@ +import type { AppVersion } from '@citytracker/shared'; +import { api } from './client'; + +export function fetchVersion() { + return api.get('/version'); +} diff --git a/client/src/components/layout/AppShell.tsx b/client/src/components/layout/AppShell.tsx index c73c46e..884d657 100644 --- a/client/src/components/layout/AppShell.tsx +++ b/client/src/components/layout/AppShell.tsx @@ -1,5 +1,6 @@ import { NavLink, Outlet, useNavigate } from 'react-router-dom'; import { useAuth } from '../../context/AuthContext'; +import { AppVersion } from './AppVersion'; export function AppShell() { const { user, logout } = useAuth(); @@ -14,6 +15,7 @@ export function AppShell() {
CityTracker +