Fix stale quarto-cli release being accepted by release-info - #2170
Open
cderv wants to merge 4 commits into
Open
Conversation
zizmor flags actions/setup-node as a high-severity cache-poisoning risk because it enables caching by default, and audit-workflows.yml runs zizmor over .github on every PR. The repo audits clean without this file, so the step would have introduced the only finding in the tree. The pin bought very little: these tests use nothing beyond node:assert and other built-in modules, so the runner image Node is sufficient.
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.
On 2026-08-17 the GitHub Releases API served inconsistent paginated results to
the
Update Downloadscron job, and the resolved latest prerelease bouncedacross four stale versions over about 100 minutes:
Each bad value was committed to
main, synced toprerelease, and published,so the downloads page and the
/download/prerelease/*redirects advertisedassets from an old release. The 14:43 run also opened #2146, regenerating 63
reference pages against a ten-month-old v1.9.10; it was closed unmerged.
Root Cause
getPrerelease()in.github/workflows/actions/release-info/index.jsreturnsthe first release flagged
prereleasefrom page 1 oflistReleases, relyingentirely on the API returning newest-first. The only downstream validation is
that the release has assets, which a ten-month-old release still has. All four
bad values are genuine old quarto-cli releases, so nothing in the payload marks
the response as wrong.
Fix
A glitched page cannot be told apart from a good one by inspection, so the
check compares against state the API does not control: the version already
committed in the JSON file the run would overwrite. A resolved version older
than the committed one throws,
core.setFailedfails the step, andgit-auto-commit-actionnever runs, so nothing is committed, synced,published, or handed to the reference-page workflow. Each check sits before
processRelease(), so a rejected run downloads no assets and writes nothing.Comparison is numeric per segment, since both
1.9.10and1.10.2sort wrongas strings.
Comparing against the latest stable release was rejected instead: the stable
and prerelease lines cross at every release cycle. Today v1.10.18 is stable
while v1.11.1 is the prerelease, and once the 1.11 line goes stable the latest
stable will exceed the latest prerelease until 1.12.0 ships, so valid data
would be rejected.
The paging loop was also bounded. It was
while(true)with no page cap and noempty-page exit, so a repository with no prerelease at all would loop until the
job timed out.
Test Plan
npm testfrom.github/workflows/actions/release-info/passes both suitesEach version the API served on 08-17 is rejected against the committed baseline:
The current correct version is still accepted, so ordinary runs are unaffected
zizmor .github/reports no findings, soaudit-workflows.ymlstays greenAfter merge, the next scheduled
Update Downloadsrun completes normallyThe original failure cannot be reproduced on demand, since it depends on the
API returning inconsistent pages. The equivalent end-to-end check inverts it:
raise the
versionfield in a local copy ofdocs/download/_prerelease.jsonabove the real latest prerelease, run the action against the live API, and
confirm the step fails with the guard message and writes nothing. Driving that
through a
workflow_dispatchofUpdate Downloadsneeds care, because thatworkflow commits and pushes once the action succeeds.
Fixes quarto-dev/quarto-cli#14823