ReviewOS

also looking at this

stacks/uplink

fix(release): one publisher, and a red run when the DMG is missing

#58
Merged glennmichael123 wants to merge fix/one-release-publisher into main
3 files +93 -36
9 days ago

Closes #32. Per your call: the Mac stays the publisher.

What was broken

Two things published a release for the same tag, and only one of them could attach the app.

release.yml ran stacksjs/action-releaser on ubuntu-latest for any v* tag and created a release with no assets. The DMG came from buddy uplink:release, run by hand on a Mac. Nothing connected them and nothing checked the result.

So a tag that arrived without the manual step still produced the release GitHub calls latest. Every download link in the project resolves through releases/latest/download/Uplink.dmg — the README button and the three on the homepage — and all four would 404, with nothing failing anywhere to say so.

What it does now

The workflow publishes nothing. It polls the release for the pushed tag and fails red if Uplink.dmg is not attached.

Polling rather than a single check is the point: gh release create makes the tag and then uploads about 35 MB, so the run starts while a correctly-working publisher is still mid-upload. Checking once would fail the good case.

I extracted the gate's shell body and ran it against a stubbed gh, all four branches:

the release for the tagresult
published, has Uplink.dmgexit 0, "releases/latest/download/Uplink.dmg resolves"
a draftexit 0, nothing points at it yet
published, no DMGexit 1 with instructions
does not exist at allexit 1 with instructions

A failed run tells the maintainer what to do about the tag that already exists, which is the awkward part of failing after the fact:

gh release upload v0.1.5 storage/framework/desktop-dmg/Uplink.dmg
# or
gh release delete v0.1.5 --cleanup-tag

Two things that came with it

Exactly one writer for the release body. The workflow's generated changelog and the command's fixed --notes string described the same tag, so which one a reader got came down to which finished last. The command writes it now, from the changelog it generates, and release.yml has a comment saying it publishes nothing.

CHANGELOG.md is generated and committed with the release. Carrying the previous entries over is done by hand, because buddy changelog rewrites the file with the commits since the last tag and nothing else — running it as-is would leave a changelog that remembers exactly one release. I simulated two consecutive releases to check the stacking and the spacing.

.github/CONTRIBUTING.md said buddy release "triggers the Release Action". That is now actively wrong, so that line names both commands and what each does. The rest of that file is still the framework scaffold's, which is #39.

Verification

  • the gate's four branches, shown above
  • 163 unit tests pass, lint and typecheck clean
  • the changelog stacking, simulated across two releases

Not done here

Moving the signing into CI. That needs your Developer ID certificate and notarytool profile as GitHub secrets, and it is a bigger change than removing the landmine. This leaves that open rather than deciding it.

🤖 Generated with Claude Code

3 changed files on the files tab, with 0 review threads.

Sign in to comment on this pull request.