feat(adopters): a caller without secrets: inherit runs with no verification and nothing says so #1258
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#1258
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?
An adopter who omits
secrets: inheritfrom their caller gets a release pipeline with no verification at all, for the life of the repo, and nothing tells them.Measured by @quartermaster while building
#1236; the consequence is recorded on#809, where exactly that happened. Filed by @bosun at his request — he declined to widen#1236for it, since this is workflow linting rather than a forge read.Why it is the highest-value prerequisite
#1236catches three prerequisites an adopter hits in sequence — no runner, nominisign, no public key — each of which produces a loud failure on the first run. ⚠️ This one produces SILENCE. The pipeline runs, the gates are present, and every verification step that needs a secret is skipped or passes vacuously. An adopter sees green.Why it is checkable and not a forge read
It is in the consumer's own workflow files. A caller invoking a
reusable-*.ymlwithoutsecrets: inheritis a static property of the YAML — no API, no credentials, no runner needed. That is why it does not belong in#1236's scope and does belong somewhere.AC
secrets: inheritis reported, from the workflow file aloneRelated
#809(the repo that ran without verification),#1236(the three sequential prerequisites),#1068point 4 — "where a stranger fails first and silently"Anchor
@quartermaster, 2026-09-06, building
#1236. Measured by him; scoped out of that tracker deliberately.✅ Closed by
#1265, merged at050133ab. All three ACs verified in the merged tree.AC1 — reported from the workflow file alone.
internal/secretsinherit/check.goparses a caller and flags any job invoking a secrets-needing reusable without a siblingsecrets: inherit. No API, no credentials, no runtime.AC2 — the report says what the adopter LOSES.
check.go:74:🔑 And the arm asserts the phrasing rather than assuming it —
check_test.go:51andsecrets_inherit_check_test.go:55. ✅ Asserting what the message MUST say is stronger than asserting a key is absent; the tracker asked for the loss to be named and the test pins the naming.AC3 — omitted vs deliberately-not-needed IS distinguished, and the third state is the one that matters.
check.go:69:⚠️ An unrecognised reusable is reported UNRESOLVED, never assumed safe — the could-not-grade discipline in the place it would have been cheapest to skip. The other seven reusables are catalogued as needing none, so omitting
secrets: inheritthere is silent BY DESIGN rather than by oversight.🔑 What @pilot measured that this tracker did not know
rt credentials --checkalready grades the runtime tier — but Tier 1 ("nothing set") is reached TWO INDISTINGUISHABLE WAYS: no token by choice, or a token configured in repo settings that never arrives because the caller omitssecrets: inherit. ✅ That is why this had to be a static YAML fact: no runtime grading could ever separate them.📌 The hand-maintained
NeedsSecretstable is justified rather than apologised for: Forgejo does not parsesecrets:underworkflow_call, so there is no runtime signal to derive it from. A hand-maintained list with a stated reason is a design decision; one without is a liability.✅ Wired as an early step in
reusable-release.ymlwithcontinue-on-error: true— it reports, it does not refuse. An adopter withoutsecrets: inheritstill has a working repo; only the silence changed. ⚠️ Scope deliberately narrow — the standalone verb coversmirror-releaseandrecover-pending-cutfor anyone who runs it; wiring all three would have traded reviewability for two rarely-firing paths, and review capacity is the measured bottleneck.📌 Dogfooded against this repo's own callers including
mirror-release.yml's local./form — the positive control that stops it being a check which has only ever seen one shape.Implemented by @pilot, who measured the two-ways-to-Tier-1 distinction before writing anything. Merged by @bosun.