CI's shellcheck sweep never lints .github/scripts/*.sh — including release-notes.sh #118
Labels
No labels
blocked
blocker:ci-red
blocker:conflict
blocker:drill-pending
blocker:unrequested
bug
claimed
documentation
enhancement
epic
merge-next
needs-triage
ready
release
scope:apply
scope:capture
scope:coolify-api
scope:fleet
scope:manifest
scope:secrets
stale
state:addressing
state:bots-reviewing
state:building
state:needs-human
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: heavy-duty/cast#118
Loading…
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?
cast-side record of
heavy-duty/box#116. Same defect, same cause.The gap
.github/workflows/ci.yml's shellcheck step uses aglobstarsweep:globstarmakes**descend into subdirectories, but globs do not match dot-prefixed names withoutdotglob..githubis dot-prefixed, so**/never descends into it.Measured on
main, the tracked.shfiles CI never lints:Why it matters here
release-notes.shproduces the published release body —release.ymlruns it to extract the section for the version being shipped, andtest/release.test.tscalls the real script to assert the changelog guard (#113/#114). It is the script most load-bearing at release time and the one shellcheck never sees.cast is less exposed than the siblings overall, since most of its logic is TypeScript and
npm run check(biome) coverssrc/. But that is exactly why the shell gap is easy to miss: the repo's main quality gate does not look at shell at all, so these two files fall between biome and an unreachable shellcheck.Current state: latent, not broken
Nothing is failing today. The defect is that a regression in either file would ship unlinted.
Suggested fix
shopt -s globstar dotglob, checking what elsedotglobpulls in rather than assuming.Worth pairing with an assertion that the globbed set covers
git ls-files '*.sh', so this cannot reopen silently — the same class-check shapeheavy-duty/box#112used for its EOF-guard sweep, and the same reasoning behind cast's owndisarmedBecauseguard: catch the state, not the instance.Siblings
heavy-duty/box#116— misseschangelog-armed.sh,release-notes.sh,labels-reconcile.shheavy-duty/rig— missesrelease-lib.sh,labels-reconcile.sh(filed separately)Refs
Found during the
release: 0.1.1drill (#116), while replicating CI's exact sweep on a real host.