From 5e7a042cad1d08d9e0bdbf7555056cb3caea21ea Mon Sep 17 00:00:00 2001 From: mram Date: Mon, 21 Sep 2026 12:42:32 +0200 Subject: [PATCH] CFG_VER is always a concrete version: dev builds stamp v0.0.0, never "dev" --- SPEC.md | 2 +- internal/config/sample.go | 9 ++++++++- internal/config/sample_test.go | 13 +++++++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/SPEC.md b/SPEC.md index ccb9855..a40af79 100644 --- a/SPEC.md +++ b/SPEC.md @@ -159,7 +159,7 @@ override file values. A missing file is fine; a malformed one is fatal. | `UPDATE_REPO` | `https://git.rambossek.at/PUBLIC/gpu-turnstile` | repository to check for releases | | `UPDATE_ASSET` | `gpu-turnstile.exe` | release asset to download | | `APP_VER` | `stable` | version to run: `dev` disables updates, `stable` tracks the latest release, or an exact `vX.Y.Z` pin (up- or downgraded to) | -| `CFG_VER` | _(installer-managed)_ | config format reference written by `--install-service`; missing = the file is replaced with a fresh sample (backup `.bak`) | +| `CFG_VER` | _(installer-managed)_ | config format reference written by `--install-service` (always a concrete `vX.Y.Z`; a dev build stamps `v0.0.0`); missing = the file is replaced with a fresh sample (backup `.bak`) | Startup fails fast on unparsable values and when neither consumer URL is set. Enabled upstreams are probed once at start (`/api/version`, diff --git a/internal/config/sample.go b/internal/config/sample.go index d7055aa..1a81d45 100644 --- a/internal/config/sample.go +++ b/internal/config/sample.go @@ -59,8 +59,15 @@ func sampleEntries(logFile string) []sampleEntry { // (a Windows service has no console). CFG_VER records the version that // wrote the file so later installs can upgrade it. func SampleEnv(version, logFile string) string { + // CFG_VER is always a concrete vX.Y.Z — never "dev". A dev build + // stamps v0.0.0, which sorts older than any release, so the next + // release install upgrades the file and stamps a proper version. + cfgVer := version + if cfgVer == "" || cfgVer == "dev" { + cfgVer = "v0.0.0" + } var b strings.Builder - fmt.Fprintf(&b, "CFG_VER=%s\n", version) + fmt.Fprintf(&b, "CFG_VER=%s\n", cfgVer) b.WriteString("# Config format reference, written by the installer — do not edit.\n") b.WriteString("# The installer uses it to append newly added settings on updates.\n\n") b.WriteString("# gpu-turnstile configuration\n") diff --git a/internal/config/sample_test.go b/internal/config/sample_test.go index 828c40c..1aa981a 100644 --- a/internal/config/sample_test.go +++ b/internal/config/sample_test.go @@ -122,6 +122,19 @@ func TestSyncSampleAppendsMissingAppVer(t *testing.T) { } } +func TestSampleEnvDevStampsConcreteVersion(t *testing.T) { + // A dev build must never write CFG_VER=dev: it stamps v0.0.0, and the + // next release install upgrades the file to a proper version. + dev := SampleEnv("dev", sampleLogPath) + if !strings.HasPrefix(dev, "CFG_VER=v0.0.0\n") { + t.Errorf("dev sample first line: %q", strings.SplitN(dev, "\n", 2)[0]) + } + out, changed := SyncSample(dev, "v0.1.7", sampleLogPath) + if !changed || !strings.HasPrefix(out, "CFG_VER=v0.1.7\n") { + t.Errorf("dev-stamped file was not upgraded to v0.1.7 (changed=%v)", changed) + } +} + func TestCompareVersions(t *testing.T) { cases := []struct { a, b string