unsloth/tests/studio/fixtures
Daniel Han c3de39652e
Source the update popup's release notes from the GitHub releases (#8352)
* Source the update popup's release notes from the GitHub releases

CHANGELOG.md had to be hand-edited before every release, and it was keyed by
the PyPI backend version while the announcement itself lives on a release
tagged with the Studio version. The two drifted: the file carried three-bullet
stubs while the release page carried the write-up.

The newest published release is the source now, so the popup follows each new
release with no file to edit and no rebuild. Only the announcement is shown:
the install instructions, the generated What's Changed list, New Contributors,
the Full Changelog line and the appended build provenance are stripped out,
wherever in the body they were written.

* Strip an install block introduced by a paragraph, not just by a heading

v0.1.471-beta writes the same sentence v0.1.43-beta puts in a `###` heading
with no hashes in front of it, so _is_upgrade never saw it and the popup kept
a stale version pin and both install commands. A paragraph has no level, so
the block it opens runs to the next heading that is not one of the platform
headings holding its commands. Run over every published release body, exactly
one output changes and the removed lines are exactly that install block.

Also raise the releases page to the endpoint maximum of 100, which costs the
same single request, and fix three assertions that could not fail: the draft
case used a tag the tag filter rejects first, so the draft filter had no
coverage; no published body carries a provenance section, so asserting its
absence proved nothing; and "refresh" appears throughout the hook, so the
retry path could be deleted with the test still green.

The comment justifying the removed desktop fallback was wrong about what
latest.json's `notes` holds. It is the static download blurb the release
workflow writes, the same text every release, not this release's body.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Bound the rate-limit deadline, not just the first wait on it

The 15 minute cap was applied to the returned TTL while the raw reset epoch
went into _rate_limited_until, so the fetch after that TTL expired answered
from the uncapped deadline and blocked release notes, Retry included, for the
whole server-supplied interval.

GitHub says not to request again before X-RateLimit-Reset, so the reset still
wins over the back-off rather than being cut to 15 minutes, which would retry
into the limit. It is now held to the hour that the unauthenticated window
actually is, so a skewed or proxied header cannot park the popup.

* Record a deadline for every refusal, not just the primary rate limit

A secondary rate limit answers 403 or 429 without X-RateLimit-Remaining: 0, so
that branch returned a 15 minute TTL and left _rate_limited_until unset. Retry
saw no lockout, dropped the cached failure and requested straight back into the
limit, which is what GitHub warns against.

Every refusal now records a bounded deadline, in the order GitHub documents:
Retry-After, which is how a secondary limit states its wait, then the primary
limit's reset, then the plain back-off when the response says neither.

* Size the releases page against the read cap, and split platforms on a slash

A release entry carries its whole body and the newest ones run about 40 KiB,
so the endpoint's maximum of 100 puts the response near 4 MiB against a 2 MiB
cap. The fetch would then fail outright with the release it wanted sitting at
the top of the page it just threw away. Back to 30, which is about 1.2 MiB at
that rate, with the arithmetic recorded in a test that fails if the page grows
past what the cap allows.

_is_platform replaced a slash with a comma but not the spaces around it, so
neither "macOS / Linux / WSL" nor "macOS/Linux/WSL" matched and an install
block written that way would have kept its commands. The separators are now
read as one thing.

* Tighten the comments this change added

Comments only, no code. Mostly the test docstrings, which had grown into
several lines of bug narrative each and now lead with the rule and keep at
most a clause of what broke, and the blocks in release_notes.py that only
restated the line below them.

The reasons bought during review are kept, shorter: why the releases page is
30 and not the endpoint maximum, why the rate-limit deadline is bounded and
why GitHub's reset beats the back-off, why releases are ordered by
published_at, and why the install block is excised where it stands.

* Refuse a desktop tag that goes backwards for PR #8352

Both updater paths compare SemVer, so v0.1.60-beta published after
v0.1.527-beta reads as older and no client on the 5xx series is ever offered
it. Desktop builds have only shipped at four tags, v0.1.526-beta through
v0.1.61-beta, so this is the first time the tag numbering has stranded
anyone, and it strands everyone installed before Aug 10.

Check the new tag against the version in the published latest.json, which is
the file a running build actually reads, and refuse a release that would
strand its own users. Warns rather than fails when the manifest is
unreachable, so a network blip cannot block a release.

* Compare full SemVer in the tag guard, and drop a bare platform install block

The guard compared only the numeric triple, so v0.1.528 or v0.1.528-rc after
v0.1.528-beta read as equal and were refused, though both are newer and the
updater treats them that way. Compare full SemVer precedence instead.

Separately, a platform heading only ended an install block that an 'Updating'
heading or paragraph had already opened, so a release heading its commands
with a bare 'MacOS, Linux, WSL:' kept them. v0.1.0-beta and v0.1.41-beta do
that, and they are the only two of the 24 published bodies this changes; all
seven platform headings in that corpus head an install block.

* Resolve the published desktop version from the newest Studio release

The guard read /releases/latest/download/latest.json, but this repo also
publishes llama.cpp prebuilts as ordinary releases: 25 of them, non-draft and
non-prerelease, so any new one becomes GitHub's latest release. Those carry no
manifest, so the read would 404 and the guard would skip itself silently,
which is the same hazard release_notes.py already documents and avoids.

Take the newest non-draft Studio tag that actually ships a latest.json, and
authenticate with the workflow token rather than spending a shared quota.

* Tighten the comments the last two rounds added

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2026-08-11 00:28:01 -07:00
..
ansi-smoke-screenshots [Fix] Unsloth Studio: Strip ANSI escape codes from Studio tool output panes (#7976) 2026-08-08 15:04:42 +02:00
release_bodies Source the update popup's release notes from the GitHub releases (#8352) 2026-08-11 00:28:01 -07:00