Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 26 additions & 8 deletions .github/actions/e2e-setup/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,29 @@ runs:
# Windows e2e jobs. The key is the ISO week, so a newer ffmpeg arrives within a week:
# the jobs that miss install it through Chocolatey as before, and the first to finish
# saves it (the others are refused the same key, a warning). Linux keeps apt: Firefox
# decodes through the system's libavcodec, not a program in a folder.
# decodes through the system's libavcodec, not a program in a folder. But the packages
# apt fetches are kept the same way, a week per runner image, so the mirror only has
# to send its package lists and what changed that week: on 2026-10-22 it sent less
# than a package a second, and three runs failed with three 300 s attempts each.
- name: This week's ffmpeg cache key
if: runner.os == 'Windows'
id: ffmpeg-key
shell: bash
run: echo "key=e2e-ffmpeg-windows-$(date -u +%G-W%V)" >> "$GITHUB_OUTPUT"
run: |
if [ "$RUNNER_OS" = Windows ]; then
echo "key=e2e-ffmpeg-windows-$(date -u +%G-W%V)" >> "$GITHUB_OUTPUT"
echo "path=~/ffmpeg-e2e" >> "$GITHUB_OUTPUT"
else
echo "key=e2e-apt-${ImageOS:-linux}-$(date -u +%G-W%V)" >> "$GITHUB_OUTPUT"
# The packages only: apt's lock file and partial/ are root's, which the save
# (not root) could not read.
echo "path=~/apt-e2e/*.deb" >> "$GITHUB_OUTPUT"
fi

- name: Restore ffmpeg from the cache
if: runner.os == 'Windows'
id: ffmpeg-cache
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ~/ffmpeg-e2e
path: ${{ steps.ffmpeg-key.outputs.path }}
key: ${{ steps.ffmpeg-key.outputs.key }}

# Linux: Firefox decodes H.264/AAC through the system ffmpeg; without it every stream
Expand Down Expand Up @@ -74,17 +84,25 @@ runs:
# it is a failed attempt like any other.
printf 'Acquire::http::Timeout "30";\nAcquire::https::Timeout "30";\nAcquire::Retries "3";\n' |
sudo tee /etc/apt/apt.conf.d/99-faststream-e2e-timeouts > /dev/null
# apt takes the packages from, and downloads them to, the folder the cache keeps.
archives="$HOME/apt-e2e"
mkdir -p "$archives/partial"
fi
for attempt in 1 2 3; do
if [ "$RUNNER_OS" = Windows ]; then
choco install ffmpeg -y --no-progress && break
else
sudo timeout -k 10 120 apt-get update &&
sudo timeout -k 10 300 apt-get install -y --no-install-recommends ffmpeg pulseaudio pulseaudio-utils && break
sudo timeout -k 10 300 apt-get install -y --no-install-recommends ffmpeg pulseaudio pulseaudio-utils \
-o Dir::Cache::Archives="$archives" && break
fi
echo "::warning::Installing ffmpeg failed (attempt $attempt of 3); trying again in 30 s."
sleep 30
done
# A miss saves this week's packages for the jobs after it.
if [ "$RUNNER_OS" != Windows ] && [ "$CACHE_HIT" != true ] && compgen -G "$archives/*.deb" > /dev/null; then
echo "save=true" >> "$GITHUB_OUTPUT"
fi
if [ "$RUNNER_OS" = Windows ]; then
# The programs themselves for the cache, not Chocolatey's shims to them, from where
# Chocolatey is (ChocolateyInstall, on the runner C:\ProgramData\chocolatey).
Expand All @@ -107,12 +125,12 @@ runs:
ffmpeg -hide_banner -version | sed -n 1p

- name: Save ffmpeg to the cache
if: runner.os == 'Windows' && steps.ffmpeg.outputs.save == 'true'
if: steps.ffmpeg.outputs.save == 'true'
# Jobs that missed the same week race to save it; a refused save fails no job.
continue-on-error: true
uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ~/ffmpeg-e2e
path: ${{ steps.ffmpeg-key.outputs.path }}
key: ${{ steps.ffmpeg-key.outputs.key }}

# sample.mp4, which every e2e fixture is made from, comes from test-videos.co.uk, which
Expand Down
19 changes: 18 additions & 1 deletion tests/workflows/e2e-setup.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ echo "apt-get $*" >> "$FIX/calls"
[ -e "$FIX/apt-fails" ] && exit 100
if [ "$1" = install ]; then
cp "$STUBS/pulseaudio" "$STUBS/pactl" "$FIX/bin/"
# With -o Dir::Cache::Archives=<folder>, a downloaded package is left there, as apt does.
for arg in "$@"; do
case "$arg" in Dir::Cache::Archives=*) : > "${arg#*=}/ffmpeg_7.0_amd64.deb" ;; esac
done
fi
EOF
cat > "$here/stubs/sleep" <<'EOF'
Expand Down Expand Up @@ -247,7 +251,11 @@ check '... the update too' contains "$FIX/calls" 'sudo timeout -k 10 120 apt-get
check 'logs the version' contains "$FIX/out" 'ffmpeg version'
check 'no Chocolatey' lacks "$FIX/calls" 'choco'
check 'adds nothing to PATH' test ! -s "$FIX/path"
check 'saves nothing' test ! -s "$FIX/output"
# A mirror that sent less than a package a second failed three runs (2026-10-22).
check 'keeps the packages in the folder the cache saves' contains "$FIX/calls" \
"pulseaudio-utils -o Dir::Cache::Archives=$FIX/home/apt-e2e"
check '... with the partial/ folder apt needs' test -d "$FIX/home/apt-e2e/partial"
check 'a miss asks the save step to save them' contains "$FIX/output" 'save=true'
# A mirror that stopped sending held the step for 19 minutes (2026-10-06).
check 'sets apt to give up on a stalled download' contains "$FIX/calls" 'sudo tee /etc/apt/apt.conf.d/99-faststream-e2e-timeouts'
check '... after 30 s without data' contains "$FIX/tee-99-faststream-e2e-timeouts" 'Acquire::http::Timeout "30";'
Expand All @@ -263,6 +271,15 @@ check 'then updated again' test "$(grep -c '^apt-get update$' "$FIX/calls")" -eq
check 'installed once' test "$(grep -c '^apt-get install' "$FIX/calls")" -eq 1
check 'logs the version' contains "$FIX/out" 'ffmpeg version'

ffmpeg_scenario 'Linux, a cache hit: apt installs from the restored packages, nothing saved' Linux true
check 'succeeds' test "$status" -eq 0
check 'installs from the cached folder' contains "$FIX/calls" "-o Dir::Cache::Archives=$FIX/home/apt-e2e"
check 'saves nothing' test ! -s "$FIX/output"

ffmpeg_scenario 'Linux, apt that keeps failing: nothing saved' Linux '' apt-fails
check 'tried three times' test "$(grep -c '^apt-get update' "$FIX/calls")" -eq 3
check 'saves nothing' test ! -s "$FIX/output"

ffmpeg_scenario 'Windows, a cache hit: the cached programs, no Chocolatey' Windows true cache-has
check 'succeeds' test "$status" -eq 0
check 'says so' contains "$FIX/out" "ffmpeg from the cache ($FIX/home/ffmpeg-e2e)."
Expand Down
Loading