fix(build): stop VMAF_VERSION degrading to a bare commit abbreviation - #1266
Merged
Merged
Conversation
26 tasks
lusoris
marked this pull request as ready for review
September 3, 2026 21:00
lusoris
force-pushed
the
fix/vcs-version-bare-sha
branch
from
September 3, 2026 21:01
ec0301e to
82f6fa3
Compare
test_output::test_vmaf_version failed the Intel LLVM and macOS Clang legs of build.yml on PR #1223, a PR that does not touch test_output.c, does not touch any version surface, and whose only meson change is a CUDA include path. The test is byte-identical on master. The failure is not that PR's. Root cause. core/include/meson.build derives VMAF_VERSION from `git describe --tags --long --match 'v*.*.*' --always`. With --always, git exits 0 even when no matching tag is reachable and prints a bare abbreviated object name, which meson substitutes into vcs_version.h verbatim. build.yml checks out at the actions/checkout default fetch-depth of 1, which fetches no tags, so every build on that workflow has been stamping a commit abbreviation where a version belongs — `vmaf --version`, the JSON and XML `version` attribute, and vmaf_version() all reported it. That is silent until the abbreviation happens to contain no ASCII digit, which is what test_vmaf_version asserts against. #1223's merge commit was abafdfc, abbreviating to "abafdfc" — no digit. Roughly one commit in a thousand, (6/16)^7. Reproduced exactly: a depth-1 tagless fetch of that commit run through mesonbuild's vcstagger yields VMAF_VERSION="abafdfc" before this change and "3.2.1" after. Master is not exempt, it has only been lucky. Its build.yml legs do run and are green, but all 20 most recent master commits abbreviate with a digit; the defect fires on whichever commit first abbreviates to all letters. PR merge commits simply roll the dice more often. Dropping --always makes git exit non-zero in precisely those cases, and vcstagger.py substitutes the vcs_tag fallback on any exception from the subprocess. The fallback is now spelled out rather than left implicit, since it is the entire tagless path. When a tag is reachable the --long form still embeds the commit, so no provenance is lost: v3.1.0-2417-g1ee6ebde42. build.yml also moves to fetch-depth 0, matching libvmaf-build-matrix.yml, so CI exercises the tagged path rather than the fallback. A real coverage gap kept the third leg quiet. The Windows job runs an explicit whitelist that omitted test_output; it now runs it, and the test already carries a GetTempPathA/GetTempFileNameA path for that platform. That loop also gained `|| exit /b 1`: GitHub runs `shell: cmd` as `%ComSpec% /D /E:ON /V:OFF /S /C "CALL ..."`, so the step result was the errorlevel of the last executable alone and a failure in any earlier test was discarded outright. /V:OFF rules out !ERRORLEVEL!, so `||` is the portable check. scripts/ci/check-vcs-version-not-bare-sha.sh keeps --always out: it brackets the vcs_tag call, strips comments so prose may discuss the flag, and fails if --always returns, if the explicit fallback goes missing, or if --match is dropped. Negative-tested on all three; positive-tested on the restored file and on a comment mentioning the flag outside the call. Upstream Netflix carries the --always form (verified against upstream/master:libvmaf/include/meson.build), so this file will conflict on a sync — the gate turns a careless resolution into a build failure rather than a silently wrong version. Wired into `make lint-sh`. Verified: CPU build clean, fast suite 106 Ok / 0 Fail, test_output 13/13, `vmaf --version` prints v3.1.0-2417-g1ee6ebde42, pre-commit clean on all touched files. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Adds the docs/state.md row + Updated line for the version-string defect (ADR-0165 / CLAUDE.md §12 r13) and the scripts/ci/AGENTS.md section covering the three properties check-vcs-version-not-bare-sha.sh enforces and why build.yml's fetch-depth: 0 is load-bearing. The row records that master's build.yml legs do run and are green, and that this is luck rather than coverage: every recent master commit abbreviated with a digit, so the defect is latent on master rather than absent from it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
lusoris
force-pushed
the
fix/vcs-version-bare-sha
branch
from
September 3, 2026 21:09
82f6fa3 to
e4e26da
Compare
scripts/release/concat-changelog-fragments.sh --check gates on drift between CHANGELOG.md and changelog.d/; the two fragments this PR adds have to be rendered in the same commit range. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This was referenced Jun 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
test_output::test_vmaf_versionfailed the Intel LLVM and macOS Clang legs ofbuild.ymlon #1223 — a PR that does not touchtest_output.c, does not touch any version surface, and whose only meson change is a CUDA include path. The test is byte-identical on master. The failure is not #1223's.core/include/meson.buildderivesVMAF_VERSIONfromgit describe --tags --long --match 'v*.*.*' --always. With--always, git exits 0 even when no matching tag is reachable and prints a bare abbreviated object name, which meson substitutes intovcs_version.hverbatim.build.ymlchecks out at theactions/checkoutdefaultfetch-depth: 1, which fetches no tags — so every build on that workflow has been stamping a commit abbreviation where a version belongs, andvmaf --version, the JSON/XMLversionfield andvmaf_version()all reported it.That is silent until the abbreviation happens to contain no ASCII digit, which is exactly what
test_vmaf_versionasserts against. #1223's merge commit isabafdfcc3c8ef40c369b4bb776c14188729ceada→abafdfc. No digit. About one commit in a thousand — (6/16)^7 — so the defect sat in tree and then failed an unrelated PR.The fix
Dropping
--alwaysmakes git exit non-zero in precisely those cases, andmesonbuild/scripts/vcstagger.pysubstitutes thevcs_tagfallback on any exception from the subprocess. The fallback is now spelled out rather than left implicit, because it is the entire tagless path. When a tag is reachable the--longform still embeds the commit, so no provenance is lost.build.ymlmoves tofetch-depth: 0, matchinglibvmaf-build-matrix.yml, so CI exercises the tagged path rather than the fallback.Master is not exempt — it has been lucky
Master's
build.ymldoes run the Intel LLVM and macOS legs and they are green. That is luck, not coverage: all 20 most recent master commits abbreviate with a digit. The defect is latent on master and fires on whichever commit first abbreviates to all letters. PR merge commits are fresh objects that change whenever the PR or its base moves, so they simply roll the dice more often — which is why a PR surfaced it first.(An earlier revision of this description claimed the CI impact planner had skipped master's Intel LLVM legs. That was wrong — it conflated
build.ymlwithlibvmaf-build-matrix.yml. Master'sbuild.ymllegs ran and passed.)One real coverage gap, closed here
The Windows job — the third leg — runs an explicit whitelist that omitted
test_output. It now runs it; the test already carries aGetTempPathA/GetTempFileNameApath for that platform.While there: that Windows
forloop gained|| exit /b 1. GitHub runsshell: cmdas%ComSpec% /D /E:ON /V:OFF /S /C "CALL ...", so the step result was the errorlevel of the last executable alone — a failure in any earlier test was discarded outright./V:OFFrules out!ERRORLEVEL!, so||is the portable form.Type
fix— bug fixbuild/ci— tooling / infraChecklist
make format && make lintis green locally.meson test -C build./cross-backend-diffand the worst ULP is ≤ 2. — n/a, no numeric code touched..c/.cpp/.cu/.h/.hpp, it has the appropriate license header. — n/a, no new C/C++ files.!orBREAKING CHANGE:. — n/a, not breaking.docs/adr/_index_fragments/. — n/a, no ADR (bug fix, CLAUDE.md §12 r8).Bug-status hygiene (ADR-0165)
docs/state.mdupdated in this PR with a row.Netflix golden-data gate (ADR-0024)
assertAlmostEqual(...)score in the Netflix golden Python tests.Deep-dive deliverables (ADR-0108)
AGENTS.mdinvariant note —scripts/ci/AGENTS.mdgains acheck-vcs-version-not-bare-sha.shsection covering all three enforced properties and thefetch-depth: 0coupling.changelog.d/fixed/vcs-version-bare-sha.md,changelog.d/fixed/windows-ci-swallowed-test-failures.md.docs/rebase-notes.md,fix/vcs-version-bare-sha. Upstream carries the--alwaysform (verified againstupstream/master:libvmaf/include/meson.build), so this file conflicts on every sync; the new gate turns a careless "take theirs" into a build failure.Reproducer
Reproduce the exact CI condition — a depth-1, tagless fetch of #1223's merge commit:
Verify the built surface and the gate:
Verification performed
mesonbuild.scripts.vcstaggeron the failing commitabafdfc(fails) →3.2.1(passes)meson test --suite=fasttest_output--always, dropfallback, drop--match)--alwaysoutside the call)shellcheckon the new gatepre-commiton all touched filesKnown follow-ups
test_outputto the Windows list and making the loop fail-fast may surface pre-existing Windows failures in the other 14 tests that were being swallowed. That would be a genuine finding, not a regression from this PR.🤖 Generated with Claude Code