Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5fff1b2692 | |||
| c8356c7603 | |||
| 0c49a50fc9 | |||
| fa48841645 |
@@ -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
|
||||
|
||||
### Added
|
||||
|
||||
@@ -808,13 +808,21 @@ class BCSCore:
|
||||
_LOGGER.debug("BCS ensure_repo_details failed for %s", repo_id, exc_info=True)
|
||||
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)
|
||||
if not repo:
|
||||
return []
|
||||
|
||||
# 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_ts = 0
|
||||
async with self._repo_cache_lock:
|
||||
@@ -823,8 +831,17 @@ class BCSCore:
|
||||
cached_ts = int(cached.get("versions_ts", 0) or 0)
|
||||
|
||||
now = int(time.time())
|
||||
if isinstance(cached, dict) and cached.get("versions") and (now - cached_ts) < VERSIONS_CACHE_TTL_SECONDS:
|
||||
return list(cached.get("versions") or [])
|
||||
cached_versions = list(cached.get("versions") or []) if isinstance(cached, dict) else []
|
||||
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:
|
||||
versions = await fetch_repo_versions(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"domain": "bahmcloud_store",
|
||||
"name": "Bahmcloud Store",
|
||||
"version": "0.7.0",
|
||||
"version": "0.7.1",
|
||||
"documentation": "https://git.bahmcloud.de/bahmcloud/bahmcloud_store",
|
||||
"config_flow": true,
|
||||
"platforms": ["update"],
|
||||
|
||||
@@ -537,7 +537,7 @@ async def fetch_repo_versions(
|
||||
- source: release|tag|branch
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
@@ -575,11 +575,13 @@ async def fetch_repo_versions(
|
||||
|
||||
try:
|
||||
if prov == "github":
|
||||
# Releases
|
||||
gh_headers = {"Accept": "application/vnd.github+json", "User-Agent": UA}
|
||||
# Releases (prefer these over tags)
|
||||
# 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(
|
||||
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,
|
||||
)
|
||||
if isinstance(data, list):
|
||||
@@ -597,7 +599,7 @@ async def fetch_repo_versions(
|
||||
# Tags
|
||||
data, _ = await _safe_json(
|
||||
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,
|
||||
)
|
||||
if isinstance(data, list):
|
||||
|
||||
Reference in New Issue
Block a user