Skip to content

Commit 9b0165c

Browse files
lcawlcottigithub-code-quality[bot]
authored
Add changelog highlights (#2643)
Co-authored-by: Felipe Cotti <felipe.cotti@elastic.co> Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
1 parent 55f1559 commit 9b0165c

15 files changed

Lines changed: 571 additions & 12 deletions

File tree

docs/_docset.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,10 @@ toc:
227227
- folder: release-notes
228228
children:
229229
- file: index.md
230+
- file: highlights.md
230231
- file: breaking-changes.md
231232
- file: deprecations.md
232-
- file: known-issues.md
233+
- file: known-issues.md
234+
- folder: release-notes-all
235+
children:
236+
- file: index.md

docs/changelog/bundles/0.100.0.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ entries:
1111
areas:
1212
- CLI
1313
pr: https://github.com/elastic/docs-builder/pull/2350
14+
highlight: true
1415
description: |
1516
Adds support for configuring PR labels that block changelog creation.
1617
This allows teams to mark PRs that should not generate changelog entries

docs/cli/release/changelog-render.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,15 @@ When `--file-type markdown` is specified (the default), the command generates mu
7272
- `breaking-changes.md` - Contains breaking changes
7373
- `deprecations.md` - Contains deprecations
7474
- `known-issues.md` - Contains known issues
75+
- `highlights.md` - Contains highlighted entries (only created when at least one entry has `highlight: true`)
7576

7677
### Asciidoc format
7778

7879
When `--file-type asciidoc` is specified, the command generates a single asciidoc file with all sections:
7980

8081
- Security updates
8182
- Bug fixes
83+
- Highlights (only included when at least one entry has `highlight: true`)
8284
- New features and enhancements
8385
- Breaking changes
8486
- Deprecations

docs/contribute/changelog.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -625,3 +625,28 @@ docs-builder changelog render \
625625
```
626626

627627
1. Generate a single asciidoc file instead of multiple markdown files.
628+
629+
#### Release highlights
630+
631+
The `highlight` field allows you to mark changelog entries that should appear in a dedicated highlights page. Highlights are most commonly used for major or minor version releases to draw attention to the most important changes.
632+
633+
When you set `highlight: true` on a changelog entry:
634+
635+
- The entry appears in both the highlights page (`highlights.md`) and its normal type section (e.g., "Features and enhancements")
636+
- The highlights page is only created when at least one entry has `highlight: true` (unlike other special pages like `known-issues.md` which are always created)
637+
- Highlights can be any type of changelog entry (features, enhancements, bug fixes, etc.)
638+
639+
Example changelog entry with highlight:
640+
641+
```yaml
642+
type: feature
643+
products:
644+
- product: elasticsearch
645+
target: 9.3.0
646+
lifecycle: ga
647+
title: New Cloud Connect UI for self-managed installations
648+
description: Adds Cloud Connect functionality to Kibana, which allows you to use cloud solutions like AutoOps and Elastic Inference Service in your self-managed Elasticsearch clusters.
649+
highlight: true
650+
```
651+
652+
When rendering changelogs, entries with `highlight: true` are collected from all types and rendered in a dedicated highlights section. In markdown output, this creates a separate `highlights.md` file. In asciidoc output, highlights appear as a dedicated section in the single asciidoc file.

docs/syntax/changelog.md

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,16 @@ The directive supports the following options:
4141

4242
#### `:type:`
4343

44-
Controls which entry types are displayed. By default, the directive excludes "separated types" (known issues, breaking changes, and deprecations) which are typically shown on their own dedicated pages.
44+
Controls which entry types are displayed. By default, the directive excludes "separated types" (known issues, breaking changes, deprecations, and highlights) which are typically shown on their own dedicated pages.
4545

4646
| Value | Description |
4747
|-------|-------------|
48-
| (omitted) | Default: shows all types EXCEPT known issues, breaking changes, and deprecations |
49-
| `all` | Shows all entry types including known issues, breaking changes, and deprecations |
48+
| (omitted) | Default: shows all types EXCEPT known issues, breaking changes, deprecations, and highlights |
49+
| `all` | Shows all entry types including known issues, breaking changes, deprecations, and highlights |
5050
| `breaking-change` | Shows only breaking change entries |
5151
| `deprecation` | Shows only deprecation entries |
5252
| `known-issue` | Shows only known issue entries |
53+
| `highlight` | Shows only highlighted entries |
5354

5455
This allows you to create separate pages for different entry types:
5556

@@ -84,6 +85,14 @@ This allows you to create separate pages for different entry types:
8485
:::
8586
```
8687

88+
```markdown
89+
# Highlights
90+
91+
:::{changelog}
92+
:type: highlight
93+
:::
94+
```
95+
8796
To show all entries on a single page (previous default behavior):
8897

8998
```markdown
@@ -379,9 +388,16 @@ Each bundle renders as a `## {version}` section with subsections beneath:
379388
| Regressions | `regression` | Grouped by area |
380389
| Other changes | `other` | Grouped by area |
381390
| Breaking changes | `breaking-change` | Expandable dropdowns |
391+
| Highlights | Entries with `highlight: true` | Expandable dropdowns |
382392
| Deprecations | `deprecation` | Expandable dropdowns |
383393
| Known issues | `known-issue` | Expandable dropdowns |
384394

395+
**Note about highlights:**
396+
- Highlights only appear when using `:type: all` (they are excluded from the default view)
397+
- When rendered, highlighted entries appear in BOTH the "Highlights" section AND their original type section (for example, a highlighted feature appears in both "Highlights" and "Features and enhancements")
398+
- The "Highlights" section is only created when at least one entry has `highlight: true`
399+
- When using `:type: highlight`, only highlighted entries are shown (no section headers or other content)
400+
385401
Sections with no entries of that type are omitted from the output.
386402

387403
## Example
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Release Notes (All)
2+
3+
:::{changelog}
4+
:type: all
5+
:::
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Highlights
2+
3+
:::{changelog}
4+
:type: highlight
5+
:::

src/Elastic.Markdown/Myst/Directives/Changelog/ChangelogBlock.cs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,12 @@ public enum ChangelogTypeFilter
4040
/// <summary>
4141
/// Show only known issue entries.
4242
/// </summary>
43-
KnownIssue
43+
KnownIssue,
44+
45+
/// <summary>
46+
/// Show only highlighted entries (where highlight == true).
47+
/// </summary>
48+
Highlight
4449
}
4550

