ADR-0317: Path-filter Docker + FFmpeg-integration on doc/Python-only PRs¶
- Status: Accepted
- Date: 2026-05-06
- Deciders: Lusoris, Claude
- Tags:
ci,build
Context¶
The recent doc / Python-only merge train (PRs #409, #411, #412) saw two non-required CI jobs go red on every push:
Docker Image Build(.github/workflows/docker-image.yml) — failed inside the image'sapt-get installstep with exit code 100. Logs from run25118138131(PR #411 head70b036e5) show the failure is a transient apt-mirror flake on the Ubuntu base image; the diff under test contains zero Dockerfile, libvmaf, or build-system changes.FFmpeg — SYCL (Build Only)in.github/workflows/ffmpeg-integration.yml— failed atmake installof FFmpeg withvf_libvmaf_tune.c:178: ‘AVFilterLink’ has no member named ‘frame_rate’(run25416488158on master11d97855). This is a real fork-local bug introduced by patch0008-add-libvmaf_tune-filter.patch(ADR-0312, PR #409):frame_ratemoved offAVFilterLinkin FFmpeg n7+ and the patch did not migrate toff_filter_link()the way patches 0005 / 0006 already do. The full-make installlane catches this; the narrowvf_libvmaf.o-only Vulkan lane does not, which is why only SYCL goes red.
Both jobs are non-required — the Required Checks Aggregator (ADR-0313) gates merge on a fixed list of 23 build/lint checks that excludes Docker, FFmpeg-SYCL, and FFmpeg-Vulkan. So merge was unblocked, but every push to a doc-only PR cost ~10–15 min of runner time and produced two red checks that reviewers had to mentally filter out. Path-filtering the workflows so they fire only on diffs that actually exercise their inputs eliminates the noise without weakening the merge gate.
The underlying patch-0008 bug is real and remains as a follow-up — it will surface as soon as a libvmaf/ or ffmpeg-patches/ change runs the SYCL lane, which is exactly when it should be caught and fixed. This ADR is about the flake on irrelevant diffs, not the upstream-API drift.
Decision¶
We will add paths: filters to both docker-image.yml and ffmpeg-integration.yml so they trigger only when their actual inputs change. For Docker: Dockerfile, .dockerignore, libvmaf/**, meson.build, meson_options.txt, the workflow file itself. For FFmpeg integration: libvmaf/**, ffmpeg-patches/**, meson.build, meson_options.txt, the workflow file itself. Neither workflow is a required check (per ADR-0313's aggregator allow-list), so the merge gate is unaffected.
Alternatives considered¶
| Option | Pros | Cons | Why not chosen |
|---|---|---|---|
| Path-filter both workflows (chosen) | Eliminates the flake on the exact PR class where it's noise (doc/Python-only); preserves coverage on diffs that actually matter; matches the existing docs.yml precedent on this fork; small diff. | Path-filter rules can drift from build inputs over time and silently skip a workflow that should have fired; needs maintenance whenever the build picks up a new top-level input. | Chosen — the maintenance cost is bounded (one-line additions) and the precedent already exists for docs.yml. |
Add continue-on-error: true to FFmpeg-SYCL (Docker already has it) | One-line change; keeps coverage on every push. | Doesn't fix the root cause of runner-time waste; jobs still consume 10–15 min per push and still display red, just without blocking merge — exactly the state the merge train was already in and that motivated this PR. | Rejected — the user's brief explicitly flagged the runner-time burn, not just the merge-gate impact. |
Quarantine to nightly (move both to a scheduled cron: workflow) | Zero per-push cost; still catches regressions within 24 h. | Loses the per-PR signal — a Dockerfile or ffmpeg-patches change wouldn't be caught until the nightly run, after merge; the bug would land on master with no pre-merge gate. | Rejected — per-PR coverage on the inputs that do exercise these jobs is exactly what we want; we just don't want the firing on inputs that don't. |
Fix patch 0008 in this PR (use ff_filter_link() like 0005/0006) | Closes the SYCL-lane real bug at the same time. | Out of scope for the brief ("fix two CI flakes"); changing an ffmpeg-patches/ file is a non-trivial integration concern that wants its own PR + series replay verification per CLAUDE rule 14; conflates two unrelated reviews. | Rejected — tracked as a follow-up; the path-filter also doesn't hide it (any libvmaf/ or ffmpeg-patches/ PR will still run SYCL and surface the bug). |
Consequences¶
- Positive: Doc-only / Python-only / vmaf-tune-only PRs no longer trigger the two flaky jobs; the merge train gets ~30 min of runner time back per PR; review surface is cleaner (no red non-required checks).
- Negative: A regression that only manifests when one of these jobs runs on a diff outside the path filter (e.g. a Python change that somehow alters Docker behaviour) wouldn't be caught pre-merge. The risk is theoretical — both workflows build C/C++ artefacts that have no Python-side coupling.
- Neutral / follow-ups:
- Patch 0008 (
vf_libvmaf_tune.c) needs its own PR migratingoutlink->frame_rate = mainlink->frame_rate;to useff_filter_link(outlink)->frame_rate/ff_filter_link(mainlink)->frame_rate, matching the pattern in patches 0005 / 0006. The path-filter does not suppress this bug; it surfaces on the next libvmaf/ or ffmpeg-patches/ touching PR. - If the path filter list ever drifts from the actual build inputs,
workflow_dispatch:is preserved on both workflows so a maintainer can manually trigger a run.
References¶
- ADR-0313 — Required Checks Aggregator (defines which checks block merge; Docker + FFmpeg-SYCL are not in the list).
- ADR-0312 — vmaf-tune ffmpeg-patches integration (introduced patch 0008 whose
AVFilterLink::frame_ratereference is the SYCL lane's deterministic failure). - PRs #409, #411, #412 — the doc/Python-only merge train where the flake pattern was observed.
.github/workflows/docs.yml— existing path-filter precedent on this fork.- Source:
req(direct user instruction to fix two persistent CI flakes tripping on doc/Python-only merge train, paraphrased: "they're burning 10–15 minutes of runner time per push on PRs that don't even touch C/C++ or Dockerfile").