diff --git a/dagger/ci.py b/dagger/ci.py index 6a66141..77d24bb 100644 --- a/dagger/ci.py +++ b/dagger/ci.py @@ -6,8 +6,25 @@ import anyio import dagger +# Substrings that mark a transient registry / image-pull failure (e.g. a Docker +# Hub 5xx on the python:3.11-bookworm pull, or a registry.dagger.io timeout) that +# is worth retrying rather than failing the whole pipeline. +_TRANSIENT_MARKERS = ( + "pull image", + "failed to authorize", + "failed to fetch oauth", + "TransportQueryError", + "i/o timeout", + "connection reset", + "context deadline exceeded", + " 502", + " 503", + " 520", + " 429", +) -async def main() -> None: + +async def _run_checks() -> None: config = dagger.Config(log_output=sys.stderr) async with dagger.Connection(config) as client: source = client.host().directory( @@ -39,5 +56,21 @@ async def main() -> None: await checks.sync() +async def main() -> None: + attempts = 3 + for attempt in range(1, attempts + 1): + try: + await _run_checks() + return + except Exception as exc: # noqa: BLE001 — retry only transient registry/pull failures + message = str(exc) + transient = any(marker in message for marker in _TRANSIENT_MARKERS) + if attempt < attempts and transient: + print(f"dagger: transient registry/pull failure on attempt {attempt}; retrying in 20s", file=sys.stderr) + await anyio.sleep(20) + continue + raise + + if __name__ == "__main__": anyio.run(main)