Sync backend/frontend versions to Docker/VERSION and read version from it

This commit is contained in:
2026-03-19 19:13:38 +01:00
parent 133ab2e82c
commit 80a6bac33e
5 changed files with 51 additions and 13 deletions

View File

@@ -157,6 +157,8 @@ This document breaks the entire BanGUI project into development stages, ordered
- Bumping only `Docker/VERSION` (e.g. `v0.9.9`) causes both layers to pick up the new version without touching any other file. - Bumping only `Docker/VERSION` (e.g. `v0.9.9`) causes both layers to pick up the new version without touching any other file.
- All existing tests pass (`pytest backend/`). - All existing tests pass (`pytest backend/`).
**Status:** ✅ Completed (2026-03-19)
--- ---
### Task GV-2 — Expose the BanGUI version through the API ### Task GV-2 — Expose the BanGUI version through the API

View File

@@ -30,21 +30,39 @@ def _read_pyproject_version() -> str:
return str(data["project"]["version"]) return str(data["project"]["version"])
def _read_docker_version() -> str:
"""Read the project version from ``Docker/VERSION``.
This file is the single source of truth for release scripts and must not be
out of sync with the frontend and backend versions.
"""
repo_root = Path(__file__).resolve().parents[2]
version_path = repo_root / "Docker" / "VERSION"
if not version_path.exists():
raise FileNotFoundError(f"Docker/VERSION not found at {version_path}")
version = version_path.read_text(encoding="utf-8").strip()
return version.lstrip("v")
def _read_version() -> str: def _read_version() -> str:
"""Return the current package version. """Return the current package version.
Prefer the project metadata in ``pyproject.toml`` when available, since this Prefer the release artifact in ``Docker/VERSION`` when available so the
is the single source of truth for local development and is kept in sync with backend version always matches what the release tooling publishes.
the frontend and Docker release version.
When running from an installed distribution where the ``pyproject.toml`` If that file is missing (e.g. in a production wheel or a local checkout),
is not available, fall back to installed package metadata. fall back to ``pyproject.toml`` and finally installed package metadata.
""" """
try: try:
return _read_pyproject_version() return _read_docker_version()
except FileNotFoundError: except FileNotFoundError:
return importlib.metadata.version(PACKAGE_NAME) try:
return _read_pyproject_version()
except FileNotFoundError:
return importlib.metadata.version(PACKAGE_NAME)
__version__ = _read_version() __version__ = _read_version()

View File

@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
[project] [project]
name = "bangui-backend" name = "bangui-backend"
version = "0.9.4" version = "0.9.8"
description = "BanGUI backend — fail2ban web management interface" description = "BanGUI backend — fail2ban web management interface"
requires-python = ">=3.12" requires-python = ">=3.12"
dependencies = [ dependencies = [

View File

@@ -0,0 +1,15 @@
from __future__ import annotations
from pathlib import Path
import app
def test_app_version_matches_docker_version() -> None:
"""The backend version should match the signed off Docker release version."""
repo_root = Path(__file__).resolve().parents[2]
version_file = repo_root / "Docker" / "VERSION"
expected = version_file.read_text(encoding="utf-8").strip().lstrip("v")
assert app.__version__ == expected

View File

@@ -3,16 +3,19 @@ import react from "@vitejs/plugin-react";
import { resolve } from "path"; import { resolve } from "path";
import { readFileSync } from "node:fs"; import { readFileSync } from "node:fs";
const pkg = JSON.parse( const appVersion = readFileSync(
readFileSync(resolve(__dirname, "package.json"), "utf-8"), resolve(__dirname, "../Docker/VERSION"),
) as { version: string }; "utf-8",
)
.trim()
.replace(/^v/, "");
// https://vitejs.dev/config/ // https://vitejs.dev/config/
export default defineConfig({ export default defineConfig({
plugins: [react()], plugins: [react()],
define: { define: {
/** BanGUI application version injected at build time from package.json. */ /** BanGUI application version injected at build time from Docker/VERSION. */
__APP_VERSION__: JSON.stringify(pkg.version), __APP_VERSION__: JSON.stringify(appVersion),
}, },
resolve: { resolve: {
alias: { alias: {