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