Changelog profile parity - final phases#2808
Open
lcawl wants to merge 8 commits intoprofile-parityfrom
Open
Conversation
…ation
Phase 3 (profile-based enhancements):
- Accept a newline-delimited URL list file as a profile argument, resolving
to PR or issue filters based on the URLs found in the file
- Support combined <version> <report|url-list> profile arguments so the
version can be used for {version} substitution while the report/file
drives filtering
- Wire Issues filter through ProfileFilterResult into bundling and remove services
Phase 4 (option-based enhancements):
- Add --report option to both `changelog bundle` and `changelog remove`,
accepting a promotion report URL or local HTML file path
- Enforce stricter validation for file-based --prs and --issues inputs:
every line must be a fully-qualified GitHub URL
Phase 5 (tests and documentation):
- Add 264-test coverage for all new behaviours in BundleChangelogsTests
and ChangelogRemoveTests
- Update changelog-bundle.md, changelog-remove.md, and contribute/changelog.md
to document new arguments, options, validation rules, and examples
Made-with: Cursor
This was referenced Mar 2, 2026
lcawl
added a commit
that referenced
this pull request
Mar 3, 2026
…-version Aligns with PR #2791 (bundle.repo/owner config fields) and PR #2808 (owner stored in bundle YAML and used for link generation). Config model changes: - BundleConfiguration gains Repo and Owner properties - BundleConfigurationYaml and ChangelogConfigurationLoader updated to serialize/deserialize the new fields Service changes: - ChangelogBundlingService.ApplyConfigDefaults falls back to config.Bundle.Repo / config.Bundle.Owner when CLI flags are absent - ChangelogRemoveService.ApplyConfigDefaults does the same Command changes: - Both Bundle and Remove --release-version blocks now load the changelog config before fetching the GitHub release, so the owner used to construct PR URLs follows the full precedence: --owner CLI > bundle.owner in changelog.yml > "elastic" - Same fix applied to the Bundle command for consistency Docs: - changelog-remove.md and contribute/changelog.md document the owner precedence, restore the "Remove by GitHub release" section, and add a matching note to the bundle release-version section Tests: - Two new tests in ChangelogRemoveTests verify config owner fallback and that explicit --owner overrides the config value Made-with: Cursor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This pull request is a continuation of #2791
It implements the final phases of an effort to get the profile-based
docs-builder changelog bundleanddocs-builder changelog removeinvocations to parity with the command-line-option method.I also merged some additional fixes into this PR via #2837 since at least one of them seemed like a regression.
Design Principles
changelog bundle <profile> <arg>orchangelog remove <profile> <arg>), any filter- or output-related command options must be rejected with an error. Profile config provides all such values.--dry-runand--forcemay be used with profiles. No other CLI options are allowed when using a profile.docs/changelog.yml):bundle.directory): The directory containing changelog YAML files for both bundle and remove.bundle.output_directory): For remove, the directory scanned for bundle dependencies. No--configor--directoryoverride — profile invocations rely on the config file.Implementation details
Phase 3 (profile-based enhancements):
to PR or issue filters based on the URLs found in the file
<version> <report|url-list>profile arguments so theversion can be used for
{version}substitution while the report/filedrives filtering
ProfileFilterResultinto bundling and remove servicesPhase 4 (option-based enhancements):
--reportoption to bothchangelog bundleandchangelog remove,accepting a promotion report URL or local HTML file path
--prsand--issuesinputs:every line must be a fully-qualified GitHub URL
Phase 5 (tests and documentation):
BundleChangelogsTestsand
ChangelogRemoveTestschangelog-bundle.md,changelog-remove.md, andcontribute/changelog.mdto document new arguments, options, validation rules, and examples
Bug fixes
Extra bugs discovered and fixed (see also #2837, which has fixes that were merged into this PR):
Bug 1:
changelog bundleprofile mode:bundle.directorywas skipped as output fallbackProcessProfilecomputed the output directory as:So when neither
bundle.output_directorywas set, it jumped straight to CWD, silently ignoringbundle.directory. The docs said it should usebundle.directoryas the fallback, but the code didn't. Fixed to:Bug 2:
changelog removeoption mode:bundle.directorywas never consultedChangelogCommand.Removeeagerly resolveddirectory ?? CWDbefore passing it to the service. This meantApplyConfigDefaults'sbundle.directorybranch was unreachable — if you hadbundle.directoryset in your config but didn't pass--directory,removewould always default to CWD. Fixed to passnullwhen--directoryis absent, letting the service's fallback chain work correctly.The consistent fallback order (now matches across both commands):
Input directory (where changelogs are read from):
bundle.directory--directorybundle.directoryOutput directory (
bundleonly —removehas no output file):bundle.output_directory--outputbundle.directorybundle.output_directory--directory→bundle.directory→ CWDBug 3:
ownermissing from bundleThe new
ownervalue frombundle.ownerin the changelog config was being correctly read and stored ininput.Owner(viaApplyConfigDefaults), and it was being used during the matching phase (inBuildFilterCriteria.DefaultOwner) to expand bare PR numbers like123intoowner/repo#123. However, it was never passed toBundleBuilder.BuildBundleand neitherBundledProductnorBundledProductDtohad anOwnerfield — so it was silently dropped before YAML serialization.Both render paths hardcode
"elastic"as the GitHub owner when building PR/issue URLs from short-form numbers (e.g.123→https://github.com/elastic/{repo}/pull/123). There is currently no mechanism to override this:Here's a summary of the fixes made:
Data model (bundle output)
BundledProductDto(Bundle.cs) — addedOwnerproperty to the YAML DTOBundledProduct.cs— addedOwnerto domain record and constructorReleaseNotesSerialization.cs— addedOwner = dto.OwnerinToBundledProduct(theToDtoside was already correct from the first session)BundleBuilder.cs/ChangelogBundlingService.cs— already correct from the first session, no changes neededDirective render path
LoadedBundle.cs— addedOwnerpositional parameter to the recordBundleLoader.cs— addedGetOwnerFromBundle(), passedownerto all threenew LoadedBundle(...)sitesChangelogInlineRenderer.cs— threadedownerthrough the full internal call chain (RenderSingleBundle→GenerateMarkdown→RenderEntriesByArea/RenderDetailedEntries→RenderSingleEntry/RenderDetailedEntry→RenderEntryLinks/RenderDetailedEntryLinks) and passed it toFormatPrLink/FormatIssueLinkCLI render path
ResolvedEntry— addedOwnerpropertyBundleDataResolver.cs— extracts owner from bundle products, sets on eachResolvedEntryChangelogRenderContext.cs— addedOwnerandEntryToOwnerpropertiesChangelogRenderingService.cs— populatesentryToOwnermap and setsOwner/EntryToOwneron contextMarkdownRendererBase.cs—GetEntryContextnow returnsentryOwner;RenderPrIssueLinksnow accepts and passesentryOwnerIndexMarkdownRenderer,KnownIssuesMarkdownRenderer,HighlightsMarkdownRenderer,DeprecationsMarkdownRenderer,BreakingChangesMarkdownRenderer— updated destructuring and call sitesChangelogTextUtilities.cs— addedstring owner = "elastic"parameter to all four link formatters; used in markdown URL templatesTests — updated
BundleChangelogs_WithProfile_RepoAndOwner_WritesValuesToProductEntriesto assertContain("owner: elastic")instead ofNotContain("owner:")NOTE: The asciidoc link formatters use attribute-reference syntax (
{repo-pull}123) rather than constructing GitHub URLs directly, soownerhas no meaning there — the owner is baked into the asciidoc attribute definitions elsewhere.FormatPrLinkAsciidocandFormatIssueLinkAsciidoctherefore don't needownerinfo. The markdown variants (FormatPrLinkandFormatIssueLink) retain the owner parameter and use it in the URL template.Steps for testing
The following sections describe the manual tests I performed.
Test profile-based bundles with PR and issue filters
elastic-agentrepo, run:Test combined
<version> <report|url-list>profile-based bundleRefer to https://github.com/lcawl/elasticsearch-serverless/pull/1
Test new
--reportoption to bothchangelog bundleandchangelog removeRefer to https://github.com/lcawl/elasticsearch-serverless/pull/1
Confirm stricter validation for file-based
--prsand--issuesOutstanding work
changelog.mdis necessary (for example to add profile-based examples since most of the bundle section of the doc relates to the command-options).Error: Failed to fetch promotion report from URL: ForbiddenGenerative AI disclosure
Tool(s) and model(s) used: composer-1.5, claude-4.6-sonnet-medium