feat(update): treat the testing channel as docker-only in the update check
All checks were successful
Testing Build / build (push) Successful in 8m47s
All checks were successful
Testing Build / build (push) Successful in 8m47s
A testing-<sha> build has no Gitea releases (the testing workflow builds only a Docker image), so the in-app update check must not fall through to the stable path - which would wrongly offer a stable "update". handle_api_update_check now short-circuits for a "testing" version with docker_only:true and nothing to update (no Gitea round-trip at all), and handle_api_update_apply refuses self-update on the testing channel the same way it already does for nightly. Two new tests cover both.
This commit is contained in:
@@ -2357,6 +2357,21 @@ class EndpointsMixin:
|
||||
|
||||
async def handle_api_update_check(self, request):
|
||||
current = self._read_version()
|
||||
# Testing channel (testing-<sha>) has no Gitea releases at all - it's
|
||||
# a Docker-only channel. Report that directly instead of falling
|
||||
# through to the stable path (which would wrongly offer a stable
|
||||
# "update"). The :testing image is rolling, so there's nothing to
|
||||
# compare a version against.
|
||||
if "testing" in current:
|
||||
return web.json_response({
|
||||
"current": current,
|
||||
"latest": current,
|
||||
"update_available": False,
|
||||
"tag": current,
|
||||
"docker_only": True,
|
||||
"changelog": "Testing channel - updates are delivered via Docker: "
|
||||
"docker compose pull && docker compose up -d",
|
||||
})
|
||||
is_nightly = "nightly" in current
|
||||
is_dev = "-dev+" in current
|
||||
if is_nightly:
|
||||
@@ -2441,9 +2456,11 @@ class EndpointsMixin:
|
||||
except Exception:
|
||||
return web.json_response({"error": "invalid json"}, status=400)
|
||||
new_tag = data.get("tag", "")
|
||||
if "nightly" in self._read_version():
|
||||
_cur = self._read_version()
|
||||
if "nightly" in _cur or "testing" in _cur:
|
||||
channel = "testing" if "testing" in _cur else "nightly"
|
||||
return web.json_response(
|
||||
{"error": "nightly updates are delivered via Docker: "
|
||||
{"error": f"{channel} updates are delivered via Docker: "
|
||||
"docker compose pull && docker compose up -d"}, status=400)
|
||||
if getattr(sys, "frozen", False):
|
||||
return web.json_response(
|
||||
|
||||
@@ -21,6 +21,43 @@ async def test_update_apply_invalid_json_returns_400(client):
|
||||
assert resp.status == 400
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_update_check_testing_channel_is_docker_only(client):
|
||||
"""A testing-<sha> build has no Gitea releases at all - the check must
|
||||
report a docker-only channel with nothing to update, NOT fall through to
|
||||
the stable path and wrongly offer a stable "update". Must not even call
|
||||
the Gitea API."""
|
||||
c, bridge = client
|
||||
bridge._read_version = lambda: "testing-2e4dbf0"
|
||||
|
||||
# Patch the API so that if the handler wrongly tried to fetch releases,
|
||||
# the test would notice (mock returns something, but the handler must not
|
||||
# reach it).
|
||||
with patch("aiohttp.ClientSession.get") as mock_get:
|
||||
resp = await c.get("/api/update/check")
|
||||
data = await resp.json()
|
||||
|
||||
assert resp.status == 200
|
||||
assert data["update_available"] is False
|
||||
assert data["docker_only"] is True
|
||||
assert data["current"] == "testing-2e4dbf0"
|
||||
mock_get.assert_not_called() # no Gitea round-trip for the testing channel
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_update_apply_testing_channel_blocked(client):
|
||||
"""Self-update must be refused on the testing channel, same as nightly -
|
||||
testing images are delivered via Docker only."""
|
||||
c, bridge = client
|
||||
bridge._read_version = lambda: "testing-2e4dbf0"
|
||||
|
||||
resp = await c.post("/api/update/apply", json={"tag": "whatever"})
|
||||
data = await resp.json()
|
||||
assert resp.status == 400
|
||||
assert "testing" in data["error"]
|
||||
assert "docker" in data["error"].lower()
|
||||
|
||||
|
||||
def _fake_releases_response(payload):
|
||||
resp = MagicMock()
|
||||
resp.status = 200
|
||||
|
||||
Reference in New Issue
Block a user