Skip to content

Improve changelog rule logic when config must apply to multiple products#2961

Open
lcawl wants to merge 26 commits intomainfrom
rules-bundle-products
Open

Improve changelog rule logic when config must apply to multiple products#2961
lcawl wants to merge 26 commits intomainfrom
rules-bundle-products

Conversation

@lcawl
Copy link
Contributor

@lcawl lcawl commented Mar 24, 2026

Problem

While testing elastic/kibana#258941 and elastic/docs-content#5582 it became obvious that some changelogs were appearing in docs where they weren't expected.

For example, 242105.yaml was picked up in the command "docs-builder changelog bundle observability-release 9.3.0 ./docs/9.3.0-observability.txt` when IMO it shouldn't have been.

The changelog configuration file contains:

rules:
  bundle:
      products:
        'observability':
          match_products: any
          include_products:
            - "observability"
          exclude_types:
            - docs
          # Include changelogs that have (at least) the following areas:
          match_areas: any
          include_areas:
            - "Actionable Observability"
            - "AI for observability"
            - "APM"
            - "Data ingestion and Fleet"
            - "Global experience"
            - "Infrastructure monitoring"
            - "Logs and metrics"
            - "Service maps"
            - "Streams"
            - "Uptime"
bundle:
  profiles:
    observability-release:
      output_products: "observability {version}"
      output: "observability/{version}.yaml"

The relevant changelog does not have either a products nor areas that matches the observability context (as indicated by the output_products). I tried removing {version} from the output_products and that didn't affect it either. It was unclear why the "changelog bundle" command thought this changelog matched the rules.

Solution summary

The final solution hinges on these decisions:

  1. The changelog's products list is curated by the folks who know best whether something is notable in any given product. That info should override whatever is asserted at the time of the bundle snapshot i.e. if a PR appears in the list for a product X release but the changelog does not mention that product, it's omitted from the release bundle (with a message for follow-up if necessary). This is the "disjoint" situation mentioned in this PR description and code.
  2. The products list in each bundle can include multiple values. However, to avoid very complex logic about how rules for each of those products intersect, only one product's rules will be applied. In the case where there are multiple products in the list, it'll default to the one that's first alphabetically. It seems a very rare situation where a release will truly have the exact same list of changes for multiple products but have different bundling rules. If that happens, the solution is to create multiple bundles (using --output-products or output_products to explicitly identify the single product each bundle should use for rule resolution).
  3. The same bundling rule logic applies to the changelog bundle and changelog gh-release commands. It does not apply to the changelog bundle-amend command.

What problem this solves

Earlier behavior mixed global rules.bundle filters with per-product maps in ways that were hard to reason about (global vs per-product precedence, disjoint multi-product changelogs, OR-style include_products, empty/missing products). This PR:

  1. Implements an explicit three-mode model for rules.bundle end-to-end.
  2. Adds match_products / match_areas (and related) conjunction semantics where every configured ID must appear on the changelog for the include/exclude rule to match as documented.

Final behavior: three bundle rule modes

  1. Mode 1 — No filtering
    No effective rules.bundle (nothing to apply). No product / type / area filtering from rules.bundle.

  2. Mode 2 — Global content
    Global-only rules.bundle (products absent or empty). Rules use each changelog’s own products, type, and areas. No single rule-context product and no disjoint exclusion.

    • include_products / exclude_products with match_products any / all / conjunction apply to changelog content as documented.
    • Changelogs with missing or empty products: included with a warning where applicable; type/area rules still apply when configured.
  3. Mode 3 — Per-product context
    Non-empty rules.bundle.products. Global rules.bundle product/type/area fields are not used for filtering. Resolution uses a single rule-context product; disjoint changelogs are excluded; empty/missing products are excluded with a warning; if there’s no per-product block for the context product, entries pass through (no global fallback).


Conjunction matching (conjunction)

  • MatchMode.Conjunction is added/used for multi-valued product and area matching (and wired through config loading, bundling, publish blockers, and PR create label rules where MatchMode applies).
  • Meaning (high level): for include_*, every listed ID must appear on the changelog to match; for exclude_*, every listed ID must appear to be excluded — see the tables in docs/contribute/changelog.md for precise semantics.

Code changes (high level)

Area What changed
Modes BundleFilterMode, BundleRules.DetermineFilterMode() (or equivalent extension) to classify config.
Resolution ResolveResult / ResolveResultWithRule including PassThrough for Mode 3.
Bundling ChangelogBundlingService: after primary gather (--all, --prs, --issues, --input-products, …), apply rules.bundle by mode; product matching includes Conjunction.
Config ChangelogConfigurationLoader: parse conjunction, adjust hints/warnings (e.g. Mode 3 ignores globals).
Profile ProfileFilterResolver: alignment with bundle/product handling.
Create / labels PrInfoProcessor: MatchMode.Conjunction for label rules.
Publish / areas PublishBlockerExtensions + MatchMode: conjunction for area matching.

