Repository navigation
fix(release): clear the 1.0.0-rc.1 merge and publication path - #1570
Merged
Merged
Conversation
The 1.0.0-rc.1 cut moves the fork's whole fragment history, 2,035 sources, into docs/changelog-archive/1.0.0-rc.1.md (1.86 MB), and the 1 MB check-added-large-files hook refused the cut commit. After the cut the archive is the only remaining copy of that text, so it cannot be generated at build time the way ADR-1115 handled the BRISQUE header. check-added-large-files now excludes ^docs/changelog-archive/[^/]+\.md$ only (ADR-1345). Rollover test T18 checks the archive path the rollover writes against that pattern and keeps neighbouring paths guarded; it fails against the previous config.
core/test/test_metal_ms_ssim_options_contract.py read changelog.d/added/T-GAP-METAL-MS-SSIM-DB-CHROMA-OPTIONS-2026-09-07.md in setUpClass. The 1.0.0-rc.1 cut deletes every consumed fragment, so the fast meson suite would fail on the release PR and turn Ubuntu gcc+DNN, a check the release PR must report, red. The 351x351 boundary stays pinned by the Metal AGENTS.md, the MS-SSIM metric doc and Research-2110. A sweep found no other code that reads fragment contents. T18 now pins the exact large-file exclusion pattern, because sample paths alone missed five widenings (lost anchors, an unescaped dot, an added alternative). ADR-1345 now cites ADR-1233 for the archive shape, says the receipt hashes the rendered body the archive holds, and describes ADR-1115 accurately.
…afts release-please.yml pauses both release-please phases while one unpublished release draft waits at the human publication gate (ADR-1127). The step that finds that draft selected tags with a plain vX.Y.Z jq regex, so the v1.0.0-rc.1 draft that the #1213 merge creates was invisible to it. With the draft invisible and bootstrap-sha removed by the cut, the next master push would re-run release-PR generation against an untagged release: it either errors or opens a bogus release PR, instead of waiting for publication. The filter now accepts the same narrow shape that scripts/release/verify-release-version.sh accepts: vX.Y.Z, or vX.Y.Z-rc.N where N has no leading zero (ADR-1201). The step name and the error text no longer say "ordinary-SemVer". jq also writes to a file now instead of feeding `mapfile < <(...)`. A jq failure inside process substitution was swallowed, and the resulting empty list read as "no draft", which is the same fail-open. scripts/release/tests/test-release-please-draft-gate.sh extracts the step and its jq filter from the workflow and checks four things. The filter is run against sample release lists. The filter must accept exactly the tags verify-release-version.sh accepts, across 30 tag shapes. The full step runs under the runner's default `bash -e` with a stub gh, and an unreadable or malformed release list must fail closed. Both release-please invocations must still be gated on the draft output. The Release Script Contract job runs it. Against the previous workflow it reports 18 failures; with this change all 64 checks pass.
The draft-detection step fails closed on a jq error only because the runner default shell runs with -e. State shell: bash explicitly so that guarantee does not rest on the default. .github/AGENTS.md still described the retired 3.2.1 cut; it now names the 1.0.0-rc.1 cut and the Release-As footer later candidates use.
verify-native-release-artifacts.sh gates both the build-artifacts and verify-native-artifacts jobs of supply-chain.yml, and it could not pass for any release this fork can publish. First, its VERSION argument accepted only a plain MAJOR.MINOR.PATCH, so the 1.0.0-rc.1 that validate-release derives from the v1.0.0-rc.1 tag exited 64 before anything was checked. ADR-1201 relaxed six guards for release candidates and missed this one. Second, it compared `vmaf --version` byte-for-byte with that bare version. The CLI prints VMAF_VERSION, which core/include/meson.build takes from `git describe --tags --long --match 'v*.*.*'`, and the release job checks out the tag itself, so describe succeeds and the binary reports `v<version>-0-g<hex>`. The Meson project version is only the fallback for a checkout with no reachable tag. A real CPU-only build from a checkout that mirrors actions/checkout v7.0.1 (unqualified tag ref, depth 1, no tags) printed `v1.0.0-rc.1-0-gd0f0e7e` for tag v1.0.0-rc.1 and `v1.0.0-0-g8820048` for tag v1.0.0. The unmodified verifier rejected both, so the final 1.0.0 would have failed at the same step. The verifier now takes exactly the ADR-1201 shape (X.Y.Z or X.Y.Z-rc.N, no leading zeros) and accepts exactly two reported strings: describe exactly on the tag (distance 0, 7 to 64 lowercase hex digits) or the bare fallback, which verify-release-version.sh already pins to the tag through the coordinated core/meson.build marker. It still matches the whole string, never a prefix. A non-zero distance (a commit after the tag), a -dirty or other suffix, rc.10 offered for rc.1 and extra output all still fail. `vmaf --version` output is unchanged. The existing release-script-contract test now builds one fixture CLI per reported string (printed on stderr, like cli_parse.cpp) and covers final and candidate versions in both forms, rc.0, rc.10 and full-hash boundaries, 13 malformed VERSION arguments, and 25 reported strings that must be rejected. Against the old verifier 28 of the 56 cases fail. With only the argument check relaxed, the 6 describe-form acceptances still fail.
A release candidate could not publish vmaf-mcp. supply-chain.yml built its wheel and sdist globs from the SemVer release version (1.0.0-rc.1), but hatchling names the files after the PEP 440 normalized version: vmaf_mcp-1.0.0rc1-py3-none-any.whl and vmaf_mcp-1.0.0rc1.tar.gz. For v1.0.0-rc.1 the mcp-build hash step therefore found no wheel and failed, which skipped the SBOM, signing, PyPI publication and release attachment jobs behind it. Final X.Y.Z releases were unaffected because both spellings are identical there. validate-release now derives a pep440_version output once, through the new scripts/release/pep440-version.sh. The converter is dependency-free and exact for the two shapes ADR-1201 accepts (X.Y.Z unchanged, X.Y.Z-rc.N to X.Y.ZrcN); every other input exits 64 with no output. The version-bound wheel and sdist globs in sbom, mcp-build and both mcp-publish-pypi steps, and the PyPI JSON release URL, now use it. The SBOM identity checks deliberately keep the SemVer version. Hatchling 1.32.4 writes the pyproject spelling into METADATA, and Syft 1.51.1 copies it verbatim into the vmaf-mcp versionInfo and purl, so switching them would break the release instead of fixing it. The sdist pattern contains no wildcard, so nullglob always left one literal entry in the array and the count check could never reject a wrong sdist name. Each of the four version-bound checks now also requires that the sdist exists. scripts/release/tests/test-pep440-version.sh covers the converter's accepted, rejected and boundary cases, the workflow wiring, and resolves every version-bound glob against hatchling-shaped filenames with decoys. It runs in the Release Script Contract job and fails against the previous workflow.
The pre-push PR-body hook mirrors CI's Deliverables Checklist (ADR-0108) but lacked the ADR-1151 release-PR exemption that CI applies through scripts/ci/release-pr-exempt.sh. Pushing the changelog cut from the local release-please--branches--master--components--vmafx branch therefore failed with six "ADR-0108 missing deliverable" errors against #1213's 216-character bot body, a gate CI itself skips for that PR. The hook now asks gh for the PR's author and headRefName and calls the shared predicate instead of re-implementing it. gh marshals every non-User author as {"is_bot": true, "login": "app/<x>"} (cli/cli Author.MarshalJSON), whereas CI passes the event payload's "<x>[bot]" / "Bot", so the hook maps that shape to the payload shape; a human keeps its login with type "User", and any other shape (deleted author, missing field) maps to an empty identity that never exempts. The public-page fallback carries no author and never exempts, and a branch without the predicate validates as before. Tests cover the bot release PR (github-actions and a release-bot App), a human PR on the same head ref, non-bot lookalike authors, a bot PR on an ordinary branch or with no head ref, a missing predicate, and the public-page fallback. The test hook now also re-runs when the predicate changes.
- pre-push PR-body hook: gh reads a numeric branch name as a PR number, so a local branch named 1213 found the bot release PR and was exempted. The exemption now also requires the PR's head ref to be the branch being pushed. The sentinel guide no longer claims the public-page fallback is always validated; it is never exempted. - release-please draft gate: the step sets -euo pipefail itself, and its test runs it under plain bash, so failing closed never depends on the runner's default shell. - verify-native-release-artifacts.sh and pep440-version.sh run with LC_ALL=C, because [0-9] matches non-ASCII digits in some UTF-8 locales. - test-verify-release-version.sh creates its fixture tag unsigned, so it passes on hosts with tag.gpgsign=true. - scripts/release/AGENTS.md states the describe-form version accurately.
Adds the docs/state.md rows, changelog fragments and rebase notes for the release-path defects found by the rc.1 dry-run cut, and documents in the release guide how a candidate moves through the draft pause, version strings, Python distribution names and the pre-push hook.
This was referenced Sep 28, 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
This PR fixes every defect that a dry-run cut of release PR #1213 and a multi-agent gate review found on the path to merging and publishing 1.0.0-rc.1. Each fix was reviewed independently before integration.
1. The cut commit was refused (ADR-1345)
The 1.0.0-rc.1 changelog cut could not be committed. The rollover moves the fork's whole fragment history, 2,035 sources, into
docs/changelog-archive/1.0.0-rc.1.md. At 1.86 MB that exceeds the 1,024 KBcheck-added-large-fileslimit, so the hook refused the cut commit on release PR #1213.This PR exempts only
^docs/changelog-archive/[^/]+\.md$from that hook (ADR-1345). Every other path, including nested or non-Markdown files in that directory, keeps the limit.ADR-1115 kept the limit for a 2.1 MB generated header by generating it at build time. That route doesn't exist here: after the cut, the archive is the only remaining copy of the consumed fragments' text, and the rollover receipt pins its SHA-256.
excludepattern in.pre-commit-config.yaml, and asserts that neighbouring paths stay guarded. It fails against master's config.scripts/release/AGENTS.md,docs/state.md, the rebase notes and a changelog fragment record the exemption.Why the earlier dry run missed this:
pre-commit run --from-ref/--to-refdoesn't treat committed files as newly added. This time the cut was dry-run through a real hookedgit commiton #1213's head with this change applied, and it passes (2,036 sources).2. Further release-path fixes (found by the gate review)
core/test/test_metal_ms_ssim_options_contract.pyreadchangelog.d/added/T-GAP-METAL-MS-SSIM-DB-CHROMA-OPTIONS-2026-09-07.md, so thefastmeson suite would fail on the release PR and turn Ubuntu gcc+DNN (a must-report release check) red. A repository sweep found no other code reading fragment contents.-rc.Ndrafts. Its regex was^vX.Y.Z$, so thev1.0.0-rc.1draft would not pause release-please. Withbootstrap-shagone after the cut, the next master push would have re-run PR generation against an untagged release. The check now matches the verifier's shape, sets-euo pipefailitself and fails closed on an unreadable release list. A new test extracts the step from the workflow and proves parity.1.0.0-rc.1, and it comparedvmaf --versionwith the bare version although a build at the tag reportsv1.0.0-rc.1-0-g<hex>(reproduced on real builds; the final 1.0.0 would fail too). It now accepts exactly the bare version or the distance-0 describe form.vmaf-mcpdistributions were matched by their SemVer spelling. Hatchling names them1.0.0rc1, somcp-buildfailed and SBOM, signing, PyPI and release attachment were skipped. A dependency-freescripts/release/pep440-version.shnow feeds the four globs.scripts/ci/release-pr-exempt.sh, maps gh'sapp/<name>author to<name>[bot], and exempts only when the PR's head ref is the pushed branch.LC_ALL=C, andtest-verify-release-version.shno longer fails on hosts withtag.gpgsign=true.Type
Checklist
Bug-status hygiene
docs/state.mdupdated in this PR: six Recently-closed rows (T-RELEASE-CUT-ARCHIVE-LARGE-FILE,T-RELEASE-CUT-TEST-READS-FRAGMENT,T-RELEASE-RC-DRAFT-GATE,T-RELEASE-NATIVE-VERIFY-RC-DESCRIBE,T-RELEASE-MCP-PEP440-DIST-NAMES,T-RELEASE-PREPUSH-RELEASE-PR-EXEMPTION, all 2026-09-27).Netflix golden-data gate
assertAlmostEqual(...)value was modified.Deep-dive deliverables
## Alternatives considered: exempt the directory's Markdown files, split the archive, or raise the global limit.AGENTS.mdinvariant note —scripts/release/AGENTS.md(archive exclusion, version shapes, describe form),scripts/ci/AGENTS.md(pre-push exemption),.github/AGENTS.md(draft pause covers RC drafts).changelog.d/fixed/release-cut-archive-large-file.md,release-please-rc-draft-gate.md,native-release-verify-rc-describe.md,mcp-pep440-dist-names.md,pre-push-release-pr-exemption.md.docs/rebase-notes.mdentries "ADR-1345 — changelog archive large-file exemption" and "1.0.0-rc.1 release-path fixes" (2026-09-27).Reproducer