fix(version): VERSION-file as source of truth

This commit is contained in:
npeter83 2026-06-15 02:22:27 +02:00
commit 6c8b9d6986
2 changed files with 30 additions and 10 deletions

View file

@ -1,5 +1,7 @@
# Build/version info, injected via --build-arg (defaults keep un-built/dev runs working). # Build/version info. APP_VERSION comes from the committed VERSION file (always correct,
ARG APP_VERSION=dev # even for a plain `docker compose build`); GIT_SHA/BUILD_DATE are best-effort build-args
# the deploy scripts pass. An explicit APP_VERSION build-arg still overrides the file.
ARG APP_VERSION=
ARG GIT_SHA=unknown ARG GIT_SHA=unknown
ARG BUILD_DATE= ARG BUILD_DATE=
@ -8,24 +10,25 @@ FROM node:20-alpine AS frontend
ARG APP_VERSION ARG APP_VERSION
ARG GIT_SHA ARG GIT_SHA
ARG BUILD_DATE ARG BUILD_DATE
# Vite inlines VITE_*-prefixed env into the bundle at build time.
ENV VITE_APP_VERSION=$APP_VERSION VITE_GIT_SHA=$GIT_SHA VITE_BUILD_DATE=$BUILD_DATE
WORKDIR /fe WORKDIR /fe
COPY frontend/package.json ./ COPY frontend/package.json ./
RUN npm install RUN npm install
COPY frontend/ ./ COPY frontend/ ./
RUN npm run build COPY VERSION ./.version
# Vite inlines VITE_*-prefixed env at build time; version falls back to the VERSION file.
RUN VITE_APP_VERSION="${APP_VERSION:-$(cat ./.version)}" \
VITE_GIT_SHA="$GIT_SHA" \
VITE_BUILD_DATE="$BUILD_DATE" \
npm run build
# Stage 2: backend runtime, serving the built SPA # Stage 2: backend runtime, serving the built SPA
FROM python:3.12-slim FROM python:3.12-slim
ARG APP_VERSION
ARG GIT_SHA ARG GIT_SHA
ARG BUILD_DATE ARG BUILD_DATE
ENV PYTHONDONTWRITEBYTECODE=1 \ ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \ PYTHONUNBUFFERED=1 \
PIP_NO_CACHE_DIR=1 \ PIP_NO_CACHE_DIR=1 \
PIP_DISABLE_PIP_VERSION_CHECK=1 \ PIP_DISABLE_PIP_VERSION_CHECK=1 \
APP_VERSION=$APP_VERSION \
GIT_SHA=$GIT_SHA \ GIT_SHA=$GIT_SHA \
BUILD_DATE=$BUILD_DATE BUILD_DATE=$BUILD_DATE
@ -35,6 +38,8 @@ COPY backend/requirements.txt .
RUN pip install --upgrade pip && pip install -r requirements.txt RUN pip install --upgrade pip && pip install -r requirements.txt
COPY backend/ . COPY backend/ .
# Read at runtime by config.py as the app_version (a committed single source of truth).
COPY VERSION ./VERSION
COPY --from=frontend /fe/dist ./app/static_spa COPY --from=frontend /fe/dist ./app/static_spa
RUN adduser --disabled-password --gecos "" appuser && chown -R appuser /app RUN adduser --disabled-password --gecos "" appuser && chown -R appuser /app

View file

@ -1,3 +1,5 @@
from pathlib import Path
from pydantic import model_validator from pydantic import model_validator
from pydantic_settings import BaseSettings, SettingsConfigDict from pydantic_settings import BaseSettings, SettingsConfigDict
@ -5,13 +7,26 @@ from pydantic_settings import BaseSettings, SettingsConfigDict
_DEFAULT_SECRET_KEY = "change-me-session-key" _DEFAULT_SECRET_KEY = "change-me-session-key"
def _version_from_file() -> str:
"""The committed VERSION file (copied into the image at /app/VERSION) is the single
source of truth for the app version; falls back to 'dev' for un-built/local runs."""
for p in (Path(__file__).resolve().parents[1] / "VERSION", Path("VERSION")):
try:
v = p.read_text(encoding="utf-8").strip()
if v:
return v
except OSError:
continue
return "dev"
class Settings(BaseSettings): class Settings(BaseSettings):
model_config = SettingsConfigDict(env_file=".env", extra="ignore") model_config = SettingsConfigDict(env_file=".env", extra="ignore")
app_name: str = "Siftlode" app_name: str = "Siftlode"
# Build/version info, injected at image build time (Docker build-args -> env). Defaults # Version from the committed VERSION file (an explicit APP_VERSION env still overrides);
# apply for un-built/dev runs; the About dialog and version banner surface these. # git_sha/build_date are injected at image build time. Surfaced by /api/version.
app_version: str = "dev" app_version: str = _version_from_file()
git_sha: str = "unknown" git_sha: str = "unknown"
build_date: str = "" build_date: str = ""