Skip to content

Close the issues a release says it resolves - #173

Open
woksin wants to merge 2 commits into
mainfrom
feat/close-resolved-issues
Open

Close the issues a release says it resolves#173
woksin wants to merge 2 commits into
mainfrom
feat/close-resolved-issues

Conversation

@woksin

@woksin woksin commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Added

  • The issues a release's notes say it resolves are closed when the release is created, each with a comment naming the release tag. Only a note bullet ending in (#123) counts; prose mentions and cross-repository references are left alone. Needs issues: write, and is turned off with close-resolved-issues: false

woksin and others added 2 commits August 5, 2026 23:03
Pull requests here name the issue a bullet delivers as a trailing
"(#123)", which is what the pull request template asks for and what the
release notes are built from - but nothing ever acted on it. Issues sat
open for months after the code that closed them shipped, and the only way
to find them was to read every merged pull request against every open
issue.

The post step now reads those references out of the notes it just
published, closes each issue and comments with the release tag.

Only the parenthesized form counts. Prose refers to issues constantly
("see #123", "blocked on #456") and reading those would close issues a
release merely mentions; a cross-repository reference names something this
token has no business closing. An issue already closed is left as it was,
and a number that turns out to be a pull request is skipped.

Closing never fails the step. The release is the thing that had to happen,
and a run reported as failed after publishing is worse than an issue left
open - including when the token lacks the issues:write scope the feature
needs.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JfEAq3cyHk3mrWpo8QA9db
Release notes carry code: a fenced workflow example, or an inline mention
of the very syntax the reader is being taught. A reference written inside
either is documentation, and closing on it closes whatever issue the
example's number happens to name.

The notes of this feature's own release are the proof - they explain the
form by writing it out, and that number in this repository is an unrelated
dependency bump. It is already closed, so the state check would have caught
it; that is luck, not a design.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JfEAq3cyHk3mrWpo8QA9db
@woksin woksin added the minor New, backwards-compatible capabilities label Aug 5, 2026
@woksin

woksin commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

Reviewer notes.

Why this exists. Triaging the org's backlog turned up 28 issues that had been delivered in shipped releases — some over a year earlier — and were still open, because the reference in the release notes was never acted on. Finding them meant cross-referencing 250 merged pull requests against every open issue by hand. This closes that loop at the point the information already exists.

The parsing contract is deliberately narrow. Only (#123) — the trailing parenthesized form the template mandates. Prose (see #123, Related: #456) is ignored, because these notes refer to issues constantly and a mention is not a delivery. Cratis/Screenplay#32 is ignored, because it names another repository's issue.

One thing worth your attention: this PR found its own bug. The first commit's parser did not understand markdown code spans — and the release notes for this very feature document the syntax by writing `(#123)` out. Releasing it would have tried to close release-action#123, an unrelated dependency bump. It happens to be closed already so the state check would have caught it, but that is luck. The second commit strips fenced blocks and inline code before matching, with specs for both, plus one asserting a real reference on a line that also carries code is still read.

Failure posture. Closing runs after the release exists and can never fail the step. A run reported as failed after publishing is worse than an issue left open — including when the token lacks issues: write, which is the likely first-run outcome for repositories that have not updated their permissions block.

The default is onclose-resolved-issues: true. Worth a deliberate yes or no from you, since it changes behavior for every consumer without them editing anything. The argument for on: the references are already there and already mean "this release delivers that issue", so acting on them needs no new discipline; and 18 repositories would otherwise each need a workflow edit to benefit. The argument for off: it closes issues on people's behalf. Easy to flip if you disagree.

Verification. yarn ci green — typecheck, lint, 126 specs (13 new for the parser, 9 for the closing behavior), coverage 89.65%, and both dist/ bundles rebuilt and committed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

minor New, backwards-compatible capabilities

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant