Conversation
…dd output_products, repo, owner profile fields Phase 1: - Bundle command: reject all filter/output options (--all, --input-products, --output-products, --prs, --issues, --output, --repo, --owner, --resolve, --no-resolve, --hide-features, --config, --directory) when a profile argument is given. - Remove command: reject all options except --dry-run and --force when a profile argument is given. - Profile-based commands now discover changelog.yml automatically (./changelog.yml then ./docs/changelog.yml) and return a helpful error if neither is found, rather than silently falling back to defaults. An explicit config path is still accepted when passed directly to the service layer (used by tests). - ChangelogRemoveArguments.Directory changed from required to nullable; ApplyConfigDefaults follows the same null-coalescing pattern as the bundle service. - Fixes a silent bug where --output was ignored in profile mode. Phase 2: - Add output_products, repo, and owner fields to BundleProfileYaml, BundleProfile, and the config loader mapping. - ProcessProfile applies these fields when building the bundled output: output_products overrides the products array with version/lifecycle substitution; repo and owner are stored on each product entry for correct PR/issue link generation. - MergeHideFeatures removed; profile mode now uses only the profile's hide_features (CLI --hide-features is rejected at the command layer). - Update changelog.example.yml and docs to document all new profile fields and the mutual exclusivity requirement. Made-with: Cursor
- Add 7 new unit tests for bundle/remove profile features:
- output_products overrides products array in bundle
- repo from profile is written to bundle product entries
- no repo/owner in profile preserves existing fallback behaviour
- missing config in profile mode returns error with advice (bundle + remove)
- changelog.yml discovered from CWD (./changelog.yml)
- changelog.yml discovered from docs/ subdir (./docs/changelog.yml)
- Update docs/contribute/changelog.md:
- Document mutual exclusivity of profile-based vs option-based bundle usage
- Add new "Profile-based bundling" section with full field reference table
- Document config auto-discovery behaviour for profile mode
- Update "Removal with profiles" to document mutual exclusivity,
allowed --dry-run/--force exceptions, and which profile fields are ignored
Made-with: Cursor
Adds repo and owner as top-level fields under bundle: in changelog.yml, providing a default that applies to all profiles. Profile-level values override the bundle-level default when set; otherwise the bundle-level value is used. This avoids repeating the same repo/owner in every profile when all profiles share the same repository. Also adds two tests verifying the fallback and override behaviour. Made-with: Cursor
Extends ApplyConfigDefaults in both ChangelogBundlingService and ChangelogRemoveService to fall back to bundle.repo and bundle.owner from config when --repo/--owner are not supplied on the CLI. This mirrors the existing behaviour for profile-based commands and means repo and owner rarely need to be specified on the command line when a changelog.yml with bundle-level defaults is present. Precedence: explicit CLI flag > bundle.repo/owner config > nothing (renderer falls back to product ID at render time). Adds four tests covering the config fallback and CLI-override paths for the bundle command. Made-with: Cursor
Updates all three places that describe --repo/--owner behaviour: - CLI param XML docs (bundle and remove): clarify both are optional and fall back to bundle.repo/bundle.owner in changelog.yml - changelog-bundle.md: expand --repo/--owner option descriptions; rewrite "Repository name in bundles" section to show the three-level precedence (CLI > profile > bundle config) with YAML examples; update profile fields table and the examples section to demonstrate bundle-level defaults with per-profile overrides - changelog.md: add a note that --repo/--owner fall back to config in option-based bundling; expand profile fields table to include bundle-level repo/owner defaults; update the --prs and --issues callout text to mention the config fallback Made-with: Cursor
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
…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
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
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
🔍 Preview links for changed docs |
src/services/Elastic.Changelog/Rendering/Markdown/BreakingChangesMarkdownRenderer.cs
Fixed
Show fixed
Hide fixed
src/services/Elastic.Changelog/Rendering/Markdown/DeprecationsMarkdownRenderer.cs
Fixed
Show fixed
Hide fixed
src/services/Elastic.Changelog/Rendering/Markdown/KnownIssuesMarkdownRenderer.cs
Fixed
Show fixed
Hide fixed
src/services/Elastic.Changelog/Rendering/Markdown/IndexMarkdownRenderer.cs
Fixed
Show fixed
Hide fixed
cotti
approved these changes
Mar 4, 2026
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