release: retry the attestation download, and say why when it fails - #1317
Merged
Conversation
justinjoy
force-pushed
the
fix/750-signing-and-publication
branch
from
September 2, 2026 12:53
388f3d2 to
6fef16f
Compare
justinjoy
force-pushed
the
fix/750-signing-and-publication
branch
from
September 2, 2026 13:07
6fef16f to
5492454
Compare
justinjoy
force-pushed
the
fix/1290-attestation-retry
branch
from
September 3, 2026 03:25
7edcfd0 to
5109979
Compare
release-tag.yml attested the source archive and downloaded the provenance bundle in the next step, back to back, with no delay and no retry. Those are separate API operations, so if the attestations API is not read-your-writes consistent the download returns nothing -- and the job died on a bare `test -n` with no indication of why, after every verification job had already passed, on a tag that cannot be rebuilt. The download now retries a bounded number of times and, on final failure, names replication lag as the usual cause, points at the repository's attestations page, says that re-running this job alone is enough, and quotes what gh actually said. It lives in a script rather than inline in the workflow so it can be exercised without cutting a release. That is the whole point: the path it guards runs for the first time on a real one. Two things the retry made necessary that the inline version did not need. Swallowing gh's status so a transient failure does not abort before the loop has had its say means success is decided by "a bundle exists" rather than "this download produced one" -- so a bundle left by an earlier run would be renamed and published as this release's provenance after a single failed call. The inline form could not do that, because gh's exit aborted the step. The directory is now cleared before the loop. And a zero or non-numeric attempt count would run the loop zero times, never call gh, and still print the full diagnosis; it is rejected instead. Refs #1290.
justinjoy
force-pushed
the
fix/1290-attestation-retry
branch
from
September 3, 2026 09:24
5109979 to
ac717e0
Compare
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.
Refs #1290. Stacked on #1289, which owns
release-tag.yml.The defect
The workflow attested the archive and downloaded the bundle in the next step, back to back, with no delay and no retry:
Those are separate API operations. Without read-your-writes consistency the download returns nothing and the job dies on a bare
test -n— after every verification job has passed, on a tag that cannot be rebuilt.Extracted, not just patched
The retry lives in
scripts/release/download-attestation.shso it can be exercised without cutting a release. That is the point rather than a side benefit: this is code whose first real execution is a release. Same reasoning #1293 established forgenerate-sbom.sh.The failure path now diagnoses:
Two problems the retry itself created
Both found in review, both regressions against the inline original:
gh's status (needed so a transient failure doesn't abort before the loop runs) means success is decided by "a bundle exists", not "this download produced one". The inline form couldn't do this —gh's exit aborted the stepgh, and still printed the full replication-lag diagnosisBoth guarded and pinned. Currently unreachable in CI (fresh VM per job), but the guard is now the code rather than runner ephemerality.
Also fixed in review: an assertion that gave false credit for the diagnosis text — the needle
attestationswas satisfied by the stub's own stderr (no attestations found for subject), so deleting the URL and re-run guidance left the suite green. It now matches text only the script can produce.Validation
abi. Confirmed by the reviewer to actually run inrelease-tag.yml's ABI job andci-pr.yml— needs only bash and a stubbedgh, nob3sum. (I have shipped two tests this session that skipped in 100% of CI; this one was checked.)cpinstead ofmv, dropping theghquote, leaving the log behindpipefailearly-exit class this repo has hit seven times is structurally absentOne redirection-order bug of mine was caught by the suite itself:
2>/dev/null >&2sends stdout to/dev/null, swallowing theghoutput that line exists to print.