feat(webapp): show running version in Mini App footer

Compute `git describe --tags --always --dirty` at server startup
and expose via unauthenticated /api/version. Render as small muted
text at the bottom of the Mini App so the running version can be
confirmed at a glance.

Once tags exist, the badge will show e.g. v0.1.0 or v0.1.0-3-gSHA.
Until then it shows the short SHA.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Danny 2026-04-18 17:38:52 +02:00
parent 31d426d53e
commit b4d76b0eca
4 changed files with 56 additions and 1 deletions

View file

@ -9,6 +9,8 @@ import io
import json
import logging
import os
import pathlib
import subprocess
from urllib.parse import parse_qs
from aiohttp import web
@ -23,6 +25,24 @@ logging.basicConfig(
logger = logging.getLogger(__name__)
# ── Version (computed once at startup) ───────────────────────────
def _compute_version() -> str:
"""Return `git describe --tags --always --dirty`, or 'unknown'."""
try:
out = subprocess.run(
["git", "describe", "--tags", "--always", "--dirty"],
cwd=pathlib.Path(__file__).parent,
capture_output=True, text=True, timeout=2, check=True,
)
return out.stdout.strip() or "unknown"
except (subprocess.SubprocessError, FileNotFoundError, OSError):
return "unknown"
_VERSION = _compute_version()
# ── Token (injected by start.py via env) ─────────────────────────
def _get_bot_token() -> str:
@ -206,6 +226,11 @@ async def api_export_json(request: web.Request):
return web.json_response({"records": data, "count": len(data)})
async def api_version(request: web.Request):
"""Return the running server version. Unauthenticated."""
return web.json_response({"version": _VERSION})
@require_auth
async def api_export_csv(request: web.Request):
"""Export all workouts as CSV."""
@ -239,9 +264,9 @@ def create_app() -> web.Application:
app.router.add_get("/api/stats", api_get_stats)
app.router.add_get("/api/export/json", api_export_json)
app.router.add_get("/api/export/csv", api_export_csv)
app.router.add_get("/api/version", api_version)
# Serve the webapp/ folder
import pathlib
webapp_dir = pathlib.Path(__file__).parent / "webapp"
async def index_handler(request):