feat(publish): un-draft the release as the final step #39
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/publish-undraft"
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?
build-kernel.ymlcreates the Forgejo release as a draft by design — that's the human review gate.publish.ymlcan read a draft's assets because it sends the token, so every step above succeeds while the release is still a draft. Which is precisely why the un-draft was easy to forget: nothing in any workflow did it, and it appeared in no runbook.Until it happens, an anonymous GET of the release assets 404s, breaking:
wget unredacted-hardened.derto enrol MOK. Without it they cannot boot the kernel they just installed on a Secure Boot machine.Being accurate about severity
This is not a live outage. I checked the server: every release shows status
releasedand the.derreturns HTTP 200 — the operator has been doing it by hand. The defect was a required manual step that existed in no runbook (documented asfirst-build.mdstep 10a in #34) and no automation. Worth stating plainly rather than letting the fix imply users were broken.Design
.draftfirst and exits early if already published, so re-running publish is safe.publish.ymlis itselfworkflow_dispatch-only; a human still decides when this runs.release: publishedtrigger — Forgejo emits no event on the draft→published transition, already verified and documented at the top of this file./releases/tags/{tag}: some Forgejo versions filter drafts out of the by-tag lookup and return a null id. Same reason and same pattern asbuild-kernel.yml's release-creation step.PATCHis not the same property as a user being able to fetch the certificate — and the second is what the docs promise.Verification
Simulated offline with a stubbed
curl:published release v7.1.5-hardened1 (id 42)+anonymous asset fetch OK (200)is already published; nothing to do— exits 0, no PATCH::warning::naming the 404 and pointing atsecure-boot.mdPasses all four
workflow-expressionsrules (including the new run:-body rule from #29) and theworkflow-shelllinter from #38 at--severity warningwith no findings.yamllint -d relaxedclean.Before trusting it in CI
The API shape isn't testable offline. Run the
PATCHby hand once against the already-publishedv7.1.4-hardened1to confirm it returns 200 and is a no-op — the step's own idempotency check means that's a safe experiment.🤖 Generated with Claude Code
build-kernel.yml creates the Forgejo release as a DRAFT by design -- that is the human review gate. publish.yml can read a draft's assets because it sends the token, so every step above succeeds while the release is still a draft, which is exactly why the un-draft was easy to forget. Nothing in any workflow did it, and it appeared in no runbook. Until it happens, an anonymous GET of the release assets 404s, which breaks: docs/users/secure-boot.md (users wget unredacted-hardened.der to enrol MOK -- without it they cannot boot the kernel they just installed on a Secure Boot machine), docs/users/verifying-packages.md (the same download plus the fingerprint published in the release notes), and docs/users/cve-policy.md (the releases RSS feed is the announced CVE-response channel, and drafts do not appear in it). To be accurate about severity: this is NOT a live outage. Checking the server, every release shows status `released` and the .der returns HTTP 200 -- the operator has been doing it by hand. The defect was a required manual step that existed in no runbook (now documented as first-build.md step 10a, in a separate change) and no automation. Placed LAST, after the registry publish and the manifest commit, so a failure earlier leaves the release a draft rather than announcing a half-published one. Idempotent: it reads `.draft` first and exits early if already published, so re-running publish is safe. Two properties worth recording: - It does not weaken the human gate. publish.yml is itself workflow_dispatch-only, so a human still decides when this runs. - It cannot recurse into this workflow's own `release: published` trigger: Forgejo emits no event on the draft->published transition, verified and documented at the top of this file. The release id comes from the LIST endpoint, not /releases/tags/{tag}: some Forgejo versions filter drafts out of the by-tag lookup and return a null id. Same reason and same pattern as build-kernel.yml's release-creation step. Finally, it verifies the assets are reachable WITHOUT credentials and warns if not. A 200 from the PATCH is not the same property as a user being able to fetch the certificate, and the second one is what the docs promise. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>