4651
/// <summary>
@@ -177,7 +182,7 @@ public override void FinalizeAndValidate(ParserContext context)
177182

178183
/// <summary>
179184
/// Parses and validates the :type: option.
180-
/// Valid values: all, breaking-change, deprecation, known-issue.
185+
/// Valid values: all, breaking-change, deprecation, known-issue, highlight.
181186
/// If not specified, returns Default (excludes separated types).
182187
/// </summary>
183188
private ChangelogTypeFilter ParseTypeFilter()
@@ -192,13 +197,14 @@ private ChangelogTypeFilter ParseTypeFilter()
192197
"breaking-change" => ChangelogTypeFilter.BreakingChange,
193198
"deprecation" => ChangelogTypeFilter.Deprecation,
194199
"known-issue" => ChangelogTypeFilter.KnownIssue,
200+
"highlight" => ChangelogTypeFilter.Highlight,
195201
_ => EmitInvalidTypeFilterWarning(typeValue)
196202
};
197203
}
198204

199205
private ChangelogTypeFilter EmitInvalidTypeFilterWarning(string typeValue)
200206
{
201-
this.EmitWarning($"Invalid :type: value '{typeValue}'. Valid values are: all, breaking-change, deprecation, known-issue. Using default behavior.");
207+
this.EmitWarning($"Invalid :type: value '{typeValue}'. Valid values are: all, breaking-change, deprecation, known-issue, highlight. Using default behavior.");
202208
return ChangelogTypeFilter.Default;
203209
}
204210

@@ -456,6 +462,20 @@ private IEnumerable<PageTocItem> ComputeTableOfContent()
456462
Level = 3
457463
};
458464