Docs and examples


Tests

Steps to test

I re-tested Kibana scenarios as follows:

  1. Check out Kibana release notes grouped by team label kibana#258941
  2. Edit the changelog configuration file to try out various rules.bundle combinations. For example, start with all rules.bundle details removed/commented out.
  3. Re-generate bundles, for example, from the kibana folder:
    /path/to/docs-builder/.artifacts/publish/docs-builder/release/docs-builder changelog bundle kibana-release 9.3.0 ./docs/9.3.0-kibana.txt
  4. Check whether there are any unexpected or undesired changelogs in the bundles. For example, in this case there should be no changelogs excluded due to their areas/types/products. The only message here is expected (since that PR had the release_note:skip label):
    Warning: No changelog file found for PR: https://github.com/elastic/kibana/pull/233289
    The bundle includes changelogs that have only product: elasticsearch and product: observability even though the bundle's output_products is kibana. This is working as expected.
  5. Edit the changelog configuration file to try out the global rule scenario. For example:
    rules:
      bundle:
        match_products: any
        include_products:
          - kibana
          - elasticsearch
        exclude_types: "docs"
    Re-generate bundles and check whether the output is as expected. For example, in this case, there should no longer be any changelogs that have only product: observability. The messages here are expected (since some changelogs are now being filtered out of the bundle):
     Warning: [-bundle-include] Excluding '243409.yaml' from bundle (global product filter).
     NOTE: docs/changelog/243409.yaml
     
     0 Errors / 38 Warnings / 0 Hints
  6. If I add another global rule: exclude_areas: "AI for observability" then 239144.yaml is also excluded (it had been included before that since it had both kibana and observability products and multiple areas).
  7. Edit the changelog configuration file to test the new conjunction functionality. For example:
    rules:
      bundle:
        match_products: conjunction
        include_products:
          - kibana
          - observability
    In this case the bundle contains only changelogs that have both kibana and observability in their products list (as opposed to all where changelogs that had only one or the other would be included).
  8. Edit the changelog configuration file to test the product-specific rule scenario. For example:
    rules:
      bundle:
        products:
            'kibana':
               exclude_types: "docs"
               match_areas: any
               exclude_areas:
                 - "Actionable Observability"
                 - "AI for observability"
                 - "AI for security"
                 ...
    Re-generate bundles and check whether the output is as expected. In this case, since output_products was kibana (and therefore that's the bundle's products list) any changelogs that don't have intersecting products (e.g. the changelogs that only have elasticsearch product) are excluded. The bundle still contains changelogs that have both kibana and observability products as long as they don't have any of the excluded areas.
  9. If I add another clause to the product-specific rules like this:
    rules:
      bundle:
        products:
          kibana:
            match_products: any
            exclude_products:
              - observability
    Then the bundle correctly excludes any changelogs that have observability products. The changelogs that have both kibana and security products persist.

I also tested in a private repo with a combination of changelogs that had product: elasticsearch and product: cloud-serverless. The results were as expected.

Outstanding tasks

  • Clean up the bundle.rules docs

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: composer-2, claude-4-sonnet

@github-actions
Copy link

github-actions bot commented Mar 24, 2026

🔍 Preview links for changed docs

@lcawl lcawl force-pushed the rules-bundle-products branch from d2d8f12 to 804d0c0 Compare March 24, 2026 18:21
@lcawl lcawl marked this pull request as ready for review March 24, 2026 22:08
@lcawl lcawl requested review from a team as code owners March 24, 2026 22:08
@lcawl lcawl requested a review from cotti March 24, 2026 22:08
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 24, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The PR separates changelog collection from bundle-time filtering so rules.bundle is always evaluated after entries are gathered. It adds BundlePerProductRule, BundleFilterMode, and resolution types to support per-product bundle-rule contexts and a new DetermineFilterMode() extension. The loader now parses per-product include/exclude and match_products (including conjunction), validating mutual exclusivity and emitting warnings. The bundler dispatches filtering by mode (NoFiltering, GlobalContent, PerProductContext), resolves a rule-context product (alphabetical first match when applicable), and applies product/type/area filtering with diagnostics for excluded entries.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant Collector as Input Collector
participant Loader as Config Loader
participant Bundler as Changelog Bundler
participant Entry as Changelog Entry
participant Output as Bundle Output

