0.32.0: StackPilot self-update (check on page load + one-click update)

- backend/version.py is now the single version source (main.py, agent).
- GET /api/system/update: reads the version tags of the backend's own image
  repo (anonymous v2 token flow, https→http fallback for insecure
  registries), compares the highest semver tag against APP_VERSION; reports
  update_supported from the container's compose labels. 10 min cache.
- POST /api/system/update (admin, audited): spawns a detached helper
  container from the current backend image that runs docker compose pull &&
  up -d on StackPilot's own compose project (project name, working dir and
  config files resolved from its own container labels) — the helper
  outlives the backend being recreated. Non-compose installs get a 400.
- /api/health now returns the version so the UI can detect the switchover.
- TopNav version badge: queries the update status on page load; when a
  newer release exists an amber pill shows the version — one click (admin)
  confirms, triggers the update and overlays a wait screen that polls
  /api/health and reloads once the new version answers.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
menzelj
2026-06-12 09:01:08 +00:00
co-authored by Claude Fable 5
parent 11effdc2ca
commit a0dda120f5
10 changed files with 407 additions and 10 deletions
+3 -2
View File
@@ -11,6 +11,7 @@ from fastapi.responses import JSONResponse
from sqlmodel import Session
from config import settings
from version import APP_VERSION
from database import engine, init_db
from docker_client import DockerError
from routers import (
@@ -66,7 +67,7 @@ async def lifespan(app: FastAPI):
uptime_task.cancel()
app = FastAPI(title="StackPilot", version="0.31.1", lifespan=lifespan)
app = FastAPI(title="StackPilot", version=APP_VERSION, lifespan=lifespan)
app.add_middleware(
CORSMiddleware,
@@ -109,4 +110,4 @@ app.include_router(ws.router)
@app.get("/api/health")
def health() -> dict:
return {"status": "ok"}
return {"status": "ok", "version": APP_VERSION}