diff --git a/.github/actions/warm-test-images/action.yml b/.github/actions/warm-test-images/action.yml index 80b6ad703f9..812828b40d7 100644 --- a/.github/actions/warm-test-images/action.yml +++ b/.github/actions/warm-test-images/action.yml @@ -50,8 +50,35 @@ runs: echo "::warning::could not warm $canonical from GHCR mirror; falling back to Docker Hub" } - warm matrixdotorg/synapse:v1.126.0 synapse:v1.126.0 - warm rnwood/smtp4dev:v3.1 smtp4dev:v3.1 - warm postgres:16.3 postgres:16.3 - warm ghcr.io/navikt/mock-oauth2-server:4.0.1 mock-oauth2-server:4.0.1 - warm caddy:2.10.2-alpine caddy:2.10.2-alpine + # Pull the five in parallel. They are distinct images, so the daemon + # fetches them concurrently and the step costs about as much as the + # slowest one instead of the sum; every shard pays this, so the + # difference is machine-hours across a run. Each pull's output goes to + # its own file and is replayed in a fixed order afterwards, because + # interleaved `docker pull` progress from five images is unreadable + # exactly when someone is trying to work out which mirror failed. + warm_bg() { + log="$(mktemp)" + logs+=("$log") + warm "$1" "$2" >"$log" 2>&1 & + pids+=($!) + } + + logs=() + pids=() + warm_bg matrixdotorg/synapse:v1.126.0 synapse:v1.126.0 + warm_bg rnwood/smtp4dev:v3.1 smtp4dev:v3.1 + warm_bg postgres:16.3 postgres:16.3 + warm_bg ghcr.io/navikt/mock-oauth2-server:4.0.1 mock-oauth2-server:4.0.1 + warm_bg caddy:2.10.2-alpine caddy:2.10.2-alpine + + # `warm` never fails (it downgrades a miss to a warning), so nothing + # here needs to inspect exit status — but wait on each pid rather than + # bare `wait` so a future warm that does fail can be noticed. + for pid in "${pids[@]}"; do + wait "$pid" || true + done + for log in "${logs[@]}"; do + cat "$log" + rm -f "$log" + done