Publish the full release binary matrix to GitHub releases, checksummed and CI-built from the same tags #454

Closed
opened 2026-07-01 22:12:16 +00:00 by coilyco-ops · 5 comments
Member

Why

Decision direction from Kai (2026-07-01, post-pressure-test-sweep): publish the full release binary matrix (darwin + linux × amd64 + arm64) to GitHub releases as well.

This buys more than mirror parity: it serves GitHub arrivals (#414), fixes the confusing Linux-only release page (#442 checkbox 2), and removes a real availability coupling — today's brew formula builds from source with GOPROXY=direct against forgejo.coilysiren.me, so every install anywhere depends on that instance being up and a local go toolchain. Published binaries let the formula (or a plain curl-install) consume artifacts instead.

Deliverable

  • The full matrix published to GitHub releases, CI-built from the same tags as the Forgejo releases so the two release pages cannot drift.
  • SHA256SUMS (ideally provenance/attestation) published alongside — without it, "which binaries are canonical, the Forgejo ones or the GitHub ones?" becomes a fair drive-by-critic dunk and worsens the canonical-vs-mirror confusion tracked in #438.
  • One sentence in the README or release-notes template saying what each asset is for and who installs which way.
  • Optional follow-on: repoint the formula at released binaries, dropping the build-time go + forgejo.coilysiren.me dependency for installers.

Done condition

A GitHub arrival can install a checksummed binary for their platform from the GitHub releases page without touching forgejo.coilysiren.me; both release pages show the same tag with the same checksums.

Related: #414 (github equivalents anchor), #442 (release-asset legibility), #438 (canonical-vs-mirror identity).


Filed by Claude Code, capturing Kai's release-direction decisions from the 2026-07-01 pressure-test debrief.

## Why Decision direction from Kai (2026-07-01, post-pressure-test-sweep): publish the full release binary matrix (darwin + linux × amd64 + arm64) to GitHub releases as well. This buys more than mirror parity: it serves GitHub arrivals (#414), fixes the confusing Linux-only release page (#442 checkbox 2), and removes a real availability coupling — today's brew formula builds from source with `GOPROXY=direct` against forgejo.coilysiren.me, so every install anywhere depends on that instance being up *and* a local go toolchain. Published binaries let the formula (or a plain curl-install) consume artifacts instead. ## Deliverable - The full matrix published to GitHub releases, CI-built **from the same tags** as the Forgejo releases so the two release pages cannot drift. - `SHA256SUMS` (ideally provenance/attestation) published alongside — without it, "which binaries are canonical, the Forgejo ones or the GitHub ones?" becomes a fair drive-by-critic dunk and worsens the canonical-vs-mirror confusion tracked in #438. - One sentence in the README or release-notes template saying what each asset is for and who installs which way. - Optional follow-on: repoint the formula at released binaries, dropping the build-time go + forgejo.coilysiren.me dependency for installers. ## Done condition A GitHub arrival can install a checksummed binary for their platform from the GitHub releases page without touching forgejo.coilysiren.me; both release pages show the same tag with the same checksums. Related: #414 (github equivalents anchor), #442 (release-asset legibility), #438 (canonical-vs-mirror identity). --- Filed by Claude Code, capturing Kai's release-direction decisions from the 2026-07-01 pressure-test debrief.
Author
Member

Observed baseline for this plan (github-only-dev/release-story, run 32, 2026-07-01): Forgejo v0.242.0 assets are linux-only, and 6 of 8 assets per release are ward-kdl tier binaries (ward-kdl-{read,write,admin}-linux-{amd64,arm64}) — so the pre-#455 asset list actively obscures which binary a newcomer wants. GitHub side currently shows stranded v0.5.x releases and 36 tags (frozen sync — filed separately as its own defect since it predates and is independent of this plan). Release-note bodies are commit-subject dumps of bare ward#NNN refs (cf. #446), which will read as noise on the GitHub releases page once the matrix publishes there.

Observed baseline for this plan (github-only-dev/release-story, run 32, 2026-07-01): Forgejo v0.242.0 assets are linux-only, and 6 of 8 assets per release are ward-kdl tier binaries (ward-kdl-{read,write,admin}-linux-{amd64,arm64}) — so the pre-#455 asset list actively obscures which binary a newcomer wants. GitHub side currently shows stranded v0.5.x releases and 36 tags (frozen sync — filed separately as its own defect since it predates and is independent of this plan). Release-note bodies are commit-subject dumps of bare ward#NNN refs (cf. #446), which will read as noise on the GitHub releases page once the matrix publishes there.
Author
Member

Data point from run 18 (drive-by-critic / install-path, real install performed on host in run 17s first-run pass): brew install coilyco-flight-deck/tap/ward compiles from source every time (go build + a specverb-gen codegen step), taking 2m35s / ~3m wall clock for a single CLI tool, and requires go as a build-time dependency the formula pulls in. The hostile-thread framing this invites: "a security tool that takes 3 minutes and a Go toolchain to install isnt lightweight, its dev-mode with extra steps - wheres the binary?" Release assets already exist (ward-linux-{amd64,arm64}, per #442) but the formula doesnt use them and theyre Linux-only anyway (no darwin). This is exactly the gap #454 already plans to close (full binary matrix, CI-built, checksummed) - flagging as a comment per the routing note rather than a new issue. Once #454 ships, the formula should switch from go build to downloading the matching prebuilt asset, which would also fix the missing-darwin-assets half of #442.

Data point from run 18 (`drive-by-critic` / `install-path`, real install performed on host in run 17s `first-run` pass): `brew install coilyco-flight-deck/tap/ward` compiles from source every time (`go build` + a `specverb-gen` codegen step), taking 2m35s / ~3m wall clock for a single CLI tool, and requires `go` as a build-time dependency the formula pulls in. The hostile-thread framing this invites: "a security tool that takes 3 minutes and a Go toolchain to install isnt lightweight, its dev-mode with extra steps - wheres the binary?" Release assets already exist (`ward-linux-{amd64,arm64}`, per #442) but the formula doesnt use them and theyre Linux-only anyway (no darwin). This is exactly the gap #454 already plans to close (full binary matrix, CI-built, checksummed) - flagging as a comment per the routing note rather than a new issue. Once #454 ships, the formula should switch from `go build` to downloading the matching prebuilt asset, which would also fix the missing-darwin-assets half of #442.
coilyco-ops added this to the ward launch milestone 2026-07-01 23:29:46 +00:00
Author
Member

DECISION - headless with one precondition: Kai provisions the GitHub token/secret capable of creating releases on the mirror BEFORE dispatch (secret will exist by run time; agent names and documents it in the workflow). Coordinate with #486 (release-notes template) and fold the surviving half of #345 (bump-tap-formula cancellation under matrix fan-out) into the same CI work if convenient. Recorded by Claude Code (Fable) during the 2026-07-01 ward launch triage session with Kai.

DECISION - headless with one precondition: Kai provisions the GitHub token/secret capable of creating releases on the mirror BEFORE dispatch (secret will exist by run time; agent names and documents it in the workflow). Coordinate with #486 (release-notes template) and fold the surviving half of #345 (bump-tap-formula cancellation under matrix fan-out) into the same CI work if convenient. Recorded by Claude Code (Fable) during the 2026-07-01 ward launch triage session with Kai.
Author
Member

🔒 Reserved by ward agent --driver claude — container engineer-claude-ward-454 on host kais-macbook-pro-2.local is carrying this issue (reserved 2026-07-02T07:52:24Z). Concurrent ward agent runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); --force overrides.

— Claude (she/her), via ward agent

<!-- ward-agent-reservation --> 🔒 Reserved by `ward agent --driver claude` — container `engineer-claude-ward-454` on host `kais-macbook-pro-2.local` is carrying this issue (reserved 2026-07-02T07:52:24Z). Concurrent `ward agent` runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); `--force` overrides. <!-- ward-agent-signature --> — Claude (she/her), via `ward agent`
Owner

WARD-OUTCOME: done - the full darwin+linux x amd64+arm64 matrix + SHA256SUMS now publishes to both the Forgejo and GitHub release pages, built once per tag so the checksums can't drift.

Retrospective, honestly: this went smoothly on the code and got fiddly on the docs. The core insight made itself obvious early - build the matrix once and upload the identical bytes to both forges, because any second build is a checksum-drift bug waiting to happen. github-mirror.md had already reserved this exact story (the author-guarded scrub keeps PAT-authored releases and deletes only github-actions[bot] ones), so reusing GITHUB_MIRROR_PAT and living in the release pipeline rather than the mirror workflow felt like the intended seam, not a hack. ward being pure Go meant CGO_ENABLED=0 cross-compiles the whole matrix from one linux runner - verified all four targets build locally.

What fought back: the doc size caps. README.md, release.md, and github-mirror.md all sat exactly at their line/char ceilings with near-zero headroom, so every edit had to be measured to the byte. The sanctioned remedy (split into a new docs/release-binaries.md) is what let the substantive detail land without butchering the existing docs. Then two rounds of concurrent pushes from sibling containers forced re-merges - one real README conflict where main still claimed 'the Releases page is empty', which my change makes false.

Confidence: high on the build/checksum logic and idempotent re-run handling (delete-same-named-asset-first on both forges); it's all verified offline - matrix cross-compile, the node JSON snippets, YAML structure, pre-commit, go test, vet. The one thing I couldn't exercise is the live API path (Forgejo + GitHub release create/upload) since it needs the real secrets and forges - that only truly proves out on the next release run. The precondition holds: GITHUB_MIRROR_PAT must be provisioned or the GitHub half skips loudly (Forgejo is unaffected).

Follow-ups worth filing: (1) the optional formula repoint at released binaries - dropping brew's build-time go + forgejo dependency - is deliberately not done here; it's the higher-risk half and deserves its own issue. (2) build provenance/attestation (the issue's 'ideally') is not implemented; SHA256SUMS is the checksum floor. (3) watch the first real release run to confirm the GitHub create/upload path is green end to end.

WARD-OUTCOME: done - the full darwin+linux x amd64+arm64 matrix + SHA256SUMS now publishes to both the Forgejo and GitHub release pages, built once per tag so the checksums can't drift. Retrospective, honestly: this went smoothly on the code and got fiddly on the docs. The core insight made itself obvious early - build the matrix *once* and upload the identical bytes to both forges, because any second build is a checksum-drift bug waiting to happen. `github-mirror.md` had already reserved this exact story (the author-guarded scrub keeps PAT-authored releases and deletes only `github-actions[bot]` ones), so reusing `GITHUB_MIRROR_PAT` and living in the release pipeline rather than the mirror workflow felt like the intended seam, not a hack. ward being pure Go meant `CGO_ENABLED=0` cross-compiles the whole matrix from one linux runner - verified all four targets build locally. What fought back: the doc size caps. `README.md`, `release.md`, and `github-mirror.md` all sat *exactly* at their line/char ceilings with near-zero headroom, so every edit had to be measured to the byte. The sanctioned remedy (split into a new `docs/release-binaries.md`) is what let the substantive detail land without butchering the existing docs. Then two rounds of concurrent pushes from sibling containers forced re-merges - one real README conflict where main still claimed 'the Releases page is empty', which my change makes false. Confidence: high on the build/checksum logic and idempotent re-run handling (delete-same-named-asset-first on both forges); it's all verified offline - matrix cross-compile, the node JSON snippets, YAML structure, pre-commit, go test, vet. The one thing I *couldn't* exercise is the live API path (Forgejo + GitHub release create/upload) since it needs the real secrets and forges - that only truly proves out on the next release run. The precondition holds: `GITHUB_MIRROR_PAT` must be provisioned or the GitHub half skips loudly (Forgejo is unaffected). Follow-ups worth filing: (1) the optional formula repoint at released binaries - dropping brew's build-time go + forgejo dependency - is deliberately not done here; it's the higher-risk half and deserves its own issue. (2) build provenance/attestation (the issue's 'ideally') is not implemented; SHA256SUMS is the checksum floor. (3) watch the first real release run to confirm the GitHub create/upload path is green end to end.
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
coilyco-flight-deck/ward#454
No description provided.