From 27075c5d2e4db50ebe3d6a7c472698412427fac0 Mon Sep 17 00:00:00 2001 From: dennisvang <29799340+dennisvang@users.noreply.github.com> Date: Mon, 20 Jul 2026 10:00:37 +0200 Subject: [PATCH 1/9] remove name and version from package.json these are bound to get out-of-sync at some point, and they are not required because we don't publish an npm package https://docs.npmjs.com/cli/v10/configuring-npm/package-json?v=true#version --- package.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/package.json b/package.json index f11b276..c7a1dd3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,4 @@ { - "name": "fdp-client-v3", - "version": "2.0.0-dev", "private": true, "type": "module", "scripts": { From fd0af014427a400157765aa0a2ab77544270171d Mon Sep 17 00:00:00 2001 From: dennisvang <29799340+dennisvang@users.noreply.github.com> Date: Mon, 20 Jul 2026 12:00:43 +0200 Subject: [PATCH 2/9] replace version from package.json by gitDescribeVersion() in vite.config.ts --- vite.config.ts | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/vite.config.ts b/vite.config.ts index 297ce4f..fed710e 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -6,9 +6,9 @@ import { defineConfig, ViteDevServer } from 'vite' import vue from '@vitejs/plugin-vue' import vueDevTools from 'vite-plugin-vue-devtools' import svgLoader from 'vite-svg-loader' -import { version } from './package.json' import path from 'node:path' import * as fs from 'node:fs' +import { spawnSync, SpawnSyncReturns } from 'node:child_process' // https://vite.dev/config/ export default defineConfig({ @@ -20,7 +20,7 @@ export default defineConfig({ }, }, define: { - __APP_VERSION__: JSON.stringify(version), + __APP_VERSION__: JSON.stringify(gitDescribeVersion()), __APP_BUILT_AT__: JSON.stringify(new Date().toISOString()), }, // vitest options @@ -63,3 +63,21 @@ function clientConfigOverridePlugin() { }, } } + +/** + * Returns a version string obtained from `git describe`, in long format, for example, `'v1.2.3-0-gfc7760f'`. + * Uses `--tags` to include the lightweight tags created by github, `--always` to use abbreviated commit hash if there + * are no tags at all, and `--long` to use long format even if the current commit is tagged. + * Falls back to `'unknown'` in case of error. + */ +function gitDescribeVersion(): string { + const { stdout, stderr, status } = spawnSync( + 'git', + ['describe', '--tags', '--always', '--long'], + { encoding: 'utf8' }, + ) + if (status !== 0) { + console.error('git describe exited with nonzero code (%d) - %s', status, stderr) + } + return stdout.trim() || 'unknown' +} From 054faaa8e73d35f4bc3a8cb337ba37747da34048 Mon Sep 17 00:00:00 2001 From: dennisvang <29799340+dennisvang@users.noreply.github.com> Date: Mon, 20 Jul 2026 12:05:31 +0200 Subject: [PATCH 3/9] inline comments for git describe options --- vite.config.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/vite.config.ts b/vite.config.ts index fed710e..3ce4c53 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -66,14 +66,17 @@ function clientConfigOverridePlugin() { /** * Returns a version string obtained from `git describe`, in long format, for example, `'v1.2.3-0-gfc7760f'`. - * Uses `--tags` to include the lightweight tags created by github, `--always` to use abbreviated commit hash if there - * are no tags at all, and `--long` to use long format even if the current commit is tagged. * Falls back to `'unknown'` in case of error. */ function gitDescribeVersion(): string { const { stdout, stderr, status } = spawnSync( 'git', - ['describe', '--tags', '--always', '--long'], + [ + 'describe', + '--tags', // include the lightweight tags created by e.g. github + '--always', // use abbreviated commit hash if there are no tags at all + '--long', // use long format even if the current commit is tagged ('v1.2.3-0-gfc7760f' instead of 'v1.2.3') + ], { encoding: 'utf8' }, ) if (status !== 0) { From 16a30e6810f804ced001454747d6be8742c333df Mon Sep 17 00:00:00 2001 From: dennisvang <29799340+dennisvang@users.noreply.github.com> Date: Mon, 20 Jul 2026 12:14:20 +0200 Subject: [PATCH 4/9] remove unused import --- vite.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vite.config.ts b/vite.config.ts index 3ce4c53..8e9ed95 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -8,7 +8,7 @@ import vueDevTools from 'vite-plugin-vue-devtools' import svgLoader from 'vite-svg-loader' import path from 'node:path' import * as fs from 'node:fs' -import { spawnSync, SpawnSyncReturns } from 'node:child_process' +import { spawnSync } from 'node:child_process' // https://vite.dev/config/ export default defineConfig({ From 24328265b8a86b2001ddaf2e3f284acae454c60c Mon Sep 17 00:00:00 2001 From: dennisvang <29799340+dennisvang@users.noreply.github.com> Date: Mon, 20 Jul 2026 13:11:42 +0200 Subject: [PATCH 5/9] fail fast so we don't need to add a test for the gitDescribeVersion --- vite.config.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/vite.config.ts b/vite.config.ts index 8e9ed95..65ff98c 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,5 +1,6 @@ /// +import { strict as assert } from 'node:assert' import { fileURLToPath, URL } from 'node:url' import { defineConfig, ViteDevServer } from 'vite' @@ -66,7 +67,7 @@ function clientConfigOverridePlugin() { /** * Returns a version string obtained from `git describe`, in long format, for example, `'v1.2.3-0-gfc7760f'`. - * Falls back to `'unknown'` in case of error. + * Fails intentionally if stdout is falsy. */ function gitDescribeVersion(): string { const { stdout, stderr, status } = spawnSync( @@ -79,8 +80,6 @@ function gitDescribeVersion(): string { ], { encoding: 'utf8' }, ) - if (status !== 0) { - console.error('git describe exited with nonzero code (%d) - %s', status, stderr) - } - return stdout.trim() || 'unknown' + assert(stdout, `git describe failed (exit code: ${status}, stderr: ${stderr?.trim()})`) + return stdout.trim() } From dec0491295f8bbf0976858640371abc3b1421e31 Mon Sep 17 00:00:00 2001 From: dennisvang <29799340+dennisvang@users.noreply.github.com> Date: Mon, 20 Jul 2026 13:43:51 +0200 Subject: [PATCH 6/9] rephrase gitDescribeVersion failure message --- vite.config.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vite.config.ts b/vite.config.ts index 65ff98c..d20d572 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -67,7 +67,7 @@ function clientConfigOverridePlugin() { /** * Returns a version string obtained from `git describe`, in long format, for example, `'v1.2.3-0-gfc7760f'`. - * Fails intentionally if stdout is falsy. + * Fails intentionally if the `git describe` call fails or if its output is falsy. */ function gitDescribeVersion(): string { const { stdout, stderr, status } = spawnSync( @@ -80,6 +80,6 @@ function gitDescribeVersion(): string { ], { encoding: 'utf8' }, ) - assert(stdout, `git describe failed (exit code: ${status}, stderr: ${stderr?.trim()})`) + assert(stdout, `git describe call failed (exit code: ${status}, stderr: ${stderr?.trim()})`) return stdout.trim() } From bf40866f2ae18c01e827808dcb255c50ef3523d3 Mon Sep 17 00:00:00 2001 From: dennisvang <29799340+dennisvang@users.noreply.github.com> Date: Mon, 20 Jul 2026 14:34:19 +0200 Subject: [PATCH 7/9] proper import order in vite.config.ts --- vite.config.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/vite.config.ts b/vite.config.ts index d20d572..7fb9392 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,15 +1,15 @@ /// import { strict as assert } from 'node:assert' +import { spawnSync } from 'node:child_process' +import * as fs from 'node:fs' +import path from 'node:path' import { fileURLToPath, URL } from 'node:url' -import { defineConfig, ViteDevServer } from 'vite' import vue from '@vitejs/plugin-vue' +import { defineConfig, ViteDevServer } from 'vite' import vueDevTools from 'vite-plugin-vue-devtools' import svgLoader from 'vite-svg-loader' -import path from 'node:path' -import * as fs from 'node:fs' -import { spawnSync } from 'node:child_process' // https://vite.dev/config/ export default defineConfig({ From 2acf5c5ad5e39a32ccd24eef2624316c0caff37f Mon Sep 17 00:00:00 2001 From: dennisvang <29799340+dennisvang@users.noreply.github.com> Date: Thu, 13 Aug 2026 13:58:35 +0200 Subject: [PATCH 8/9] do not ignore .git from docker build context The .git dir is only needed to get a version description based on git tags in the build stage. The .git dir is not copied to the final image. --- .dockerignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.dockerignore b/.dockerignore index f2ce3d6..baeabed 100644 --- a/.dockerignore +++ b/.dockerignore @@ -10,7 +10,8 @@ coverage/ *.test.ts # Version control -.git/ +# The .git/ dir is not excluded from the build context because we need it to get a version tag in the build stage. +# This is not a problem because the Dockerfile only copies the build output from /app/dist into the final image. .gitignore # CI/CD From 874c957023f81eb3aa8e7ee591a329938734e5d8 Mon Sep 17 00:00:00 2001 From: dennisvang <29799340+dennisvang@users.noreply.github.com> Date: Thu, 13 Aug 2026 14:05:33 +0200 Subject: [PATCH 9/9] clarify .dockerignore comment --- .dockerignore | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.dockerignore b/.dockerignore index baeabed..8221834 100644 --- a/.dockerignore +++ b/.dockerignore @@ -10,8 +10,8 @@ coverage/ *.test.ts # Version control -# The .git/ dir is not excluded from the build context because we need it to get a version tag in the build stage. -# This is not a problem because the Dockerfile only copies the build output from /app/dist into the final image. +# The .git dir is intentionally included in the build context because the build stage needs it to derive a version tag. +# The Dockerfile only copies the build stage output from /app/dist into the final image, so .git is excluded that way. .gitignore # CI/CD