Skip to content

Comments

Add support for issue-centric changelogs#2748

Open
lcawl wants to merge 14 commits intomainfrom
changelog-issues
Open

Add support for issue-centric changelogs#2748
lcawl wants to merge 14 commits intomainfrom
changelog-issues

Conversation

@lcawl
Copy link
Contributor

@lcawl lcawl commented Feb 19, 2026

Summary

This PR adds issue-centric workflow support to the changelog commands, so changelog files can be authored, filtered, and bundled by GitHub issue numbers — not just PR numbers. It also migrates the pr field from a single string to a prs array to support multi-PR changelogs.


Schema: prprs (array)

  • The pr field (single string) is replaced by prs (list of strings) in changelog YAML files.
  • Backward compatible: the old pr: key is still parsed and transparently promoted to a single-element prs list.
  • Writers always emit prs: going forward.

Before:

pr: "137431"

After:

prs:
  - "137431"
  - "137432"

Changelog YAML files can now record GitHub issue numbers alongside (or instead of) PRs:

title: My feature
type: feature
prs:
  - "137431"
issues:
  - "12345"

CLI changes

changelog add

  • New --issues option: accepts comma-separated issue numbers or a file path containing them.
  • When --issues is provided without --prs, docs-builder fetches the issue from GitHub, extracts metadata (title, labels → type/area, linked PRs from body), and creates the changelog file(s) automatically.
  • New --use-issue-number flag: names the output file by issue number instead of PR number (e.g. 12345.yaml).
  • --use-pr-number now aggregates multiple PR numbers in the filename (e.g. 137431-137432.yaml).

changelog bundle

  • New --issues filter: includes only changelog files whose issues field contains at least one matching value (any-match semantics, same as --prs).
  • --prs now iterates the full prs array; a file is included if any listed PR matches.

Any-match semantics (not all-match)

For both --prs and --issues filters, a changelog file is included in the bundle as soon as any single value in its array matches any value in the filter set. The file does not need to list every filtered PR/issue.


GitHub derivation for changelog add --issues

When creating changelogs from issues, the tool:

  1. Fetches the issue from the GitHub API.
  2. Maps issue labels to type and areas using the repo's rules.create label mapping.
  3. Extracts release notes from the issue body (if a release notes: section is present).
  4. Scans the issue body for linked PR URLs and populates prs.
  5. Writes one changelog file per issue, applying the same rules as the PR-based flow.

Documentation

  • docs/contribute/changelog.md, docs/cli/release/changelog-bundle.md, docs/cli/release/changelog-add.md:
    • updated with --issues, --use-issue-number, issue-centric workflow, and GitHub derivation details.
    • The --no-extract-issues / extract.issues prose now clarifies both directions.
  • docs/contribute/_snippets/changelog-fields.md: updated field reference (prprs field).
  • MCP changelog template and guidelines updated to reflect the new schema.

The following changes were also added in later commits:

  • CreateChangelogArgumentsValidator.cs

    • ValidateRequiredFields: When neither --prs nor --issues was specified and title is missing, the error now says "specify --prs or --issues to derive it". When --issues was used and title is missing, it says "specify --issues to derive it from the issue".
  • ChangelogCommand.cs (help text)

    • issues param: Expanded from a thin one-liner to full --prs-level detail (file path, comma-separated, --owner/--repo for bare numbers, one file per issue).
    • noExtractIssues param: Now describes both directions — issues from PR body and PRs from issue body.
    • owner / repo params: "used when --prs contains just numbers" → "used when --prs or --issues contains just numbers".
    • title / type params: "Required if --prs is not specified" → "Required if neither --prs nor --issues is specified."
  • config/changelog.example.yml

    • The extract.issues comment updated to describe both PR→issues and issue→PRs extraction.

Test changes

  • All test fixtures migrated from pr: https://... to prs: ["NNN"].
  • New test: BundleChangelogs_WithIssuesFilter_FiltersCorrectly.
  • New test: BundleChangelogs_WithOldPrFormat_StillMatchesWhenFilteringByPrs (backward compatibility).
  • ExtractIssueNumber utility tests added.

