4 Commits
0.7.0 ... 0.7.1

Author SHA1 Message Date
5fff1b2692 add 0.7.1 2026-01-20 07:19:03 +00:00
c8356c7603 0.7.1 2026-01-20 07:17:45 +00:00
0c49a50fc9 0.7.1 2026-01-20 07:17:24 +00:00
fa48841645 0.7.1 2026-01-20 07:16:48 +00:00
4 changed files with 36 additions and 10 deletions

View File

@@ -11,6 +11,13 @@ Sections:
--- ---
## 0.7.1 2026-01-20
### Fixed
- GitHub version provider now reliably fetches the latest 20 releases/tags using authenticated API requests.
- Repositories that were previously fetched in a degraded state (only `latest` and `branch`) are now automatically refreshed on repository view.
- Cached version lists with incomplete data are no longer reused and are re-fetched from the provider.
## [0.7.0] - 2026-01-20 ## [0.7.0] - 2026-01-20
### Added ### Added

View File

@@ -808,13 +808,21 @@ class BCSCore:
_LOGGER.debug("BCS ensure_repo_details failed for %s", repo_id, exc_info=True) _LOGGER.debug("BCS ensure_repo_details failed for %s", repo_id, exc_info=True)
return r return r
async def list_repo_versions(self, repo_id: str, *, limit: int = 20) -> list[dict[str, Any]]: async def list_repo_versions(
self,
repo_id: str,
*,
limit: int = 20,
force_refresh: bool = False,
) -> list[dict[str, Any]]:
repo = self.get_repo(repo_id) repo = self.get_repo(repo_id)
if not repo: if not repo:
return [] return []
# Prefer cached version lists to avoid hammering provider APIs (notably GitHub unauthenticated # Prefer cached version lists to avoid hammering provider APIs (notably GitHub unauthenticated
# rate limits). We refresh on-demand when the user opens the selector. # rate limits). However, if the cached list is clearly a degraded fallback (e.g. only
# "Latest" + "Branch"), we treat it as stale and retry immediately when the user requests
# versions again.
cached = None cached = None
cached_ts = 0 cached_ts = 0
async with self._repo_cache_lock: async with self._repo_cache_lock:
@@ -823,8 +831,17 @@ class BCSCore:
cached_ts = int(cached.get("versions_ts", 0) or 0) cached_ts = int(cached.get("versions_ts", 0) or 0)
now = int(time.time()) now = int(time.time())
if isinstance(cached, dict) and cached.get("versions") and (now - cached_ts) < VERSIONS_CACHE_TTL_SECONDS: cached_versions = list(cached.get("versions") or []) if isinstance(cached, dict) else []
return list(cached.get("versions") or []) cache_fresh = (now - cached_ts) < VERSIONS_CACHE_TTL_SECONDS
# Cache hit if it's fresh and not degraded, unless the caller explicitly wants a refresh.
if (
not force_refresh
and cached_versions
and cache_fresh
and len(cached_versions) > 2
):
return cached_versions
try: try:
versions = await fetch_repo_versions( versions = await fetch_repo_versions(

View File

@@ -1,7 +1,7 @@
{ {
"domain": "bahmcloud_store", "domain": "bahmcloud_store",
"name": "Bahmcloud Store", "name": "Bahmcloud Store",
"version": "0.7.0", "version": "0.7.1",
"documentation": "https://git.bahmcloud.de/bahmcloud/bahmcloud_store", "documentation": "https://git.bahmcloud.de/bahmcloud/bahmcloud_store",
"config_flow": true, "config_flow": true,
"platforms": ["update"], "platforms": ["update"],

View File

@@ -537,7 +537,7 @@ async def fetch_repo_versions(
- source: release|tag|branch - source: release|tag|branch
Notes: Notes:
- Uses public endpoints (no tokens) for public repositories. - Uses provider APIs; for GitHub we include the configured token (if any) to avoid unauthenticated rate limits.
- We prefer releases first (if available), then tags. - We prefer releases first (if available), then tags.
""" """
@@ -575,11 +575,13 @@ async def fetch_repo_versions(
try: try:
if prov == "github": if prov == "github":
# Releases # Releases (prefer these over tags)
gh_headers = {"Accept": "application/vnd.github+json", "User-Agent": UA} # Use the configured GitHub token (if any) to avoid unauthenticated rate limits.
gh_headers = _github_headers(github_token)
per_page = max(1, min(int(limit), 100))
data, _ = await _safe_json( data, _ = await _safe_json(
session, session,
f"https://api.github.com/repos/{owner}/{repo}/releases?per_page={int(limit)}", f"https://api.github.com/repos/{owner}/{repo}/releases?per_page={per_page}",
headers=gh_headers, headers=gh_headers,
) )
if isinstance(data, list): if isinstance(data, list):
@@ -597,7 +599,7 @@ async def fetch_repo_versions(
# Tags # Tags
data, _ = await _safe_json( data, _ = await _safe_json(
session, session,
f"https://api.github.com/repos/{owner}/{repo}/tags?per_page={int(limit)}", f"https://api.github.com/repos/{owner}/{repo}/tags?per_page={per_page}",
headers=gh_headers, headers=gh_headers,
) )
if isinstance(data, list): if isinstance(data, list):