Collector->>Entry: Gather changelog files (--input-products / --prs / --all)
Loader->>Bundler: Load rules.bundle (global rules + ByProduct -> BundlePerProductRule)
Bundler->>Bundler: DetermineFilterMode(bundleRules)
Bundler->>Entry: For each entry, read entry.products and type/areas
Bundler->>Bundler: ResolvePerProductBundleRule(entry, bundleRules, outputProductContext)
Bundler->>Bundler: Apply product include/exclude (global or resolved per-product rule)
Bundler->>Bundler: Apply type/area blocker (global or resolved per-product Blocker)
Bundler->>Output: Emit accepted entries
Bundler->>Output: Emit diagnostics for excluded entries

Suggested labels

fix, documentation

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 18.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: implementing per-product rule logic and a three-mode model for bundle filtering to fix incorrect changelog inclusion.
Description check ✅ Passed The pull request description clearly explains the problem, solution, and three-mode bundle rule model with concrete examples and testing steps.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch rules-bundle-products

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@config/changelog.example.yml`:
- Line 216: Update the warning comment about exclude_products to state that
per-context exclude_products override global product filtering, so context
excludes should generally be supersets of global excludes (include global
excludes) to avoid re-including globally excluded products; locate the comment
referencing "Context product lists should be subsets of global lists to avoid
conflicts" and change its wording to reflect that exclude_products in a context
replaces global excludes and therefore context lists should usually include
global excludes (be supersets) to prevent unintended inclusion.

In `@docs/contribute/changelog.md`:
- Around line 177-186: The docs for rules.bundle.products currently claim
per-product rules completely override global bundle rules; update the wording to
explain that overrides are applied per-dimension so unspecified dimensions fall
back to global rules (e.g., a product rule that only sets
include_products/exclude_products will not suppress global
exclude_types/include_types/exclude_areas/include_areas/match_areas); reference
the rules.bundle.products section and mirror this per-dimension fallback
clarification in the other affected section (the similar text around lines
221-239) so behavior aligns with tests (see test expectations in
BundleChangelogsTests regarding global exclude_types still applying).

In `@src/services/Elastic.Changelog/Bundling/ChangelogBundlingService.cs`:
- Around line 759-768: The current fallback when candidates.Count == 0 uses
entrySet (which can pick another per-product override); instead, replace that
branch so it falls back to the global bundle rule: when candidates is empty set
it to a single-item list that contains the canonical global product key (e.g.
the existing GlobalProductKey constant or string.Empty/NULL key your byProduct
map uses for global rules) rather than entrySet, so the subsequent
byProduct.TryGetValue lookup returns the global rule; update the branch that
touches candidates, entrySet and byProduct in ChangelogBundlingService/Select...
logic accordingly.

In
`@src/services/Elastic.Changelog/Configuration/ChangelogConfigurationLoader.cs`:
- Around line 738-748: The per-context default for match_products is wrong:
change the initialization of contextMatchProducts from inheritedMatch to the
resolved bundle-level matchProducts so contexts inherit
rules.bundle.match_products by default; then if productYaml.MatchProducts is
non-empty, call ParseMatchMode(productYaml.MatchProducts), emit the same error
via collector.EmitError on failure, and set contextMatchProducts = parsed.Value
on success (keeping the existing ParseMatchMode and collector.EmitError usage);
ensure you update the assignment that currently uses inheritedMatch to use
matchProducts instead.

In `@tests/Elastic.Changelog.Tests/Changelogs/BundleChangelogsTests.cs`:
- Around line 4839-4889: The test
BundleChangelogs_WithPerProductExcludeProducts_ExcludesContextMatchingProducts
currently doesn't verify that rules.bundle.products.security.exclude_products
actually exclude entries; add a new changelog entry created via CreateTestEntry
(e.g., "security-kibana-feature.yaml") whose product list includes both
"security" and "kibana" (shared [security, kibana] context), rerun the
BundleChangelogs call with the same input, and add an assertion that the output
bundle (read from outputPath) does NOT contain that new file name to ensure the
security-context exclude_products rule removed it; keep other assertions intact.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 73633035-ddcb-459a-94b0-bb5d91c07606

📥 Commits

Reviewing files that changed from the base of the PR and between 894d634 and 99d6d08.

📒 Files selected for processing (9)
  • config/changelog.example.yml
  • docs/cli/release/changelog-bundle.md
  • docs/cli/release/changelog-gh-release.md
  • docs/contribute/changelog.md
  • src/Elastic.Documentation.Configuration/Changelog/BlockConfiguration.cs
  • src/services/Elastic.Changelog/Bundling/ChangelogBundlingService.cs
  • src/services/Elastic.Changelog/Configuration/ChangelogConfigurationLoader.cs
  • tests/Elastic.Changelog.Tests/Changelogs/BundleChangelogsTests.cs
  • tests/Elastic.Changelog.Tests/Changelogs/ChangelogConfigurationTests.cs

@lcawl lcawl marked this pull request as ready for review March 27, 2026 02:49
@coderabbitai coderabbitai bot added documentation Improvements or additions to documentation fix and removed enhancement labels Mar 27, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (2)
src/services/Elastic.Changelog/Bundling/ChangelogBundlingService.cs (1)

714-785: Minor: ruleStats mixes counters with a warning flag, producing odd summary output.

Line 750 sets ruleStats["ineffective_pattern_warned"] = 1, which will appear in the bundle summary at line 779 as "ineffective_pattern_warned: 1 entries". This is technically correct but confusing.

Consider using a separate boolean flag for the warning state:

+var ineffectivePatternWarned = false;
 // ...
-if (!ruleStats.ContainsKey("ineffective_pattern_warned"))
+if (!ineffectivePatternWarned)
 {
     // emit hint
-    ruleStats["ineffective_pattern_warned"] = 1;
+    ineffectivePatternWarned = true;
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/services/Elastic.Changelog/Bundling/ChangelogBundlingService.cs` around
lines 714 - 785, The ruleStats dictionary is being used both for numeric
counters and a boolean flag ("ineffective_pattern_warned") which yields
confusing summary output; change the implementation in the
ChangelogBundlingService loop to keep ruleStats strictly numeric and introduce a
separate boolean (e.g., ineffectivePatternWarned) used by the per-product branch
(where resolveResult.Rule.MatchProducts is checked) to ensure the
collector.EmitHint for the ineffective-pattern warning is emitted only once;
update the final summary assembly (where ruleStats is read and the message
variable is built) to not include the boolean, and ensure references to
ruleStats and the new ineffectivePatternWarned flag are used in
ResolvePerProductBundleRule/ShouldExcludeByResolvedProductRule handling blocks
as needed.
tests/Elastic.Changelog.Tests/Changelogs/ChangelogConfigurationTests.cs (1)

