60 lines
2.1 KiB
Python
60 lines
2.1 KiB
Python
import logging
|
|
import os
|
|
|
|
from packaging.version import InvalidVersion, Version
|
|
|
|
from api.v1.schemas.version import GitHubRelease, UpdateCheckResponse, VersionInfo
|
|
from repositories.github_repository import GitHubRepository
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class VersionService:
|
|
def __init__(self, github_repo: GitHubRepository):
|
|
self._github_repo = github_repo
|
|
|
|
def get_current_version(self) -> VersionInfo:
|
|
version = os.environ.get("COMMIT_TAG", "dev")
|
|
build_date = os.environ.get("BUILD_DATE")
|
|
return VersionInfo(version=version, build_date=build_date)
|
|
|
|
async def check_for_updates(self) -> UpdateCheckResponse:
|
|
current = self.get_current_version()
|
|
latest = await self._github_repo.fetch_latest_release()
|
|
|
|
if latest is None:
|
|
return UpdateCheckResponse(current_version=current.version)
|
|
|
|
update_available, comparison_failed = self._is_newer(
|
|
latest.tag_name, current.version
|
|
)
|
|
|
|
# Dev builds: simulate update available so the full UI can be tested
|
|
is_dev = current.version in ("dev", "hosting-local")
|
|
if comparison_failed and is_dev:
|
|
update_available = True
|
|
|
|
return UpdateCheckResponse(
|
|
current_version=current.version,
|
|
latest_version=latest.tag_name,
|
|
update_available=update_available,
|
|
comparison_failed=comparison_failed,
|
|
latest_release=latest if update_available else None,
|
|
)
|
|
|
|
async def get_release_history(self) -> list[GitHubRelease]:
|
|
return await self._github_repo.fetch_releases()
|
|
|
|
@staticmethod
|
|
def _is_newer(latest_tag: str, current_tag: str) -> tuple[bool, bool]:
|
|
"""Compare version tags. Returns (update_available, comparison_failed)."""
|
|
try:
|
|
latest = Version(latest_tag.lstrip("v"))
|
|
current = Version(current_tag.lstrip("v"))
|
|
return (latest > current, False)
|
|
except InvalidVersion:
|
|
logger.warning(
|
|
"Invalid version comparison: %s vs %s", latest_tag, current_tag
|
|
)
|
|
return (False, True)
|