Release notes: categorize changes using linked-issue labels, and fix the dead label strings
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 970
- Forks
- 486
- Avg merge
- 3d 33m
- Merged PRs (30d)
- 170
Description
Description
gather-release-data decides which changelog section each change lands in by reading pull request labels (categorize.ts → hasLabel, fed by octokit.pulls.get in github.ts). The labels the team actually maintains for this purpose — the Changelog: family — are applied almost exclusively to issues, so they never reach the categorizer.
Measured on dotCMS/core:
| Label | Total uses | On PRs | On issues |
|---|---|---|---|
Changelog: Breaking Change |
42 | 2 | 40 |
Changelog: Skip |
25 | 0 | 25 |
Changelog: Skip is matched exactly by SKIP_LABELS, and has still never taken effect, because it is never on a PR. That is the clearest evidence the family was intended to drive this pipeline and is reaching it through the wrong object.
Compounding this, most of the label strings the categorizer looks for do not exist in the repository at all. Auditing all 19 against the repo's 639 labels:
- Absent (dead entries):
feature,new feature,fix,defect,regression,infrastructure,security,ci/cd,deprecation,breaking change,eol - Present and actually used on PRs:
Area : CI/CD(149),dependencies(175),AI: Not Safe To Rollback(50),Doc : Not Needed(3) - Present but never applied to a PR:
Changelog: Skip(0),bug(0),enhancement(0),Human: Not Safe To Rollback(0)
Net effect: the deprecation category is unreachable by label — only title.startsWith('deprecat') can reach it — and categorization is in practice driven almost entirely by conventional-commit title prefixes. A change labelled Changelog: Breaking Change is silently filed under Fixes with a one-line summary, and the "Deprecations, End of Life & Reminders" section never receives it.
Note that hasLabel compares normalized names for exact equality, so 'breaking change' will never match Changelog: Breaking Change even once labels are read from the right place. Both halves need fixing.
Acceptance Criteria
-
gather-release-dataresolves each PR's linked issues and merges those issues' labels with the PR's own labels before categorizing. - The merged label set is used for categorization only.
SKIP_LABELSandROLLBACK_UNSAFE_LABELScontinue to read PR labels exclusively, so an issue-sideChangelog: Skipcan never silently drop a change from the release notes and an issue edit can never add or remove the rollback[!CAUTION]block. - When a PR label and a linked-issue label imply different categories, the existing first-match priority (
deprecation>feature>fix>infrastructure) decides, regardless of which object the label came from. No new precedence rule is introduced. - The label lists in
categorize.tsare remapped to names that exist indotCMS/core— at minimum'breaking change'→Changelog: Breaking Change— and the strings that match no repository label are removed. - A PR whose linked issue carries
Changelog: Breaking Changeis categorized asdeprecationand appears under "Deprecations, End of Life & Reminders". - A PR carrying no categorizing label, whose linked issue carries none either, still falls back to the conventional-commit title heuristics exactly as it does today.
- Unit tests in
categorize.test.tscover: label union across PR + issue, an issue-sideChangelog: Skipnot suppressing the change, an issue-sideChangelog: Breaking Changerouting todeprecation, and conflicting PR/issue labels resolving by the existing priority order. - Existing tests continue to pass (
npm testin.github/scripts/gather-release-data), andnpx tsc --noEmitis clean. - The additional label lookups do not materially slow the gatherer or trip GitHub rate limits on a full release (50+ PRs) — reuse the existing batching/throttling approach.
Priority
Medium
Additional Context
Where this came from. Found while QA-verifying #37331 — the acceptance criteria there included "the behavior change is called out in the release notes", which prompted a check of whether the generator could ever surface such a callout. It cannot, for the reasons above.
Dependency — already addressed separately. This work is only practical because extractLinkedIssues now actually resolves linked issues. That function required whitespace directly after the keyword (\s+), so the This PR fixes: #N colon form used by most dotCMS PR bodies matched nothing. Across the 40 most recently merged PRs, linkedIssues was empty for 25 of them; after loosening the separator it is empty for 1 (a chore(ci) PR with genuinely no linked issue). That change is a separate, self-contained edit to .github/scripts/gather-release-data/src/github.ts and is not in scope here — but merging it first is a prerequisite, since a label union keyed on linked issues is worthless while linkedIssues is empty 62% of the time.
Related second-order gap (out of scope, noted for whoever picks this up). BODY_CHAR_LIMIT = 1000 in github.ts truncates every PR body before the model sees it. Where a PR documents a user-visible behavior change further down the body, the generator never receives that text. In #37402 the behavior-change paragraph sits at offset ~2225 of a 4752-char body and is cut. Raising the limit has a real cost — the comment there explains it guards against MAX_ARG_STRLEN (128 KiB) on the assembled prompt — so it needs its own analysis rather than a bump.
Files involved
.github/scripts/gather-release-data/src/categorize.ts—SKIP_LABELS,ROLLBACK_UNSAFE_LABELS,FEATURE_LABELS,FIX_LABELS,INFRA_LABELS,DEPRECATION_LABELS,hasLabel,categorize,processChanges.github/scripts/gather-release-data/src/github.ts—fetchPRDetails(label source),extractLinkedIssues.github/scripts/gather-release-data/src/types.ts—PRDetails/Changeif the merged label set is carried explicitly.github/scripts/gather-release-data/prompt-template.md— the section set that consumescategory
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with .github/scripts/gather-release-data/src/categorize.ts and its categorize.test.ts tests, then trace label retrieval through github.ts and the PRDetails/Change types in types.ts. Verify the existing batching approach before adding linked-issue label data. Done means the specified label union, category priority, fallback behavior, skip/rollback isolation, tests, npm test, and npx tsc --noEmit all pass.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- github, node.js, typescript
- Domain
- release, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100