Skip to content

Update the floating release in place instead of recreating it - #7

Merged
excid3 merged 2 commits into
mainfrom
floating-release-in-place
Sep 9, 2026
Merged

excid3 merged 2 commits into
mainfrom
floating-release-in-place

Conversation

@excid3

@excid3 excid3 commented Sep 9, 2026 •

Copy link
Copy Markdown
Member

Problem

create-release deleted the floating release (e.g. 3.4.8) and its tag, then created a new draft. A draft has no tag, so the floating download URLs returned 404 from the delete until publish-release, about two minutes in a healthy run. If anything after the delete failed, the floating release stayed missing indefinitely. That is exactly what happened to every 3.x floating release in today's batch when the create call was rejected with a 403 (the token lacked the workflow scope needed because main had moved to a commit that changed a workflow file).

mise resolves versions that are not on the first page of releases (currently everything older than 3.4.0) through the floating tag, and cannot fall back to the pinned 3.4.8-N release on its own; a missing tarball means a source compile.

Change

  • create-release only creates the pinned revision draft (e.g. 3.4.8-4) and cleans up leftover drafts with that tag from earlier failed runs. The floating release is not touched.
  • upload-assets uploads tarballs and provenance to the revision draft only.
  • publish-release publishes the revision first, then re-points the floating release at it in place:
    • existing floating release: delete assets this build no longer produces (and temporary names left by an interrupted run), upload the new assets under *.incoming, then per asset rename the old one to *.previous, rename the new one into place, and delete the old one. Each download URL is missing for one API call at most, instead of for a whole re-upload. Notes, title, latest and prerelease flags are refreshed and the floating tag is force-moved to the build commit.
    • no floating release yet: create it as a draft with all assets, then publish it, so it never appears without assets.
    • stale floating drafts left by the old workflow are deleted.

A failure anywhere in the workflow leaves the previous floating build serving.

Notes

  • Publishing the revision before touching the floating release means the floating release never points at a build that does not exist, and clients that resolve revision releases (mise with MISE_LIST_ALL_VERSIONS=1, or a lockfile) see a rebuild as a new, complete, immutable release with no window at all.
  • The floating tag moves on every rebuild, which is the intended semantics of a floating tag; consumers key on the asset URLs.
  • README updated to describe the new ordering.

https://claude.ai/code/session_01KeNcsk8V24YRXGfD2HwDZY

The release workflow deleted the floating release (e.g. 3.4.8) and its tag
before creating a new draft, so the floating download URLs returned 404
from that point until publish. If anything after the delete failed, they
stayed 404 indefinitely; that is what happened to every 3.x floating
release today when the create call was rejected. Clients like mise and
asdf cannot fall back to the pinned revision on their own and compile
from source instead.

Only the pinned revision release is created as a draft and uploaded to
now. Once it is published, the floating release is re-pointed at that
build in place: assets are replaced with --clobber, stale assets from
targets no longer built are removed, the notes are refreshed, and the
floating tag is force-moved to the build commit. A missing floating
release is created published with its assets in one call. Leftover
drafts from failed runs are cleaned up before creating a revision draft.

Claude-Session: https://claude.ai/code/session_01KeNcsk8V24YRXGfD2HwDZY
gh release upload --clobber deletes the old asset and then uploads the
new one, so each floating download URL was missing for the length of a
multi-megabyte upload. Upload the new assets under a temporary name,
then rename the old one aside, rename the new one into place, and delete
the old one: each URL is now missing for a single API call at most.
Stale assets and leftover temporary names are cleaned up first, and a
brand-new floating release is created as a draft with its assets and
only then published, so it never appears without them.

Claude-Session: https://claude.ai/code/session_01KeNcsk8V24YRXGfD2HwDZY
@excid3
excid3 merged commit b50c8ee into main Sep 9, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant