Skip to content

ci: a release goes public only once every artifact is up - #387

Merged
sepehr-safari merged 1 commit into
mainfrom
the-release-lifts-only-when-its-files-are-up
Sep 25, 2026
Merged

sepehr-safari merged 1 commit into
mainfrom
the-release-lifts-only-when-its-files-are-up

Conversation

@sepehr-safari

Copy link
Copy Markdown
Contributor

Part of #362. Notary has the same two claims word for word and gets the same change in its own pull request, which closes the issue.

  • publish runs scripts/check-release-assets.sh before lifting the draft. Each expected file must be listed by name, have state == uploaded and a non-zero size; otherwise the release stays a draft and the step names what is missing. It fails closed: if gh errors, the check sees no input and refuses.
  • The macOS job's existing-release branch re-drafts the release before uploading, so neither branch exposes a partial set.
  • The lift goes through gh api with draft=false (typed boolean) and make_latest=legacy. A plain --draft=false counts as a new publish and defaults to making that release Latest, so re-running an older tag would have moved /releases/latest (both installers and the in-app update check) back a version. legacy picks Latest by version and date.

Verified:

  • the script against real releases: v0.23.0 passes with all 5 files; v0.18.0 is refused with its 4 missing Linux files named
  • the self-test (missing file, unfinished upload, empty file, another version's files, arch list vs release.yml's matrix), each negative case asserting which file was reported; three deliberate breaks of the check were each caught for the right reason, and one of those probes exposed a fixture that had been passing for the wrong reason, now fixed
  • runs under macOS /bin/bash 3.2 and shellcheck clean
  • the PATCH body, sent to a release id that does not exist (404, nothing changed): {"draft": false, "make_latest": "legacy"}

Not verifiable before a real release: the check and the lift against a draft. Both fail closed (the release stays a draft), and the next release is the first run.

The publish job lifted the draft as soon as the macOS and Linux jobs exited 0, and its comment claimed that meant every artifact was up. It now runs scripts/check-release-assets.sh first: every file a release of that tag should carry has to be listed by name, finished uploading and not empty, or the release stays a draft and the job says which file is missing.

The macOS job's other branch, for a release that already exists, uploaded straight into it while it was public, so the page offered a partial set until the Linux jobs finished. It now turns the release back into a draft before uploading, so both branches keep it hidden until the check passes. Publishing a draft defaults to making it Latest, which would let a re-run of an older tag take Latest from a newer one, so the lift goes through the API with make_latest=legacy: a new release still becomes Latest, a re-published old one does not.

The check is a script so it can be run by hand against any release: against v0.23.0 it passes with all five files, against v0.18.0 it names the four Linux files that release never had. CI runs its self-test, which covers a missing file, an unfinished upload, an empty file and another version's files, each asserting which file was reported, and compares its architectures with release.yml's matrix.
@sepehr-safari
sepehr-safari merged commit 0e835bc into main Sep 25, 2026
6 checks passed
@sepehr-safari
sepehr-safari deleted the the-release-lifts-only-when-its-files-are-up branch September 25, 2026 07:30
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