feat(fase-14): version chip in /settings + GIT_SHA bake-through (14.3)

`apps/web/vite.config.ts` now injects three build-time constants via
`define`: `__APP_VERSION__` (root package.json), `__APP_COMMIT__`
(GIT_SHA env > local `git rev-parse` > 'dev'), `__BUILD_TIME__` (ISO
timestamp at build). They're declared in `apps/web/src/global.d.ts`
and re-exported through `$lib/version` — components consume the named
exports rather than the magic globals so an accidental tree-shake
would break the test, not the page silently.

`/settings` gains an "About" section at the bottom: a small chip
`v{version} · {commit} · {date}` in muted text. Not interactive,
purely diagnostic — useful when a user reports a bug from a stale
PWA install.

Deploy pipeline:
  - `apps/web/Dockerfile` accepts a `GIT_SHA` build arg and exports
    it as an env var for the SvelteKit build step.
  - `infra/docker-compose.erosi.yml` forwards `${GIT_SHA:-dev}` into
    the build args.
  - `infra/scripts/deploy-erosi.sh` captures `git rev-parse --short
    HEAD` locally (the deploy host has .git; the remote doesn't —
    rsync excludes it) and forwards it via `ssh ... env GIT_SHA=…`
    so the remote `docker compose build` sees it.

V-01/V-02 vitest: stub the three globals via `vi.stubGlobal` (vitest
doesn't run through the main vite.config so `define` isn't applied),
assert the named exports thread through and never collapse to
undefined or the 'dev' sentinel under a real build.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-18 07:09:15 +02:00
parent 45cca5072b
commit 38b2be61ef
7 changed files with 133 additions and 5 deletions

View File

@@ -2,8 +2,37 @@ import { defineConfig } from 'vite';
import { sveltekit } from '@sveltejs/kit/vite';
import { SvelteKitPWA } from '@vite-pwa/sveltekit';
import { paraglide } from '@inlang/paraglide-sveltekit/vite';
import { execSync } from 'node:child_process';
import { readFileSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
// Fase 14.3.1 — build-time version constants.
// Source order: explicit GIT_SHA env (used by `apps/web/Dockerfile`
// during `infra/scripts/deploy-erosi.sh`) > local `git rev-parse` >
// 'dev' fallback when neither path works (e.g. tarball builds).
const rootPkgUrl = new URL('../../package.json', import.meta.url);
const rootPkg = JSON.parse(readFileSync(fileURLToPath(rootPkgUrl), 'utf8')) as {
version?: string;
};
const APP_VERSION = rootPkg.version ?? '0.0.0';
let APP_COMMIT: string = process.env.GIT_SHA ?? '';
if (!APP_COMMIT) {
try {
APP_COMMIT = execSync('git rev-parse --short HEAD', { stdio: ['ignore', 'pipe', 'ignore'] })
.toString()
.trim();
} catch {
APP_COMMIT = 'dev';
}
}
const BUILD_TIME = new Date().toISOString();
export default defineConfig({
define: {
__APP_VERSION__: JSON.stringify(APP_VERSION),
__APP_COMMIT__: JSON.stringify(APP_COMMIT),
__BUILD_TIME__: JSON.stringify(BUILD_TIME)
},
plugins: [
paraglide({
project: './project.inlang',