Skip to content

Nothing enforces a CHANGELOG [Unreleased] entry — 25 of 26 PRs since v0.107.0 shipped without one #2174

Description

@mabry1985

What happened

Prepping the v0.108.0 release, [Unreleased] had one entry (#2114) against 48 commits / 26 merged PRs since v0.107.0. Backfilled in #2173 — but the process hole that allowed it is still open, and it will recur on the next release.

Had Prepare Release been dispatched from that state, the GitHub Release, the CHANGELOG.md section and the marketing /changelog page would have announced only the delegate env editor — silently omitting workflow human gates (#2138/#2140/#2141/#2142), the managed Python runtime (#2144/#2149), the pip-less wheel installer (#2151), Fleet Room (#2129/#2132), and ~7 fixes.

Why it happened

docs/guides/releasing.md puts the entry squarely on the feature PR:

feature PR (adds a CHANGELOG [Unreleased] entry) ──▶ merge to main

…and prepare-release.yml only rolls whatever is in [Unreleased]. But nothing checks that the entry exists:

  • No CI gate. changelog appears in desktop-build.yml, prepare-release.yml, release.yml — none of them run on PRs, and ci.yml doesn't mention it.
  • No PR template. There's no .github/PULL_REQUEST_TEMPLATE.md at all, so there isn't even a checkbox reminder.
  • The failure is silent. A missing entry produces no warning at merge time and no warning at release time — roll happily promotes a nearly-empty section. The only way to catch it is for a human to read the diff of 26 PRs, which is exactly what didn't happen.

This is the same class as the publish.yml trigger failure called out in releasing.md: "Nothing alerts on a trigger that simply doesn't happen."

Suggested fix (pick one or both)

  1. A PR CI check — fail (or warn) when a PR touches non-doc source and doesn't add a line under ## [Unreleased]. Needs an escape hatch for genuine no-user-impact PRs: a skip-changelog label or a [skip changelog] marker, so chore/refactor work isn't blocked. scripts/changelog.py already parses the section, so the check is a few lines on top of existing code.
  2. A PR template with a "Changelog entry added under [Unreleased] (or skip-changelog)" checkbox — cheap, catches the honest omissions, no CI cost.

Optional third: have prepare-release.yml refuse (or loudly warn) when [Unreleased] has fewer entries than there are non-chore PRs since the last tag — a backstop for whatever slips past 1 and 2.

Notes

  • Fix 1 is the real gate; 2 is a cheap partial. 1 + 3 together make the failure impossible to ship silently.
  • Whoever picks this up: docs(changelog): backfill [Unreleased] for the 26 PRs merged since v0.107.0 #2173 is the backfill and a good sample of what a "good" entry looks like in this repo's house style (bold lead-in, mechanics + rationale, PR ref).
  • Worth deciding explicitly whether docs:/chore: PRs are exempt by convention — the release notes already exclude them (release.yml builds "notes minus chore/docs"), so the check should mirror that rule rather than invent a second one.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestteam-readyTriaged and approved for autonomous team dispatch — the ONLY intake gate the board pipeline accepts

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions