ci: spec-driven release process — maintainer tags, binaries gate packages#87
Conversation
Release Config FilesThe following is the list of files used in the release process. Update this PR #87: ci: spec-driven release process — maintainer tags, binaries gate packages14 files, +478 / -258 Scope🟡 736 lines changed. PRs under 400 receive more thorough review. 🟡 Large PR with no linked issue. 🟡 PR mixes config and source changes. Structural✅ No structural bloat detected. SlopStatic Analysis✅ Oxlint found no issues. CorrectnessFILE: scripts/gen-publish-workflow.md FILE: scripts/gen-publish-workflow.md FILE: .github/workflows/publish-packages.yml FILE: specs/release-process-spec.md FILE: scripts/gen-publish-workflow.md |
…ages Rebased onto main as the branch's net change (the iterative history lives in PR #87's review threads). - specs/release-process-spec.md: single reference for the release process — UI-driven releases, sequence diagram, version lockstep, OIDC trusted publishers, protection configuration, new-package bootstrap, recovery. - Rolling draft release with a changelog of merged PRs (release-drafter, SHA-pinned); publishing the draft cuts the release. Maintainers create tags; no workflow does, and no dispatch path remains in the release path. - publish-packages.yml is generated by scripts/gen-publish-workflow.md — an executable markdown document — and its version job validates the tag against every manifest, then waits for release.yml to succeed, so npm versions never exist without matching binaries. release.yml fails fast on a tag the manifests do not declare. - cli reads its version from cli/deno.json; the manifests are the single version source. - ReleaseSpecWarning renders a warning in the PR review comment when release configuration changes without a matching spec update (AGENTS.md rule 8).
The component's heading, maintenance note, and file list are documentation — they execute (the capture feeds the check) but never render into the review comment; only the conditional warning inside <Output> does (#88).
The review documents now use <Output> (#88), which the v0.2.0 binary predates — its CI review run fails to resolve the component and leaks documentation into the PR comment. Bump every manifest to 0.3.0 (spec §2 ritual) and pin review.yml / repo-analysis.yml to v0.3.0: those jobs fail loudly at install until the v0.3.0 draft release is published after merge, then run a binary that understands <Output>.
Motivation
Cutting a release was CLI-only,
publish-packages.ymlwas dispatchable with atyped version string (publishing npm versions with no corresponding binary),
the release process lived in scattered workflow comments, and the CLI
hardcoded its version separately from the manifests.
Approach
specs/release-process-spec.md(new): the single reference for therelease process — sequence diagram, version lockstep, OIDC trusted-publisher
settings, setup, new-package bootstrap, recovery. Absorbs
.github/PUBLISHING.md; workflows carry only operational comments pointingat the spec.
GitHub Releases UI ("Create new tag on publish" targeting
main) or bypushing a tag. No PAT, no tag workflow.
publish-packages.ymldropsworkflow_dispatch(via its generator).release.ymlfails fast when thetag does not match
cli/deno.json; the generatedversionjob validatesthe tag against every manifest.
versionjob polls therelease.ymlrun for the same commit and fails if the binary build fails,so npm versions never exist without matching binaries.
cli/deno.json(static JSON import bakedinto the compiled binary) — the manifests are the single version source;
verified the binary reports the manifest version.
Scope confirmation
New abstractions (if any)
None — one spec document; the publish orchestrator remains generated.
New dependencies (if any)
None (
jqships on GitHub runners).New tests (if any)
None automated; verified: generator typechecks and regenerates idempotently
(CI staleness check), all workflow YAML parses, the compiled binary reports
the manifest version, and lint/typecheck/tests pass.
Refs #88.