diff --git a/.github/workflows/complex-visual.yml b/.github/workflows/complex-visual.yml index 759cb61..5c0906d 100644 --- a/.github/workflows/complex-visual.yml +++ b/.github/workflows/complex-visual.yml @@ -36,11 +36,41 @@ jobs: run: uv sync --locked --extra dev --no-sources - name: Ensure local X11 fixture tools + # The job budget is 15 minutes and the campaign itself is the point of + # it. Without a step bound, one hung apt call consumes all 15 and the + # real work never runs. The equivalent apt step in openadapt-capture + # takes 19s, so 5 minutes covers three update attempts plus 30s of + # backoff with wide margin, and leaves at least 10 minutes for the + # dependency install and the campaign. + timeout-minutes: 5 run: | + set -uo pipefail if ! command -v Xvfb >/dev/null || ! command -v xvfb-run >/dev/null; then - sudo apt-get update + # The hosted runner resolves its Ubuntu mirror through + # /etc/apt/apt-mirrors.txt, which points at azure.archive.ubuntu.com. + # That mirror fails intermittently, and each failure costs minutes of + # apt retries. Prefer the canonical archive. Best-effort: an absent + # or already-canonical file changes nothing. + sudo sed -i \ + 's|http://azure.archive.ubuntu.com/ubuntu|http://archive.ubuntu.com/ubuntu|g' \ + /etc/apt/apt-mirrors.txt 2>/dev/null || true + update_ok="" + for attempt in 1 2 3; do + if sudo apt-get update; then + update_ok=1 + break + fi + echo "::warning::apt-get update failed (attempt ${attempt}/3); retrying" + sleep $((attempt * 10)) + done + if [ -z "$update_ok" ]; then + echo "::error::apt-get update failed three times; the Ubuntu mirror is unreachable" + exit 1 + fi + set -e sudo apt-get install --yes xvfb xauth fi + set -e python -c 'import tkinter' - name: Create dedicated actor identity