Status: Accepted Date: 2026-06-19 Deciders: Achref Soua
quiver update, scripts/install.sh, and scripts/install.ps1 all download a
per-platform binary plus its .sha256 from the GitHub release matching the
latest tag. The asset name is derived in crates/quiver-cli/src/update.rs:
quiver-<os>-<arch> # unix
quiver-<os>-<arch>.exe # windows
Two defects let a release ship without the assets those clients require:
-
release.ymlhad no Windows job. Its matrix built Linux (x86_64 + aarch64) and macOS (x86_64 + aarch64) only. The Windows.exefiles attached to the v0.17.0 / v0.17.2 releases were built by hand on a Windows machine and uploaded manually — an out-of-band step that is easy to forget. -
v0.18.0 shipped with zero assets. The tag was created but no release build ran, so
quiver updatefrom a Windows v0.17.2 client resolved…/download/v0.18.0/quiver-windows-x86_64.exeand failed with a 404:Error: failed to download https://github.com/achref-soua/quiver/releases/download/v0.18.0/quiver-windows-x86_64.exe
The deeper cause of (2): the release workflow is workflow_dispatch-only
(ADR-0015 made every workflow manual, with local just verify as the
authoritative gate). A tag can therefore be pushed with no asset build behind
it, and there is no signal that assets are missing.
Make release-asset publishing automatic and complete for every supported platform.
-
Add the Windows job. Extend the
release.ymlbuild matrix withwindows-latest/x86_64-pc-windows-msvc, producingquiver-windows-x86_64.exe(icon embedded natively viawinresource, ADR-0039) and its.sha256. Add both to the publish step'sfiles:list. -
Trigger on tag push. Add
on: push: tags: ['v[0-9]+.[0-9]+.[0-9]+']so that tagging a release (the existingdevelop → main, tag-on-mainflow) builds and attaches all five platform binaries with no extra step. Keepworkflow_dispatch(with ataginput) as a manual fallback to (re)build assets for an existing tag. -
Unify packaging across platforms in one
shell: bashstep (Git Bash on the Windows runner providescp+sha256sum); the.exesuffix is the only per-OS difference. -
Pass the resolved tag through
env:, never interpolated into the script body, per GitHub's workflow-injection guidance.
This narrows ADR-0015 for the release workflow specifically: test/build gates stay manual-by-design, but release publishing is automated on tag push — the binaries an end user downloads must never depend on a remembered manual step.
- Document a local fallback (
just release-local) that reproduces the CI build on a maintainer machine and uploads viagh release, for when hosted runners are unavailable (see Constraint below).
At the time of this ADR the account's hosted runners are billing-locked — a dispatched job is rejected in ~5 s with "The job was not started because your account is locked due to a billing issue." Until that is cleared, none of the four workflows can execute, so the automation above cannot run on push and v0.18.0's missing assets cannot be backfilled by CI.
Therefore:
- The workflow change is the durable fix: the moment billing is restored, tagging a release publishes every platform binary automatically, Windows included — no manual upload, no missing-asset class of bug.
- In the interim, releases are cut locally.
just release-localbuilds the targets the maintainer's toolchain supports (a Linux→Windows binary needs thex86_64-pc-windows-gnutarget +gcc-mingw-w64; a native Windows build needs a Windows host), generates checksums, and uploads them to the tag withgh.
Clearing the billing lock is the single owner action that turns this from "works locally" into "works automatically." It is out of scope for code.
- Cross-compile Windows from Linux in CI (
x86_64-pc-windows-gnu). Works (build.rs already supports it), but a nativewindows-latestMSVC build is the more compatible, lower-surprise artifact and is free on hosted runners. Rejected in favour of the native job; the gnu cross path remains the documented local fallback. - Keep Windows a manual upload. This is exactly the process that produced the v0.18.0 outage. Rejected.
- Trigger on GitHub
release: publishedinstead of tag push. Equivalent, but tag push matches the existing tag-on-mainrelease ritual and needs no separate "create release" click. Rejected for less ceremony.
Positive
- A pushed SemVer tag yields a complete, checksummed, multi-platform release — Windows included — with no out-of-band steps.
quiver update/install.sh/install.ps1can no longer 404 on a missing platform asset for a tagged release built by CI.- Injection-safe tag handling.
Negative / risks
- Automation is gated on the billing lock being cleared (documented above).
- Tag-triggered publishing means a mistakenly-pushed tag would publish a
release; mitigated by the strict
v*.*.*tag pattern and the existing protectedmain+ tag-on-main-only convention.
-
release.yml— Windows job + tag-push trigger + unified packaging + env-passed tag -
just release-localfallback recipe - ADR recorded
- Billing lock cleared (owner action — enables CI automation)
- First tag-triggered release verified green (blocked on the line above)