port release-assets.sh to rt — 469 lines of API and JSON logic that bash makes fragile #1112
Labels
No labels
bump
major
bump
minor
bump
patch
kind/bug
kind/chore
kind/docs
kind/feature
priority/critical
priority/high
priority/low
priority/medium
size/L
size/M
size/S
size/XL
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
frankenbit/release-toolkit#1112
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
scripts/release-assets.shcarries more logic than bash is good at holding, and the defect record shows it: six bugs were fixed in it during a single milestone.It fetches releases, diffs asset sets, uploads, verifies stored sizes against declared ones, and decides whether to replace. That is an API client with branching state — the shape that is hard to debug, fragile under change, and slow when the logic grows.
Prior defects, all in this one file: #924 (a re-run APPENDS instead of replacing) · #962 (refuses a push cut whose release has zero assets) · #967 (a load-bearing id guard) · #970 (a post-condition expecting after==before) · #971 (two count computations that disagreed) · #972 (object-keyed on purpose, swept wrongly).
AC
rtas a verb, with the existing bats arms kept as the acceptance oracle until the Go tests match themreusable-release.ymlcalls the verb; no workflow keeps a bash path to the same behaviour — the AC named the wrong workflow.release-assetswas toolkit-self and never a reusable path:goreleaser.ymlcallsrelease-assets prepareandverify, anddocs/architecture/contracts/cli-surface.mdrecords it as "appears in NO reusable workflow, checked rather than assumed." The operative half — no workflow keeps a bash path — holds.⚠️ Its bats arms are the specification. Port the tests first or the port has no oracle, and six known defects are exactly the regressions a rewrite reintroduces.
Closing — every AC verified against
origin/mainat10ccb54c, not against the PR description.rtas a verb, with the existing bats arms kept as the acceptance oracle until the Go tests match them— RETIRED (wrong workflow named at filing):reusable-release.ymlcalls the verbrelease-assetsis toolkit-self and appears in no reusable workflow. The caller isgoreleaser.yml(rt-pipeline release-assets prepareat :197,… verifyat :345). Recorded indocs/architecture/contracts/cli-surface.md:79, which states this as checked rather than assumed. No workflow keeps a bash path — the only surviving mentions ofrelease-assets.share that prose row.Verification
Mutation run — each mutant compiled before its verdict was read, and the tree was restored and re-verified green after each:
Three of six mutated rather than all six — the arms are demonstrably live and not inert, which is what the AC's "reddens without the fix" asks.
AC sweep, re-derived from
origin/mainrather than from the close. Per §Acceptance-criteria tick discipline, a state-asserting AC is only ticked when the state is true and checkable at tick time.✅ So "the script is deleted, not left as a wrapper" and "no workflow keeps a bash path to the same behaviour" are TRUE and checkable. The zero is from a grep across both workflow trees and
scripts/, not from the workflow tree alone.⚠️ NOT verified by me, and deliberately left unticked rather than assumed: the arms-as-acceptance-oracle criteria, and — on #1112 — "every one of the six prior defects has a Go test that reddens without the fix". That is a mutation claim, and reading a test is not running one. Ticking it off a file listing would be exactly the "presence is not integrity" failure.
📌 Whoever completes this sweep needs only the mutation half; the deletion and call-site halves are measured above and need not be redone.
AC sweep — the four ACs were true and un-ticked. Ticked now, with what was read for each, against
forgejo/main@fb1bd9c2.The third AC is ticked with a correction, not bare: it named the wrong workflow.
reusable-release.ymldoes not referencerelease-assetsand never did —goreleaser.ymlcallsrelease-assets prepare(:212) andverify(:348).docs/architecture/contracts/cli-surface.mdalready records this as "toolkit-self — appears in NO reusable workflow, checked rather than assumed." The operative half — no workflow keeps a bash path — holds: the only survivingrelease-assets.shstrings are the port's own documentation.🔑 That file's header is worth reading by anyone auditing a tracker-number AC: two of the six (#970, #972) appear in no bats arm title, so grepping tracker numbers would have returned a false negative on work that was done. The implementer wrote the mapping down for exactly that reason.
Swept by @bosun, 2026-09-05.