From 31c94d6beb7456a43adc42a2dc0a2b91766e354b Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Thu, 5 Nov 2026 10:39:32 -0500 Subject: [PATCH] ci: the weekly refresh reuses main's signed extension; worker tests pin the machine Two more reasons CI could not go green, found while fixing #6864. 1. sign-extension's "never go backwards" guard refused every weekly base refresh since at least 2026-10-04 (runs 8023, 9015, 9400, 9818). The refresh builds main, whose extension version (2026.9.25.1201) trails the highest one dev has signed since (2026.9.28.1403), so the guard exited before the cache lookup that would have found main's version already signed and reused it. The web image (:latest) was never refreshed. A version that is already signed now passes the guard: it is reused from its release, not signed again, so it cannot be a downgrade. 2. tests/test_api_workers.py read each lane's ceiling from the CI container's CPU quota and memory limit. Since run 10242 (2026-11-05) the runner's container allows fewer slots than two tests set (6 worker slots, 2 ML), so both got 400 "above what this container can hold". An autouse fixture now pins a 16-core, 64 GiB container, as test_worker_lanes.py already does. Task #6864. Co-Authored-By: Claude Opus 5.5 --- .forgejo/workflows/build.yml | 9 +++++++++ tests/test_api_workers.py | 13 +++++++++++++ 2 files changed, 22 insertions(+) diff --git a/.forgejo/workflows/build.yml b/.forgejo/workflows/build.yml index 8538bb3..6bedc66 100644 --- a/.forgejo/workflows/build.yml +++ b/.forgejo/workflows/build.yml @@ -787,6 +787,15 @@ jobs: print("guard: no ext-* release yet — nothing to go backwards from") raise SystemExit(0) + # A version that is already signed is reused from its release, not + # signed again, so it cannot be a downgrade. The weekly refresh builds + # main, whose version trails whatever dev has signed since; refusing + # it here would stop :latest from ever being refreshed while dev is + # ahead. + if any(v == derived for v, _ in signed): + print(f"guard: {derived_s} is already signed — reused, not re-signed") + raise SystemExit(0) + hi, hi_tag = signed[-1] print(f"guard: derived={derived_s} highest already signed={hi_tag}") if derived < hi: diff --git a/tests/test_api_workers.py b/tests/test_api_workers.py index 24de6b5..4866019 100644 --- a/tests/test_api_workers.py +++ b/tests/test_api_workers.py @@ -13,12 +13,25 @@ from sqlalchemy import select from backend.app.api import workers as workers_api from backend.app.models import WorkerLane from backend.app.services import worker_control as wc +from backend.app.services import worker_lanes as wl from backend.app.services.worker_lanes import LANES, SWEEP_PERIOD_SECONDS from tests.doubles import RecordingSession pytestmark = pytest.mark.integration +@pytest.fixture(autouse=True) +def a_known_machine(monkeypatch): + """A 16-core, 64 GiB container, whatever runs the suite. + + Each lane's ceiling is derived from the container's CPU quota and memory + limit, so without this the caps these tests may set depend on the CI + runner's size, and a smaller runner refuses them as above the ceiling. + """ + monkeypatch.setattr(wl, "container_cpu_count", lambda: 16) + monkeypatch.setattr(wl, "container_memory_bytes", lambda: 64 * wl.GIB) + + @pytest_asyncio.fixture async def no_live_workers(monkeypatch): """Nothing is running — which is the CI lane's actual truth, asserted