Compare commits

...

2 Commits

Author SHA1 Message Date
Lightjunction Assistant
e912488bbd refactor: simplify prerelease update selection 2026-07-01 03:44:09 +08:00
Lightjunction Assistant
0a8fb37ca3 fix: skip stable update prompt for newer prereleases 2026-06-29 03:18:20 +08:00
2 changed files with 82 additions and 20 deletions

View File

@@ -234,6 +234,45 @@ class RepoZipUpdator:
"""Semver 版本比较"""
return VersionComparator.compare_version(v1, v2)
def _is_prerelease_version(self, version: str) -> bool:
"""Check if a version string is a prerelease version."""
return bool(
re.search(
r"[\-_.]?(alpha|beta|rc|dev)[\-_.]?\d*$",
version,
re.IGNORECASE,
)
)
def _matches_prerelease_policy(
self,
release: dict,
consider_prerelease: bool,
) -> bool:
"""Return whether a release is allowed by the prerelease policy."""
return consider_prerelease or not self._is_prerelease_version(
release["tag_name"],
)
def _select_release_data(
self,
releases: list,
consider_prerelease: bool,
) -> dict | None:
"""Select the first release allowed by the prerelease policy."""
return next(
(
release
for release in releases
if self._matches_prerelease_policy(release, consider_prerelease)
),
None,
)
def _has_newer_version(self, current_version: str, release_version: str) -> bool:
"""Return whether the selected release is newer than current version."""
return self.compare_version(current_version, release_version) < 0
async def check_update(
self,
url: str,
@@ -241,29 +280,17 @@ class RepoZipUpdator:
consider_prerelease: bool = True,
) -> ReleaseInfo | None:
update_data = await self.fetch_release_info(url)
sel_release_data = None
if consider_prerelease:
tag_name = update_data[0]["tag_name"]
sel_release_data = update_data[0]
else:
for data in update_data:
# 跳过带有 alpha、beta 等预发布标签的版本
if re.search(
r"[\-_.]?(alpha|beta|rc|dev)[\-_.]?\d*$",
data["tag_name"],
re.IGNORECASE,
):
continue
tag_name = data["tag_name"]
sel_release_data = data
break
if not sel_release_data or not tag_name:
if not update_data:
logger.error("未找到合适的发布版本")
return None
if self.compare_version(current_version, tag_name) >= 0:
sel_release_data = self._select_release_data(update_data, consider_prerelease)
if not sel_release_data:
logger.error("未找到合适的发布版本")
return None
tag_name = sel_release_data["tag_name"]
if not self._has_newer_version(current_version, tag_name):
return None
return ReleaseInfo(
version=tag_name,

View File

@@ -418,6 +418,41 @@ async def test_plugin_update_validates_archive_before_removing_existing_plugin(
assert marker_path.read_text(encoding="utf-8") == "VALUE = 'old'\n"
@pytest.mark.asyncio
async def test_check_update_skips_stable_when_current_prerelease_is_newer(
monkeypatch: pytest.MonkeyPatch,
) -> None:
updator = RepoZipUpdator()
async def fake_fetch_release_info(url: str, latest: bool = True): # noqa: ARG001
return [
{
"version": "AstrBot v4.26.0-beta.1",
"published_at": "2026-06-20T00:00:00Z",
"body": "beta",
"tag_name": "v4.26.0-beta.1",
"zipball_url": "https://github.example/beta.zip",
},
{
"version": "AstrBot v4.25.6",
"published_at": "2026-06-19T00:00:00Z",
"body": "stable",
"tag_name": "v4.25.6",
"zipball_url": "https://github.example/stable.zip",
},
]
monkeypatch.setattr(updator, "fetch_release_info", fake_fetch_release_info)
result = await updator.check_update(
"https://example.invalid/releases",
current_version="v4.26.0-dev",
consider_prerelease=False,
)
assert result is None
@pytest.mark.asyncio
async def test_astrbot_updator_prefers_hosted_core_package(
monkeypatch: pytest.MonkeyPatch,