Some additional iteration was required to get the tests to pass, as follows:

  1. ChangelogCreationService: routing fix for issues-only flow with pre-populated fields (ChangelogCreationService.cs)

    • Problem: The test CreateChangelog_WithIssues_CreatesValidYaml failed because when Issues contained multiple values and no PRs were provided, the service always routed to CreateChangelogsForMultipleIssuesAsync. That method creates one file per issue (intended for GitHub-derived changelogs), so each file only contained a single issue URL.
    • Fix: Added an early-exit path in the issues-only routing block. When the title and type fields are already provided (no GitHub derivation needed), the service now routes to CreateSingleChangelogAsync, which produces a single file with all issue URLs recorded as metadata in the issues: array.
  2. ChangelogFileWriter: raw string literal indentation fix (ChangelogFileWriter.cs)

    • Problem: A CS8999 compiler error — lines in the YAML template for the # prs: comment block had incorrect indentation relative to the raw string literal's closing delimiter.
    • Fix: Corrected the tab indentation of two comment lines (# prs: and the following description) to match the closing """ delimiter.
  3. IssueInfoProcessor: duplicate using directive removed (IssueInfoProcessor.cs)

    • Problem: A CS0105 compiler error — using Elastic.Documentation.ReleaseNotes; appeared twice in the file.
    • Fix: Removed the duplicate using directive.
  4. Test fixtures: migrated from pr: to prs: array format (multiple *Tests.cs files)

    • Problem: After the schema change from a single pr: <url> field to a prs: array, all inline YAML fixtures in the test files still used the old format, causing deserialization mismatches.
    • Fix: Bulk-updated all test fixtures across the render and bundle-loading test files (BasicRenderTests, BlockConfigurationTests, BundleAmendTests, BundleLoaderTests, BundleValidationTests, ChecksumValidationTests, DuplicateHandlingTests, ErrorHandlingTests, HideFeaturesTests, HighlightsRenderTests, OutputFormatTests, TitleTargetTests) to use the new prs: array format. One instance in BundleChangelogsTests was intentionally left in the old pr: format to cover backward-compatibility deserialization.
  5. ChangelogTocFilteringTests: YAML malformation fix

    • Problem: An automated bulk replacement introduced an extra blank line after prs: in the YAML fixtures, making the YAML structurally invalid.
  6. ChangelogLinksHiddenInDetailedEntriesTests failures

    • Switched from AddToFileSystem to the constructor initializer (=> FileSystem.AddFile(...)) so the bundle file is added in the constructor body and is present before parsing.
    • Adjusted YAML so prs and issues lists use consistent indentation (list items aligned with the key).
  7. YAML indentation

    • Changelog bundle YAML was updated across several tests so prs and issues use the correct format:
# Before (could break parsing)
prs:
    - "123456"
issues:
  - "78901"

# After
prs:
- "123456"
issues:
- "78901"
  1. Use explicit Title and Type in changelog tests

    • Fixed tests to no longer rely on deriving type from PR labels.
  2. Add breaking-change to the config in changelog tests

    • The changelog config loader requires pivot.types to define all three types: feature, bug-fix, and breaking-change. The config was missing breaking-change, so loading failed and returned null, which made CreateChangelog fail immediately.
  3. Correct lifecycles placement in changelog tests

    • lifecycles was placed under pivot, but the loader expects it at the top level of ChangelogConfigurationYaml. It was moved to the correct level so lifecycle validation works.

Generative AI disclosure

  1. Did you use a generative AI (GenAI) tool to assist in creating this contribution?
  • Yes
  • No
  1. If you answered "Yes" to the previous question, please specify the tool(s) and model(s) used (e.g., Google Gemini, OpenAI ChatGPT-4, etc.).

Tool(s) and model(s) used: claude-4.6-sonnet-medium, composer-1.5

@github-actions
Copy link

github-actions bot commented Feb 19, 2026

…ect'

Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
…ariable'

Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant