Skip to content

Conversation

@lcawl
Copy link
Contributor

@lcawl lcawl commented Dec 2, 2025

This PR adds a docs-builder command that generates a changelog YAML file.

It is derived from the "elastic-agent-changelog-tool new a-changeset-filename" workflow in https://github.com/elastic/elastic-agent-changelog-tool

For example:

./docs-builder release-notes create --pr https://github.com/elastic/elasticsearch/pull/130027 --title "Fixes prevent duplication of \"invalid index name\" string in the final exception error message"  --type bug-fix --products "elasticsearch 9.2.0 beta, cloud-serverless 2025-11-11 ga" --area "ES|QL"

That command creates a file named 1764714171-fixes-prevent-duplication-of-invalid-index-name-st.yaml that contains:

id: 182558445
pr: https://github.com/elastic/elasticsearch/pull/130027
type: bug-fix
products:
- product: elasticsearch
  target: 9.2.0
  lifecycle: beta
- product: cloud-serverless
  target: 2025-11-11
  lifecycle: ga
areas:
- ES|QL
title: Fixes prevent duplication of "invalid index name" string in the final exception error message

Everything is currently specified on the command line, with only three required options (title, type, and product):

Create a new release notes changelog fragment from command-line input

Options:
  --title <string>                  Required: A short, user-facing title (max 80 characters) (Required)
  --type <string>                   Required: Type of change (feature, enhancement, bug-fix, breaking-change, etc.) (Required)
  --products <List<ProductInfo>>    Required: Products affected in format "product target lifecycle, ..." (e.g., "elasticsearch 9.2.0 ga, cloud-serverless 2025-08-05") (Required)
  --subtype <string?>               Optional: Subtype for breaking changes (api, behavioral, configuration, etc.) (Default: null)
  --area <string[]?>                Optional: Area(s) affected (comma-separated or specify multiple times) (Default: null)
  --pr <string?>                    Optional: Pull request URL (Default: null)
  --issues <string[]?>              Optional: Issue URL(s) (comma-separated or specify multiple times) (Default: null)
  --description <string?>           Optional: Additional information about the change (max 600 characters) (Default: null)
  --impact <string?>                Optional: How the user's environment is affected (Default: null)
  --action <string?>                Optional: What users must do to mitigate (Default: null)
  --feature-id <string?>            Optional: Feature flag ID (Default: null)
  --highlight <bool?>               Optional: Include in release highlights (Default: null)
  --id <int?>                       Optional: Custom ID (auto-generated if not provided) (Default: null)
  --output <string?>                Optional: Output directory for the changelog fragment. Defaults to current directory (Default: null)

Error handing

If you provide a value that doesn't match the schema, you get a warning but the changelog is still created.
For example:

./docs-builder release-notes create --title "Test" --products "kibana" --type blah
...
warn ::d.b.d.Log             :: Type 'blah' is not in the list of available types. Available types: feature, enhancement, bug-fix, known-issue, breaking-change, deprecation, docs, regression, security, other
info ::e.d.s.easeNotesService:: Created release notes fragment: /Users/lcawley/Documents/GitHub/docs-builder/.artifacts/publish/docs-builder/release/1764714423-test.yaml

	The following errors and warnings were found in the documentation

Warning: Type 'blah' is not in the list of available types. Available types: feature, enhancement, bug-fix, known-issue, breaking-change, deprecation, docs, regression, security, other

Perhaps that ought to be an error instead of a warning and block the creation of the changelog file, but for now I'll leave as a non-blocking warning.

Next steps

  • If we want to have even fewer required options, we could follow elastic-agent-changelog-tool new and require only a filename (per https://github.com/elastic/elastic-agent-changelog-tool/blob/main/docs/usage.md#adding-a-changelog-fragment). However, we'd want to add validation that the minimal information exists before a changelog is merged.
  • We will likely want to have a --config <path> command option in case teams want to store the config file in different locations per repo. Currently, the command looks for it in a specific location: warn ::e.d.s.easeNotesService:: Release notes configuration not found at ...GitHub/docs-builder/.artifacts/publish/docs-builder/release/config/release-notes.yml, using defaults.
  • Ultimately the command ought to be able to get information from a pull request to fill in parts of the changelog (i.e. for the use case where the command is being run automatically to add a changelog to an open PR).
    That was the intention behind having a label mapping configuration file.

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-1 agent

Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
@lcawl lcawl marked this pull request as ready for review December 2, 2025 22:31
@lcawl lcawl requested review from a team as code owners December 2, 2025 22:31
@lcawl lcawl requested a review from reakaleek December 2, 2025 22:31
Copy link
Member

@reakaleek reakaleek left a comment

Choose a reason for hiding this comment

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

wow. thank you for the contribution.

app.Add<ServeCommand>("serve");
app.Add<IndexCommand>("index");
app.Add<FormatCommand>("format");
app.Add<ReleaseNotesCommand>("release-notes");
Copy link
Member

Choose a reason for hiding this comment

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

Nit: I think we should adjust the naming a bit.

From my understanding this is a single entry within release notes. Right now, it could confuse users to think it already creates the full release notes.

I don't know what would be a good terminology. I know the term "Changeset" for a single unit. But I'm also not sure if this is the most fitting in our case.

Copy link
Member

Choose a reason for hiding this comment

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

I initially proposed to have all release-notes commands under release-notes

docs-builder release-notes create

I am not opposed to split it into

docs-builder changelog add

That way release-notes commands operate over N changelog entries.

Where changelog is used for single changelog commands (which most people will use).

changelog matches the proposed docs/changelog location (already in use by elastic/elasticsearch).

# Maps PR labels to "product" field
# Add mappings for your products, e.g.:
product:
product:elasticsearch: elasticsearch
Copy link
Member

Choose a reason for hiding this comment

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

Does this syntax actually work?

I imagine yaml parsers could get confused by multiple colons (:) in a single line.

var yaml = serializer.Serialize(data);

// Add schema comments
var sb = new StringBuilder();
Copy link
Member

Choose a reason for hiding this comment

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

I think it would be nice for maintainability if this was a template.

Maybe for now it's just enough to use a raw string literal.

https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-11.0/raw-string-literal

@reakaleek
Copy link
Member

Another thing that would be nice.. but probably as a follow-up is somehthing like an interactive form.

If you don't provide all the args, the CLI asks you. Similar to (gh cli)

/// </summary>
/// <param name="title">Required: A short, user-facing title (max 80 characters)</param>
/// <param name="type">Required: Type of change (feature, enhancement, bug-fix, breaking-change, etc.)</param>
/// <param name="products">Required: Products affected in format "product target lifecycle, ..." (e.g., "elasticsearch 9.2.0 ga, cloud-serverless 2025-08-05")</param>
Copy link
Member

@reakaleek reakaleek Dec 3, 2025

Choose a reason for hiding this comment

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

I wonder if applies_to could be the base for it.
Not sure if we can align the syntax. (Also applies_to must be extended to also support dates)

I guess we cannot do this now.. but aligning this in the future could be nice.

I definitely see a connection.

Copy link
Member

Choose a reason for hiding this comment

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

++ I don't think we need to put dates any longer.

Since in our proposal we would discover what serverless release these go out.

@@ -0,0 +1,92 @@
# Release Notes Configuration
Copy link
Member

Choose a reason for hiding this comment

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

This file should live in docs/changelog.yml

}

// Generate unique ID if not provided
var id = input.Id ?? GenerateUniqueId(input.Title, input.Pr ?? string.Empty);
Copy link
Member

Choose a reason for hiding this comment

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

We don't need id's, the pr-filename.yml is the id.

/// <param name="products">Required: Products affected in format "product target lifecycle, ..." (e.g., "elasticsearch 9.2.0 ga, cloud-serverless 2025-08-05")</param>
/// <param name="subtype">Optional: Subtype for breaking changes (api, behavioral, configuration, etc.)</param>
/// <param name="area">Optional: Area(s) affected (comma-separated or specify multiple times)</param>
/// <param name="pr">Optional: Pull request URL</param>
Copy link
Member

Choose a reason for hiding this comment

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

This can just be the pull request number (we can get the github url from our configuration.Git

Copy link
Member

@Mpdreamz Mpdreamz left a comment

Choose a reason for hiding this comment

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

Few changes but overall looks good 😍

It'd be nice if we can follow up with this with an interactive mode like gh pr create.

EDIT: @reakaleek already mentioned that :)

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.

4 participants