1171-1193: Append Async to the new async test names.

These added [Fact] methods are all public async Task methods but still omit the required Async suffix.

As per coding guidelines, "Public async methods must use PascalCase + Async suffix (e.g., GetDataAsync)".

Also applies to: 1440-1610

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/Elastic.Changelog.Tests/Changelogs/ChangelogConfigurationTests.cs`
around lines 1171 - 1193, The test method
LoadChangelogConfiguration_WithRulesBundle_MatchProductsConjunction_LoadsCorrectly
is a public async Task and must be renamed to include the Async suffix (e.g.,
LoadChangelogConfiguration_WithRulesBundle_MatchProductsConjunction_LoadsCorrectlyAsync);
update the method name and any references to it (test discovery uses the method
name) and apply the same renaming pattern to the other public async tests in
this file (the ones noted in the comment range) so all public async methods
follow PascalCase + Async convention.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/services/Elastic.Changelog/Bundling/ProfileFilterResolver.cs`:
- Around line 341-350: The parser currently silently ignores extra tokens in
entries; update the logic that builds ProductArgument (the code handling
variable parts and the products.Add call) to validate token count: after
splitting into parts, if parts.Length is 0 continue, if parts.Length > 3 throw a
descriptive FormatException/ArgumentException that includes the offending entry
string, and only then create ProductArgument using parts[0..2] with default "*"
for missing tokens; this enforces fail-fast behavior for malformed product
entries in the ProductArgument creation path.

In `@tests/Elastic.Changelog.Tests/Changelogs/BundleChangelogsTests.cs`:
- Around line 4366-4369: The assertion is checking for the wrong diagnostic tag;
update the diagnostic check in the test (the block that asserts
Collector.Diagnostics contains a message) to look for "[-bundle-global]" instead
of "[-bundle-exclude]" so it matches the bundle service's global product-filter
diagnostic; keep the rest of the predicate (e.g., checking for
"1755268130-elasticsearch-feature.yaml") and leave the surrounding assertions on
result and Collector.Errors unchanged.
- Around line 5053-5104: The test
BundleChangelogs_WithPerProductRules_FallsBackToGlobalWhenNoContextRule
currently passes under both old and new fallback behaviors because globals
include "security"; update the test so globals do NOT include "security" (e.g.,
change the top-level rules.bundle.include_products to only "elasticsearch") and
keep OutputProducts = [new ProductArgument { Product = "security", Target =
"9.3.0" }]; this way security-feature.yaml will only be included if
missing-context per-product rules are correctly bypassing global filters; adjust
the assertions to expect security-feature.yaml included and confirm that
globals-excluded entries remain excluded using
ServiceWithConfig.BundleChangelogs and BundleChangelogsArguments/ProductArgument
references.

