Skip to content

Commit 1a78ddf

Browse files
committed
Add support for release-date field
1 parent 75fc1d6 commit 1a78ddf

File tree

13 files changed

+375
-9
lines changed

13 files changed

+375
-9
lines changed

docs/cli/changelog/bundle.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,25 @@ docs-builder changelog bundle \
388388
--description "Elasticsearch {version} includes performance improvements. Download: https://github.com/{owner}/{repo}/releases/tag/v{version}"
389389
```
390390

391+
### Bundle with release date
392+
393+
You can add a `release-date` field directly to a bundle YAML file. This field is optional and purely informative for end-users. It is especially useful for components released outside the usual stack lifecycle, such as APM agents and EDOT agents.
394+
395+
```yaml
396+
products:
397+
- product: apm-agent-dotnet
398+
target: 1.34.0
399+
release-date: "April 9, 2026"
400+
description: |
401+
This release includes tracing improvements and bug fixes.
402+
entries:
403+
- file:
404+
name: tracing-improvement.yaml
405+
checksum: abc123
406+
```
407+
408+
When the bundle is rendered (by the `changelog render` command or `{changelog}` directive), the release date appears immediately after the version heading as italicized text: `_Released: April 9, 2026_`.
409+
391410
## Profile-based examples
392411

393412
When the changelog configuration file defines `bundle.profiles`, you can use those profiles with the `changelog bundle` command.

docs/syntax/changelog.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,10 +142,11 @@ For full syntax, refer to the [rules for filtered bundles](/cli/changelog/bundle
142142
When bundles contain a `hide-features` field, entries with matching `feature-id` values are automatically filtered out from the rendered output. This allows you to hide unreleased or experimental features without modifying the bundle at render time.
143143

144144
```yaml
145-
# Example bundle with description and hide-features
145+
# Example bundle with release-date, description, and hide-features
146146
products:
147147
- product: elasticsearch
148148
target: 9.3.0
149+
release-date: "2026-04-09"
149150
description: |
150151
This release includes new features and bug fixes.
151152
@@ -227,11 +228,13 @@ The version is extracted from the first product's `target` field in each bundle
227228

228229
## Rendered output
229230

230-
Each bundle renders as a `## {version}` section with optional description and subsections beneath:
231+
Each bundle renders as a `## {version}` section with optional release date, description, and subsections beneath:
231232

232233
```markdown
233234
## 0.100.0
234235
236+
_Released: 2026-04-09_
237+
235238
This release includes new features and bug fixes.
236239
237240
Download the release binaries: https://github.com/elastic/elasticsearch/releases/tag/v0.100.0
@@ -246,7 +249,9 @@ Download the release binaries: https://github.com/elastic/elasticsearch/releases
246249
...
247250
```
248251

249-
Bundle descriptions are rendered when present in the bundle YAML file. The description appears immediately after the version heading but before any entry sections. Descriptions support Markdown formatting including links, lists, and multiple paragraphs.
252+
When present, the `release-date` field is rendered immediately after the version heading as italicized text (e.g., `_Released: 2026-04-09_`). This is purely informative for end-users and is especially useful for components released outside the usual stack lifecycle, such as APM agents and EDOT agents.
253+
254+
Bundle descriptions are rendered when present in the bundle YAML file. The description appears after the release date (if any) but before any entry sections. Descriptions support Markdown formatting including links, lists, and multiple paragraphs.
250255

251256
### Section types
252257

src/Elastic.Documentation.Configuration/ReleaseNotes/Bundle.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ public sealed record BundleDto
1818
/// </summary>
1919
public string? Description { get; set; }
2020
/// <summary>
21+
/// Optional release date for this bundle.
22+
/// Purely informative; rendered after the release heading.
23+
/// </summary>
24+
[YamlMember(Alias = "release-date", ApplyNamingConventions = false)]
25+
public string? ReleaseDate { get; set; }
26+
/// <summary>
2127
/// Feature IDs that should be hidden when rendering this bundle.
2228
/// Entries with matching feature-id values will be commented out in the output.
2329
/// </summary>

src/Elastic.Documentation.Configuration/ReleaseNotes/BundleLoader.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,19 @@ private static LoadedBundle MergeBundleGroup(IGrouping<string, LoadedBundle> gro
229229
_ => string.Join("\n\n", descriptions)
230230
};
231231

232-
var mergedData = first.Data with { Description = mergedDescription };
232+
var releaseDates = bundlesList
233+
.Select(b => b.Data?.ReleaseDate)
234+
.Where(d => !string.IsNullOrEmpty(d))
235+
.Distinct()
236+
.ToList();
237+
238+
var mergedReleaseDate = releaseDates.Count switch
239+
{
240+
0 => null,
241+
_ => releaseDates[0]
242+
};
243+
244+
var mergedData = first.Data with { Description = mergedDescription, ReleaseDate = mergedReleaseDate };
233245

234246
return new LoadedBundle(
235247
first.Version,

src/Elastic.Documentation.Configuration/ReleaseNotes/ReleaseNotesSerialization.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ public static string SerializeBundle(Bundle bundle)
136136
{
137137
Products = dto.Products?.Select(ToBundledProduct).ToList() ?? [],
138138
Description = dto.Description,
139+
ReleaseDate = dto.ReleaseDate,
139140
HideFeatures = dto.HideFeatures ?? [],
140141
Entries = dto.Entries?.Select(ToBundledEntry).ToList() ?? []
141142
};
@@ -241,6 +242,7 @@ private static ChangelogEntryType ParseEntryType(string? value)
241242
{
242243
Products = bundle.Products.Select(ToDto).ToList(),
243244
Description = bundle.Description,
245+
ReleaseDate = bundle.ReleaseDate,
244246
HideFeatures = bundle.HideFeatures.Count > 0 ? bundle.HideFeatures.ToList() : null,
245247
Entries = bundle.Entries.Select(ToDto).ToList()
246248
};

src/Elastic.Documentation/ReleaseNotes/Bundle.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ public record Bundle
1919
/// </summary>
2020
public string? Description { get; init; }
2121

22+
/// <summary>
23+
/// Optional release date for this bundle.
24+
/// Purely informative for end-users; rendered after the release heading.
25+
/// Useful for components released outside the usual stack lifecycle (e.g., APM/EDOT agents).
26+
/// </summary>
27+
public string? ReleaseDate { get; init; }
28+
2229
/// <summary>
2330
/// Feature IDs that should be hidden when rendering this bundle.
2431
/// Entries with matching feature-id values will be commented out in the output.

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ private static string RenderSingleBundle(
7979
};
8080

8181
var displayVersion = VersionOrDate.FormatDisplayVersion(bundle.Version);
82-
return GenerateMarkdown(displayVersion, titleSlug, bundle.Repo, bundle.Owner, entriesByType, subsections, hideLinks, typeFilter, publishBlocker, bundle.Data?.Description);
82+
return GenerateMarkdown(displayVersion, titleSlug, bundle.Repo, bundle.Owner, entriesByType, subsections, hideLinks, typeFilter, publishBlocker, bundle.Data?.Description, bundle.Data?.ReleaseDate);
8383
}
8484

8585
/// <summary>
@@ -153,7 +153,8 @@ private static string GenerateMarkdown(
153153
bool hideLinks,
154154
ChangelogTypeFilter typeFilter,
155155
PublishBlocker? publishBlocker,
156-
string? description = null)
156+
string? description = null,
157+
string? releaseDate = null)
157158
{
158159
var sb = new StringBuilder();
159160

@@ -177,6 +178,13 @@ private static string GenerateMarkdown(
177178

178179
_ = sb.AppendLine(CultureInfo.InvariantCulture, $"## {title}");
179180

181+
// Add release date if present
182+
if (!string.IsNullOrEmpty(releaseDate))
183+
{
184+
_ = sb.AppendLine();
185+
_ = sb.AppendLine(CultureInfo.InvariantCulture, $"_Released: {releaseDate}_");
186+
}
187+
180188
// Add description if present
181189
if (!string.IsNullOrEmpty(description))
182190
{

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@ public async Task RenderAsciidoc(ChangelogRenderContext context, Cancel ctx)
3232
_ = sb.AppendLine(InvariantCulture, $"== {context.Title}");
3333
_ = sb.AppendLine();
3434

35+
// Add release date if present
36+
if (!string.IsNullOrEmpty(context.BundleReleaseDate))
37+
{
38+
_ = sb.AppendLine(InvariantCulture, $"_Released: {context.BundleReleaseDate}_");
39+
_ = sb.AppendLine();
40+
}
41+
3542
// Add description if present
3643
if (!string.IsNullOrEmpty(context.BundleDescription))
3744
{

src/services/Elastic.Changelog/Rendering/ChangelogRenderContext.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,9 @@ public record ChangelogRenderContext
3030
/// Optional bundle-level introductory description. Only set when there's a single bundle with a description (MVP approach).
3131
/// </summary>
3232
public string? BundleDescription { get; init; }
33+
/// <summary>
34+
/// Optional release date for this bundle. Purely informative for end-users.
35+
/// Only set when there's a single bundle with a release date (MVP approach).
36+
/// </summary>
37+
public string? BundleReleaseDate { get; init; }
3338
}

src/services/Elastic.Changelog/Rendering/ChangelogRenderingService.cs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,26 @@ Cancel ctx
152152
renderDescription = bundleDescriptions[0];
153153
}
154154

155+
// Extract release dates from bundles for MVP support
156+
var bundleReleaseDates = validationResult.Bundles
157+
.Select(b => b.Data.ReleaseDate)
158+
.Where(d => !string.IsNullOrEmpty(d))
159+
.ToList();
160+
161+
string? renderReleaseDate = null;
162+
if (bundleReleaseDates.Count > 1)
163+
{
164+
collector.EmitWarning(string.Empty,
165+
$"Multiple bundles contain release dates ({bundleReleaseDates.Count} found). " +
166+
"Multi-bundle release date support is not yet implemented. Release dates will be skipped.");
167+
}
168+
else if (bundleReleaseDates.Count == 1)
169+
{
170+
renderReleaseDate = bundleReleaseDates[0];
171+
}
172+
155173
// Build render context
156-
var context = BuildRenderContext(input, outputSetup, resolvedResult, combinedHideFeatures, config, renderDescription);
174+
var context = BuildRenderContext(input, outputSetup, resolvedResult, combinedHideFeatures, config, renderDescription, renderReleaseDate);
157175

158176
// Validate entry types
159177
if (!ValidateEntryTypes(collector, resolvedResult.Entries, config.Types))
@@ -266,7 +284,8 @@ private static ChangelogRenderContext BuildRenderContext(
266284
ResolvedEntriesResult resolved,
267285
HashSet<string> featureIdsToHide,
268286
ChangelogConfiguration? config,
269-
string? description = null)
287+
string? description = null,
288+
string? releaseDate = null)
270289
{
271290
// Group entries by type
272291
var entriesByType = resolved.Entries
@@ -308,7 +327,8 @@ private static ChangelogRenderContext BuildRenderContext(
308327
EntryToOwner = entryToOwner,
309328
EntryToHideLinks = entryToHideLinks,
310329
Configuration = config,
311-
BundleDescription = description
330+
BundleDescription = description,
331+
BundleReleaseDate = releaseDate
312332
};
313333
}
314334

0 commit comments

Comments
 (0)