fix(release): retry the Modrinth read-back instead of reding a released tag - #164
Conversation
Acceptance evidence - fresh tag, first attempt, no rerunsThe merge cut 0.15.13 through the normal chain (
Step table of the tag run (
No The retry path itself, replayed against the released workflowSince this release did not race, the retry path is shown by executing the Three read-backs (two retried, the third confirmed), one create, exit 0. The inverse cases are pinned by the new tests: 404 forever fails after exactly the declared bound, a 403 fails on the first read, and a digest mismatch fails on the first read without ever being retried or reported as published. |
Problem
release.yml's "Publish to Modrinth" step is fail-closed by design: after creating each platform version it reads that version back and asserts sha1+sha512 against the jar this run built. On the 0.15.12 release the read-back raced the create and returned HTTP 404 for a version Modrinth had in fact stored, so the step red-ed a tag that had published correctly:OK: 0.15.12+velocity published as Jp5zP2v3; connect-velocity.jar matches on sha1 and sha512.then::error::Could not read version 0.15.12+spigot back from Modrinth (HTTP 404)- bungee never attemptedModrinth already carries 0.15.12+velocity/...+spigot(so spigot was stored), then::error::Could not read version 0.15.12+bungee back from Modrinth (HTTP 404)already carries-> stepsuccessOnly the read-back raced; the bytes were stored every time. Two manual job reruns were needed to get a green release run. 0.15.9/0.15.10/0.15.11 had this step green, so it is a latency flake, not a permission or contract problem.
What changed
.github/workflows/release.yml, "Publish to Modrinth" step only:local read_attempts=4,local read_retry_seconds=8. Only HTTP 404 ("not visible yet") is retryable; after the attempts are spent the step fails exactly as before.createis not retried. A duplicate version number (400/409 with analready exists/duplicateerror) is now treated as inventory: resolve the existing version id from the version list and let the same read-back confirm the bytes. Anything else still fails immediately.TDD - RED then GREEN
core/.../release/ReleaseModrinthPublishTestnow executes the step's ownpublish_platformshell against a stubbed Modrinth API (api()andsleep()overridden) instead of only grepping the YAML, so the retry decision is run, not described. Counts of create/read-back/inventory calls are asserted, which is what pins "only the read-back is retried".RED - test file only, workflow untouched, at
a55e14b2:GREEN -
./gradlew build(the CI command), JDK 21 on the Hermes pod:.agents/skills/release/SKILL.mddocuments the bounded read-back retry, the retryable answer and the duplicate-create handling.Acceptance
The fix is on a fresh tag via the normal release chain (
fix:prefix -> release-please ->release.ymldispatched on the tag), where the read-back races are the thing being tested. Evidence (run URL + the step's log lines) will be posted on this PR once the release run finishes.