In `@tests/Elastic.Changelog.Tests/Changelogs/ChangelogConfigurationTests.cs`:
- Around line 1518-1549: The test
LoadChangelogConfiguration_WithPerProductProductFiltering_SubsetValidationWarning_EmitsWarning
is asserting a Mode-3 warning that should be ignored; update the assertions to
reflect Mode 3 behaviour by removing the expectation of a subset validation
warning and asserting no such diagnostic is emitted. Specifically, change the
checks after config load: remove or replace
Collector.Warnings.Should().BeGreaterThan(0) with an assertion that no warnings
are emitted (e.g., Collector.Warnings.Should().Be(0) or equivalent) and change
Collector.Diagnostics.Should().Contain(d => d.Message.Contains("Context
'security' includes products [security]")) to
Collector.Diagnostics.Should().NotContain(...), so the test aligns with
ChangelogConfigurationLoader's Mode 3 logic for rules.bundle.products.

---

Nitpick comments:
In `@src/services/Elastic.Changelog/Bundling/ChangelogBundlingService.cs`:
- Around line 714-785: The ruleStats dictionary is being used both for numeric
counters and a boolean flag ("ineffective_pattern_warned") which yields
confusing summary output; change the implementation in the
ChangelogBundlingService loop to keep ruleStats strictly numeric and introduce a
separate boolean (e.g., ineffectivePatternWarned) used by the per-product branch
(where resolveResult.Rule.MatchProducts is checked) to ensure the
collector.EmitHint for the ineffective-pattern warning is emitted only once;
update the final summary assembly (where ruleStats is read and the message
variable is built) to not include the boolean, and ensure references to
ruleStats and the new ineffectivePatternWarned flag are used in
ResolvePerProductBundleRule/ShouldExcludeByResolvedProductRule handling blocks
as needed.

In `@tests/Elastic.Changelog.Tests/Changelogs/ChangelogConfigurationTests.cs`:
- Around line 1171-1193: The test method
LoadChangelogConfiguration_WithRulesBundle_MatchProductsConjunction_LoadsCorrectly
is a public async Task and must be renamed to include the Async suffix (e.g.,
LoadChangelogConfiguration_WithRulesBundle_MatchProductsConjunction_LoadsCorrectlyAsync);
update the method name and any references to it (test discovery uses the method
name) and apply the same renaming pattern to the other public async tests in
this file (the ones noted in the comment range) so all public async methods
follow PascalCase + Async convention.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 829385b9-6ec9-4aa8-8c25-6c6ece3936f1

📥 Commits

Reviewing files that changed from the base of the PR and between 7a500a3 and 34ed8e9.

📒 Files selected for processing (16)
  • config/changelog.example.yml
  • docs/cli/release/changelog-bundle.md
  • docs/cli/release/changelog-gh-release.md
  • docs/contribute/changelog.md
  • src/Elastic.Documentation.Configuration/Changelog/BlockConfiguration.cs
  • src/Elastic.Documentation.Configuration/ReleaseNotes/ReleaseNotesSerialization.cs
  • src/Elastic.Documentation/ReleaseNotes/PublishBlocker.cs
  • src/Elastic.Documentation/ReleaseNotes/PublishBlockerExtensions.cs
  • src/services/Elastic.Changelog/Bundling/ChangelogBundlingService.cs
  • src/services/Elastic.Changelog/Bundling/ProfileFilterResolver.cs
  • src/services/Elastic.Changelog/Configuration/ChangelogConfigurationLoader.cs
  • src/services/Elastic.Changelog/Creation/PrInfoProcessor.cs
  • tests/Elastic.Changelog.Tests/Changelogs/BundleChangelogsTests.cs
  • tests/Elastic.Changelog.Tests/Changelogs/BundleRulesExtensionsTests.cs
  • tests/Elastic.Changelog.Tests/Changelogs/ChangelogConfigurationTests.cs
  • tests/Elastic.Documentation.Configuration.Tests/ReleaseNotes/PublishBlockerExtensionsTests.cs
✅ Files skipped from review due to trivial changes (1)
  • docs/cli/release/changelog-gh-release.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs/cli/release/changelog-bundle.md

@lcawl lcawl removed the documentation Improvements or additions to documentation label Mar 27, 2026
@lcawl lcawl marked this pull request as ready for review March 27, 2026 16:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants