From 0872d545d557d78769670aca70e97c6c4c43775d Mon Sep 17 00:00:00 2001 From: Danny Date: Sat, 18 Apr 2026 18:39:26 +0200 Subject: [PATCH] fix(server): pure-python fallback for version when git is not on PATH The systemd service environment on the NixOS deploy host has a minimal PATH without git, so subprocess.run(['git', ...]) fails with FileNotFoundError and /api/version returned 'unknown'. Fall back to reading .git/HEAD directly (resolving the ref) and returning the short SHA. Loses tag/dirty detection, but unblocks the version badge in deployed environments. Co-Authored-By: Claude Opus 4.7 (1M context) --- server.py | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/server.py b/server.py index c5543c1..84b400a 100644 --- a/server.py +++ b/server.py @@ -28,15 +28,33 @@ logger = logging.getLogger(__name__) # ── Version (computed once at startup) ─────────────────────────── def _compute_version() -> str: - """Return `git describe --tags --always --dirty`, or 'unknown'.""" + """Return `git describe --tags --always --dirty`, with a pure-Python + fallback for environments where the `git` binary isn't on PATH + (e.g. minimal systemd service environments on NixOS). + """ + repo_root = pathlib.Path(__file__).parent + + # Preferred: git describe (picks up tags + dirty state). try: out = subprocess.run( ["git", "describe", "--tags", "--always", "--dirty"], - cwd=pathlib.Path(__file__).parent, + cwd=repo_root, capture_output=True, text=True, timeout=2, check=True, ) - return out.stdout.strip() or "unknown" + if out.stdout.strip(): + return out.stdout.strip() except (subprocess.SubprocessError, FileNotFoundError, OSError): + pass + + # Fallback: resolve HEAD ourselves. No tags, no dirty detection, just SHA. + try: + head = (repo_root / ".git" / "HEAD").read_text().strip() + if head.startswith("ref: "): + sha = (repo_root / ".git" / head[5:]).read_text().strip() + else: + sha = head + return sha[:7] if sha else "unknown" + except OSError: return "unknown"