|
| 1 | +#!/usr/bin/env bash |
| 2 | +# CI-only helper: install the Linux system audio deps the suite needs — libportaudio2 |
| 3 | +# (sounddevice's PortAudio backend) and ffmpeg (decodes non-WAV/URL audio for the |
| 4 | +# `--sample` stream tests; the require_ffmpeg probe needs it on PATH). Three Ubuntu jobs |
| 5 | +# in .github/workflows/ci.yml need the identical pair, so the slow-mirror resilience |
| 6 | +# below lives in one place. |
| 7 | +# |
| 8 | +# The Azure Ubuntu apt mirror periodically degrades to a crawl (~100 KB/s). A plain |
| 9 | +# `apt-get install ffmpeg` pulls ffmpeg's ~62 MB codec dependency closure, which then |
| 10 | +# overruns the job timeout mid-download and gets cancelled before the tests run, bouncing |
| 11 | +# the PR out of the merge queue. So, mirroring the Windows ffmpeg step's strategy of |
| 12 | +# falling back to a static build off GitHub's release CDN: |
| 13 | +# * libportaudio2 has no portable prebuilt, so it always comes from apt — but it's tiny, |
| 14 | +# so a bounded retry rides out a slow mirror. |
| 15 | +# * ffmpeg is fetched as a static build from GitHub's release CDN (BtbN/FFmpeg-Builds — |
| 16 | +# the same origin the Windows job uses), bypassing apt's heavy codec chain on the |
| 17 | +# flaky mirror entirely, and prepended to GITHUB_PATH so later steps see it. |
| 18 | +set -euo pipefail |
| 19 | + |
| 20 | +# Run one bounded apt-get attempt, retrying a stalled/failed call a couple of times. A |
| 21 | +# stalled mirror connection is killed by `timeout` (run under sudo so the killer is root |
| 22 | +# and can reap apt) rather than wedging the whole job; the 3rd failure falls through. |
| 23 | +apt_retry() { |
| 24 | + local attempt |
| 25 | + for attempt in 1 2 3; do |
| 26 | + if sudo timeout --kill-after=10s 120s apt-get "$@"; then |
| 27 | + return 0 |
| 28 | + fi |
| 29 | + if [ "$attempt" -lt 3 ]; then |
| 30 | + echo "::warning::apt-get $* failed or stalled (attempt ${attempt}/3); retrying" >&2 |
| 31 | + sleep "$((attempt * 5))" |
| 32 | + fi |
| 33 | + done |
| 34 | + echo "::warning::apt-get $* failed after 3 attempts" >&2 |
| 35 | + return 1 |
| 36 | +} |
| 37 | + |
| 38 | +# A stale list is fine (the runner image's apt cache is recent), so don't let a slow |
| 39 | +# `update` be fatal; libportaudio2 itself has no CDN fallback, so that one must succeed. |
| 40 | +apt_retry update -o Acquire::Retries=3 || true |
| 41 | +apt_retry install -y --no-install-recommends -o Acquire::Retries=3 libportaudio2 |
| 42 | + |
| 43 | +# ffmpeg from GitHub's release CDN, not apt: a static, self-contained build off a reliable |
| 44 | +# origin sidesteps the 62 MB codec download the degraded apt mirror kept failing to serve. |
| 45 | +url="https://github.com/BtbN/FFmpeg-Builds/releases/download/latest/ffmpeg-master-latest-linux64-gpl.tar.xz" |
| 46 | +dest="${RUNNER_TEMP:-/tmp}/ffmpeg-static" |
| 47 | +mkdir -p "$dest" |
| 48 | +curl -fsSL --retry 3 --retry-all-errors "$url" | tar -xJ -C "$dest" --strip-components=1 |
| 49 | +echo "$dest/bin" >> "${GITHUB_PATH:-/dev/null}" |
| 50 | +export PATH="$dest/bin:$PATH" |
| 51 | + |
| 52 | +command -v ffmpeg >/dev/null || { |
| 53 | + echo "::error::ffmpeg unavailable after setup" >&2 |
| 54 | + exit 1 |
| 55 | +} |
| 56 | +ffmpeg -version >/dev/null |
| 57 | +echo "audio deps ready: libportaudio2 + ffmpeg ($(command -v ffmpeg))" |
0 commit comments