465+
// Check for highlights (any entry with highlight == true) - only show in :type: all
466+
var hasHighlights = bundle.Entries.Any(e => e.Highlight == true);
467+
if (hasHighlights && TypeFilter == ChangelogTypeFilter.All)
468+
yield return new PageTocItem
469+
{
470+
Heading = "Highlights",
471+
Slug = $"{repo}-{titleSlug}-highlights",
472+
Level = 3
473+
};
474+
475+
// When filtering by highlight, skip all other type-based sections
476+
if (TypeFilter == ChangelogTypeFilter.Highlight)
477+
continue;
478+
459479
if (shouldInclude(ChangelogEntryType.Security) && entriesByType.ContainsKey(ChangelogEntryType.Security))
460480
yield return new PageTocItem
461481
{

src/Elastic.Markdown/Myst/Directives/Changelog/ChangelogInlineRenderer.cs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ private static IReadOnlyList<ChangelogEntry> FilterEntriesByType(
8787
ChangelogTypeFilter.BreakingChange => entries.Where(e => e.Type == ChangelogEntryType.BreakingChange).ToList(),
8888
ChangelogTypeFilter.Deprecation => entries.Where(e => e.Type == ChangelogEntryType.Deprecation).ToList(),
8989
ChangelogTypeFilter.KnownIssue => entries.Where(e => e.Type == ChangelogEntryType.KnownIssue).ToList(),
90+
ChangelogTypeFilter.Highlight => entries.Where(e => e.Highlight == true).ToList(),
9091
_ => entries.Where(e => !ChangelogBlock.SeparatedTypes.Contains(e.Type)).ToList() // Default: exclude separated types
9192
};
9293

@@ -159,26 +160,48 @@ private static string GenerateMarkdown(
159160
var deprecations = entriesByType.GetValueOrDefault(ChangelogEntryType.Deprecation, []);
160161
var knownIssues = entriesByType.GetValueOrDefault(ChangelogEntryType.KnownIssue, []);
161162

163+
// Get highlighted entries from all types
164+
var highlights = entriesByType.Values
165+
.SelectMany(e => e)
166+
.Where(e => e.Highlight == true)
167+
.ToList();
168+
162169
_ = sb.AppendLine(CultureInfo.InvariantCulture, $"## {title}");
163170

164171
// Check if we have any content at all
165172
var hasAnyContent = features.Count > 0 || enhancements.Count > 0 || security.Count > 0 ||
166173
bugFixes.Count > 0 || docs.Count > 0 || regressions.Count > 0 || other.Count > 0 ||
167-
breakingChanges.Count > 0 || deprecations.Count > 0 || knownIssues.Count > 0;
174+
breakingChanges.Count > 0 || deprecations.Count > 0 || knownIssues.Count > 0 ||
175+
highlights.Count > 0;
168176

169177
if (!hasAnyContent)
170178
{
171179
_ = sb.AppendLine(GetEmptyMessage(typeFilter));
172180
return sb.ToString();
173181
}
174182

183+
// Special case: When filtering by highlight, render only highlights without type-based sections
184+
if (typeFilter == ChangelogTypeFilter.Highlight)
185+
{
186+
if (highlights.Count > 0)
187+
RenderDetailedEntries(sb, highlights, repo, groupBySubtype: false, hideLinks);
188+
return sb.ToString();
189+
}
190+
175191
if (breakingChanges.Count > 0)
176192
{
177193
_ = sb.AppendLine();
178194
_ = sb.AppendLine(CultureInfo.InvariantCulture, $"### Breaking changes [{repo}-{titleSlug}-breaking-changes]");
179195
RenderDetailedEntries(sb, breakingChanges, repo, groupBySubtype: true, hideLinks);
180196
}
181197

198+
if (highlights.Count > 0 && typeFilter == ChangelogTypeFilter.All)
199+
{
200+
_ = sb.AppendLine();
201+
_ = sb.AppendLine(CultureInfo.InvariantCulture, $"### Highlights [{repo}-{titleSlug}-highlights]");
202+
RenderDetailedEntries(sb, highlights, repo, groupBySubtype: false, hideLinks);
203+
}
204+
182205
if (security.Count > 0)
183206
{
184207
_ = sb.AppendLine();

src/services/Elastic.Changelog/Rendering/Asciidoc/ChangelogAsciidocRenderer.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public async Task RenderAsciidoc(ChangelogRenderContext context, Cancel ctx)
2525
var breakingChangesRenderer = new BreakingChangesAsciidocRenderer(sb);
2626
var deprecationsRenderer = new DeprecationsAsciidocRenderer(sb);
2727
var knownIssuesRenderer = new KnownIssuesAsciidocRenderer(sb);
28+
var highlightsRenderer = new HighlightsAsciidocRenderer(sb);
2829

2930
// Add anchor
3031
_ = sb.AppendLine(InvariantCulture, $"[[release-notes-{context.TitleSlug}]]");
@@ -60,6 +61,18 @@ public async Task RenderAsciidoc(ChangelogRenderContext context, Cancel ctx)
6061
_ = sb.AppendLine();
6162
}
6263

64+
// Render highlights (only if any entries have highlight == true)
65+
var highlights = entriesByType.Values
66+
.SelectMany(e => e)
67+
.Where(e => e.Highlight == true)
68+
.ToList();
69+
if (highlights.Count > 0)
70+
{
71+
RenderSectionHeader(sb, "highlights", context.TitleSlug, "Highlights");
72+
highlightsRenderer.Render(highlights, context);
73+
_ = sb.AppendLine();
74+
}
75+
6376
// Render features and enhancements
6477
if (features.Count > 0 || enhancements.Count > 0)
6578
{

0 commit comments

Comments
 (0)