diff --git a/CHANGELOG.md b/CHANGELOG.md index b08f709..730b1f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 0.45.12 - 2026-05-26 + +- Changed `ani-cli-web` runtime version reporting to load directly from the project `VERSION` file instead of a duplicated hardcoded constant, which keeps Runtime info, API version responses, and startup logs in sync with release metadata. +- Added regression coverage to ensure the loaded runtime version matches the checked-in `VERSION` file. + ## 0.45.11 - 2026-05-26 - Fixed watchlist auto-download queueing so the first manual or scheduled refresh after adding a `Watching` series can pick up already-available missing episodes instead of waiting for a later refresh cycle. diff --git a/README.md b/README.md index 7b6f37a..8220c5f 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Small local web UI for a system-wide `ani-cli` install. -Current version: `0.45.11` +Current version: `0.45.12` ## Project Layout @@ -199,6 +199,7 @@ Layout: - `Dependencies` stays at the top as a full-width runtime status card. - The remaining Config sections use two columns on larger screens and collapse to one column at `1080px` width and below. - Runtime info shows both the `ani-cli-web` version and the installed `ani-cli` version. +- The `ani-cli-web` Runtime info version is read directly from the project `VERSION` file so the UI and startup logs stay aligned with release metadata. - Path fields include `Browse` buttons that open a host-side folder picker modal in the browser. Saved settings are written to `.ani-cli-web/config.json`. diff --git a/VERSION b/VERSION index a1cf49f..cbb488e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.45.11 +0.45.12 diff --git a/app_support.py b/app_support.py index 324a504..c5c5f5f 100644 --- a/app_support.py +++ b/app_support.py @@ -24,7 +24,7 @@ from uuid import uuid4 PROJECT_ROOT = Path(__file__).resolve().parent ANI_CLI = os.environ.get("ANI_CLI_BIN") or shutil.which("ani-cli") or "ani-cli" APP_NAME = "ani-cli-web" -VERSION = "0.45.10" +VERSION_FILE = PROJECT_ROOT / "VERSION" ALLANIME_BASE = "allanime.day" ALLANIME_API = f"https://api.{ALLANIME_BASE}" ALLANIME_REFERER = "https://allmanga.to" @@ -79,6 +79,17 @@ REMOTE_ACCESS_SESSION_TTL_SECONDS = 30 * 24 * 60 * 60 REMOTE_SESSION_STORE_LOCK = threading.RLock() +def load_app_version(default="0.0.0"): + try: + version = VERSION_FILE.read_text(encoding="utf-8").strip() + except OSError: + return default + return version or default + + +VERSION = load_app_version() + + def env_flag(name, default=False): raw = os.environ.get(name) if raw is None: diff --git a/test_app.py b/test_app.py index fa63ca3..72d44c0 100644 --- a/test_app.py +++ b/test_app.py @@ -2685,6 +2685,10 @@ class HandlerRouteTests(unittest.TestCase): self.assertEqual(handler.json_payload["version"], APP.VERSION) self.assertIn("ani_cli_version", handler.json_payload) + def test_loaded_runtime_version_matches_version_file(self): + expected_version = (ROOT / "VERSION").read_text(encoding="utf-8").strip() + self.assertEqual(APP.VERSION, expected_version) + def test_filesystem_browse_route_lists_directories(self): with tempfile.TemporaryDirectory() as temp_root: Path(temp_root, "folder-a").mkdir()