diff --git a/.gitignore b/.gitignore index 0439ebd3..86be1765 100644 --- a/.gitignore +++ b/.gitignore @@ -161,6 +161,7 @@ docker-compose.override.yml *.override.yml # Deployment & Security +.build-info deployment-local/ *.pem *.key diff --git a/app/core/build_info.py b/app/core/build_info.py new file mode 100644 index 00000000..e63000ef --- /dev/null +++ b/app/core/build_info.py @@ -0,0 +1,60 @@ +# app/core/build_info.py +""" +Build information utilities. + +Reads commit SHA and deploy timestamp from .build-info file +(written by scripts/deploy.sh at deploy time), or falls back +to git for local development. +""" + +import json +import logging +import subprocess +from datetime import UTC, datetime +from pathlib import Path + +logger = logging.getLogger(__name__) + +_BUILD_INFO_FILE = Path(__file__).resolve().parent.parent.parent / ".build-info" +_cached_info: dict | None = None + + +def get_build_info() -> dict: + """Return build info: commit, deployed_at, environment.""" + global _cached_info + if _cached_info is not None: + return _cached_info + + info = { + "commit": None, + "deployed_at": None, + } + + # Try .build-info file first (written by deploy.sh) + if _BUILD_INFO_FILE.is_file(): + try: + data = json.loads(_BUILD_INFO_FILE.read_text()) + info["commit"] = data.get("commit") + info["deployed_at"] = data.get("deployed_at") + except Exception as e: + logger.warning(f"Failed to read .build-info: {e}") + + # Fall back to git for local development + if not info["commit"]: + try: + result = subprocess.run( + ["git", "rev-parse", "--short=8", "HEAD"], + capture_output=True, + text=True, + timeout=5, + ) + if result.returncode == 0: + info["commit"] = result.stdout.strip() + except Exception: + pass + + if not info["deployed_at"]: + info["deployed_at"] = datetime.now(UTC).isoformat() + + _cached_info = info + return info diff --git a/app/templates/admin/partials/sidebar.html b/app/templates/admin/partials/sidebar.html index cc141919..cb351f64 100644 --- a/app/templates/admin/partials/sidebar.html +++ b/app/templates/admin/partials/sidebar.html @@ -101,8 +101,18 @@ DESKTOP SIDEBAR ============================================================================ #} -