`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>
47 lines
1.6 KiB
TypeScript
47 lines
1.6 KiB
TypeScript
/**
|
|
* Fase 14.3.6 — guard the version.ts barrel against accidental
|
|
* tree-shaking / undefined replacement.
|
|
*
|
|
* Vitest doesn't run through Vite's `define`, so the `__APP_*`
|
|
* globals don't exist in this environment. We stub them via
|
|
* `vi.stubGlobal` to mimic what `vite build` (and `vite dev`)
|
|
* inject at build/dev time.
|
|
*
|
|
* The point of the test is two-fold:
|
|
* 1. The module re-exports the three globals as an object so
|
|
* consumers never reach for the `__APP_*` symbols inline.
|
|
* 2. None of the three exports collapse to `undefined` or the
|
|
* sentinel `'dev'` when the build-time substitution is
|
|
* working — that's the canary for an accidental tree-shake
|
|
* that would silently break the version chip in production.
|
|
*/
|
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
|
|
describe('version barrel', () => {
|
|
beforeEach(() => {
|
|
vi.resetModules();
|
|
vi.stubGlobal('__APP_VERSION__', '1.2.3');
|
|
vi.stubGlobal('__APP_COMMIT__', 'abc1234');
|
|
vi.stubGlobal('__BUILD_TIME__', '2026-05-18T10:00:00.000Z');
|
|
});
|
|
|
|
afterEach(() => {
|
|
vi.unstubAllGlobals();
|
|
});
|
|
|
|
it('V-01: exports version / commit / builtAt from the build-time define', async () => {
|
|
const mod = await import('./version');
|
|
expect(mod.version).toBe('1.2.3');
|
|
expect(mod.commit).toBe('abc1234');
|
|
expect(mod.builtAt).toBe('2026-05-18T10:00:00.000Z');
|
|
});
|
|
|
|
it('V-02: none of the exports are undefined or the "dev" sentinel under a real build define', async () => {
|
|
const mod = await import('./version');
|
|
for (const v of [mod.version, mod.commit, mod.builtAt]) {
|
|
expect(v).toBeTruthy();
|
|
expect(v).not.toBe('dev');
|
|
}
|
|
});
|
|
});
|