fix(CI): Publish release binaries via draft releases - #19
Merged
almostintuitive merged 1 commit intoAug 27, 2026
Merged
Conversation
Releases have shipped without binaries since v1.0.4, so `install.sh` has been installing a 404 body as the CLI. Three compounding causes: 1. `bump.yml` pushes the version tag with the default `GITHUB_TOKEN`. GitHub does not trigger workflows from `GITHUB_TOKEN` events, so `ci.yml`'s tag-gated `release` job never ran — not once, for any tag. 2. Releases were then published by hand, which fired `release-assets.yml` on `release: published`. This repo has immutable releases enabled, so uploading assets after publication is rejected: "Cannot upload asset ... to an immutable release." 3. `install.sh` downloaded with `curl -L` (no `-f`), so curl exited 0 on the resulting 404 and wrote the response body to disk. The script then chmod +x'd a 9-byte file containing "Not Found" and moved it to /usr/local/bin/aperiodic. `bump.yml` now owns the whole release: it tags, builds all six targets, attaches them to a *draft* release (allowed under immutability), verifies the asset count, and only then flips the release to published. The `release` job in `ci.yml` is removed. It could never fire from a `GITHUB_TOKEN` tag push, and on a manual tag push it would now race `bump.yml` and fail on immutability anyway. `install.sh` now uses `curl -fL`, rejects empty or HTML/error responses, and cleans up its temp file on any exit path. Also wires up PagerDuty on release failure, matching the notify-failure pattern from dream-faster/unravel-router#517. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
almostintuitive
deleted the
fix/release-binaries-and-install-verification
branch
August 27, 2026 10:41
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
curl -fsSL .../install.sh | bashinstalls a 9-byte text file containingNot Foundas/usr/local/bin/aperiodic:Every release since v1.0.4 has shipped with zero binaries, so
releases/latest/download/aperiodic-darwin-arm64404s:Root cause
Three failures compounding:
ci.yml's release job has never run.bump.ymlpushes the tag with the defaultGITHUB_TOKEN, and GitHub deliberately does not trigger workflows fromGITHUB_TOKENevents. Everyci.ymlrun in this repo's history isevent: pushonmainorpull_request— not one tag push.Immutable releases reject post-publish uploads. With no automated release, tags were published by hand, firing
release-assets.ymlonrelease: published. That's too late — run 32262281202 built all six binaries and then died on:fix(CI): stop re-uploading release assets to already-published releases #18 responded by deleting the upload logic rather than moving it before publication, so nothing has uploaded binaries since.
install.shfailed silently. It usedcurl -Lwithout-f, so curl exits0on a 404 and writes the error body to disk. The script thenchmod +x'd it and moved it into/usr/local/bin.Changes
bump.ymlnow owns the entire release. Tag → build all six targets → attach them to a draft release (permitted under immutability) → verify the asset count → publish. Keeping it in one workflow sidesteps theGITHUB_TOKENtrigger problem entirely, with no PAT required.The asset-count check means a partial upload fails the run instead of quietly publishing an empty release — the exact failure mode that went unnoticed for two releases.
ci.yml'sreleasejob is removed. It could never fire from aGITHUB_TOKENtag push, and on a manual tag push it would now racebump.ymland fail on immutability regardless.install.shfails loudly.curl -fL, plus explicit rejection of empty and HTML/error-page responses, and temp-file cleanup on every exit path.INSTALL_DIRis now overridable, which makes the happy path testable without touching the system.PagerDuty
Adds a
notify-failurejob, onubuntu-latestto match this repo's runners. A silent release failure is precisely what this bug was.Verification
install.shagainst the currently-brokenlatest— now exits 1 and leaves the system untouched:Happy path against
v1.0.3, which still has assets:actionlintclean across all workflows.go build ./...passes;go test ./...gives 33 passed / 5 failed, all five being pre-existing integration tests gated onAPERIODIC_API_KEY, which CI supplies.Follow-ups (not in this PR)
bumprun produces the first working release; until theninstall.shcorrectly refuses rather than installing garbage.release-assets.yml(the README link updater) triggers onrelease: published. Sincebump.ymlpublishes viaGITHUB_TOKEN, it won't fire either — same root cause as feature(Project): Add Go CLI downloader with tests and GitHub Actions release workflow #1, worth folding intobump.ymlseparately.🤖 Generated with Claude Code