Bundle changelogs
You can use docs-builder changelog commands to created consolidated data files ("release bundles") that list all the notable changes associated with a particular release.
These files are ultimately used to generate release documentation.
This page describes how to create these files from the command line. For details about the equivalent GitHub action, refer to the docs-actions README.
- Create a changelog configuration file to define all the default behavior and optional profiles and rules. Refer to Configure changelogs.
- Create changelogs that describe all the notable changes. Refer to Create changelogs.
To have accurate release notes, there must be a definitive source of truth for what was shipped in each release. This is a superset of what will appear in the documentation.
The source of truth can be:
- a list of GitHub pull requests
- a list of GitHub issues
- a buildkite promotion report (which contains a list of PRs)
- automated release notes for GitHub releases
- all changelog files that exist in a specific folder
- all changelog files that match specific products, versions, and lifecycles
Deriving the source of truth from the contents of a folder or from the metadata in changelogs are the least accurate options (unless you have additional processes to confirm the validity of that information). It is recommended to use lists that are generated as part of your release coordination activities. Consider your options carefully and discuss with your docs team if necessary.
Not everything that was shipped will have a changelog. For example, you can configure rules that control changelog creation for work that's not publicly notable or spans multiple PRs.
Your release workflow should not assume there will be a one-to-one mapping between what was shipped and what will be documented.
The changelog bundle command has two modes of operation. You can:
- specify all the command options every time you run the command, or
- define "profiles" in the changelog configuration file
The latter method is more convenient and consistent for repetitive workflows, therefore it's the recommended method described here.
You must create profiles that match your chosen source of truth.
It is strongly recommended to set output_products in your profile so your bundles have a single top-level product entry that provides the context of the release. This context is particularly important if you'll be applying bundle rules.
For the most up-to-date changelog configuration options, refer to changelog.example.yml and Changelog configuration reference.
If the source of truth for what was shipped in each release is:
- a list of GitHub pull requests
- a list of GitHub issues
- a buildkite promotion report (which contains a list of PRs)
... your profile does not have any mandatory settings. However it's a good idea to define the basic bundle settings and the profile settings for the output filename and output products. For example:
bundle:
directory: docs/changelog
output_directory: docs/releases
repo: elasticsearch
owner: elastic
resolve: true
profiles:
serverless-report:
output: "serverless/{version}.yaml"
output_products: "cloud-serverless {version}"
elasticsearch-release:
output: "elasticsearch/{version}.yaml"
output_products: "elasticsearch {version} {lifecycle}"
- The directory that contains changelog files.
- The directory that contains changelog bundles.
- Resolve the changelog files in the bundle rather than just referencing them. Otherwise, when you move or remove changelog files the bundle cannot be rendered.
- If
outputis omitted, the default path and file names are used. This example shows how you can use a{version}variable to customize the bundle's filename. - The bundle's product metadata, which affects the rules that are applied and the product and version titles that ultimately appear in the documentation. If omitted, it's derived from all the changelogs in the bundle.
If you have automated GitHub release notes, the changelog bundle command can fetch the release from GitHub, parse PR references from the release notes, and uses them as the bundle filter.
Only automated GitHub release notes (the default format or Release Drafter format) are supported at this time.
Your profile must contain source: github_release.
It's also a good idea to include the basic bundle settings and the profile settings for the output filename and output products.
For example:
bundle:
resolve: true
profiles:
agent-gh-release:
source: github_release
repo: apm-agent-dotnet
owner: elastic
output: "agent-{version}.yaml"
output_products: "apm-agent-dotnet {version} {lifecycle}"
- This profile fetches the PR list from the GitHub release notes for the version tag specified in the command.
- For
source: github_releaseprofiles, the{lifecycle}placeholder inoutputandoutput_productsis inferred from full release tag name. For example, if the release tag isv1.34.1-preview.1the lifecycle ispreview. Refer to changelog bundle cli command > Lifecycle inference for more details.
If the source of truth for what was shipped in each release is:
- the
productsinformation that exists in each changelog - all changelog files that exist in a specific folder
... you must include products in your profile.
For example:
bundle:
directory: docs/changelog
output_directory: docs/releases
resolve: true
repo: elasticsearch
owner: elastic
profiles:
# Collect all changelogs
release-all:
products: "* * *"
output: "all.yaml"
# Find changelogs with any lifecycle and a partial date
serverless-monthly:
products: "cloud-serverless {version}-* *"
output: "serverless-{version}.yaml"
output_products: "cloud-serverless {version}"
# Find changelogs with a specific lifecycle
elasticsearch-ga-only:
products: "elasticsearch {version} ga"
output: "elasticsearch-{version}.yaml"
# Infer the lifecycle from the version
elasticsearch-with-lifecycle:
products: "elasticsearch {version} {lifecycle}"
output: "elasticsearch-{version}.yaml"
output_products: "elasticsearch {version}"
- This profile collects all changelogs from the
directory. - This profile collects any changelogs that have
product: cloud-serverless, any lifecycle, and the date partially specified in the command. - This profile collects any changelogs that have
product: elasticsearch,lifecycle: ga, and the version specified in the command. - In this case, the lifecycle is inferred from the version specified in the command. For example, if the version is
9.2.0-beta.1the lifecycle isbeta. Refer to changelog bundle cli command > Lifecycle inference.
The products field determines which changelog files are gathered for consideration. You can still apply rules afterward to further filter changelogs from the bundle. The input stage and bundle filtering stage are conceptually separate.
If you created profiles, you can use them with the changelog bundle command like this:
docs-builder changelog bundle <profile> <version|report|url-list>
The second argument accepts a version string, a promotion report URL or path, or a URL list file (a plain-text file with one fully-qualified GitHub URL per line).
If you are using a {version} placeholder in the output_products or output fields, you must provide that value as well as your report or URL argument.
For example, if the source of truth for what was shipped in each release is:
a list of GitHub pull requests or issues:
# Bundle changelogs from a PR list ({lifecycle} → "ga" inferred from "9.2.0") docs-builder changelog bundle elasticsearch-release 9.2.0 ./prs.txt... where
prs.txtis a newline delimited file with PR or issue URLs like this this:https://github.com/elastic/kibana/pull/123 https://github.com/elastic/kibana/pull/456
| Field | Description |
|---|---|
repo |
Default GitHub repository name applied to all profiles. Falls back to product ID if not set at any level. |
owner |
Default GitHub repository owner applied to all profiles. |
resolve |
When true, embeds full changelog entry content in the bundle (same as --resolve). Required when link_allow_repos is set. |
link_allow_repos |
When set (including an empty list), only PR/issue links whose resolved repository is in this owner/repo list are kept; others are rewritten to # PRIVATE: sentinels in bundle YAML. When absent, no link filtering is applied. Requires resolve: true. Refer to PR and issue link allowlist. |
# Bundle changelogs from a buildkite report ({version} → "2026-02-13")
docs-builder changelog bundle serverless-report 2026-02-13 ./promotion-report.html
automated release notes for GitHub releases:
# Bundle changelogs from the release notes of a specific GitHub tag docs-builder changelog bundle agent-gh-release v1.34.1 # Use "latest" to fetch the most recent release docs-builder changelog bundle agent-gh-release latestAlternatively, use the changelog gh-release command, which creates the changelogs and bundles at the same time.
NoteThis method requires a
GITHUB_TOKENorGH_TOKENenvironment variable (or an activeghlogin) to fetch release details from the GitHub API.all changelog files that exist in a specific folder:
docs-builder changelog bundle release-all '*'all changelog files that match specific products, versions, and lifecycles:
# Bundle changelogs with partial dates docs-builder changelog bundle serverless-monthly 2026-02 # Bundle changelogs for a GA release ({lifecycle} → "ga" inferred from "9.2.0") docs-builder changelog bundle elasticsearch-with-lifecycle 9.2.0 # Bundle changelogs for a beta release ({lifecycle} → "beta" inferred from "9.2.0-beta.1") docs-builder changelog bundle elasticsearch-with-lifecycle 9.2.0-beta.1
By default all changelogs that match the chosen source of truth are included in the bundle.
It is strongly recommended to pull all of the content from each changelog into the bundle; otherwise you can't move or remove your changelogs. If your bundle contains only references to the files, add set bundle.resolve to true and re-generate your bundle.
To apply additional filtering by the changelog type, areas, or products, add bundle rules.
- Include all changelogs that have the
cloud-serverlessproduct identifier with target dates of either December 2 2025 (lifecyclega) or December 6 2025 (lifecyclebeta). For more information about product values, refer to Product format.
You can use wildcards in any of the three parts:
# Bundle any changelogs that have exact matches for either of these clauses
docs-builder changelog bundle --input-products "cloud-serverless 2025-12-02 ga, elasticsearch 9.3.0 beta"
# Bundle all elasticsearch changelogs regardless of target or lifecycle
docs-builder changelog bundle --input-products "elasticsearch * *"
# Bundle all cloud-serverless 2025-12-02 changelogs with any lifecycle
docs-builder changelog bundle --input-products "cloud-serverless 2025-12-02 *"
# Bundle any cloud-serverless changelogs with target starting with "2025-11-" and "ga" lifecycle
docs-builder changelog bundle --input-products "cloud-serverless 2025-11-* ga"
# Bundle all changelogs (equivalent to --all)
docs-builder changelog bundle --input-products "* * *"
If you have changelog files that reference those product details, the command creates a file like this:
products:
- product: cloud-serverless
target: 2025-12-02
- product: cloud-serverless
target: 2025-12-06
entries:
- file:
name: 1765495972-fixes-enrich-and-lookup-join-resolution-based-on-m.yaml
checksum: 6c3243f56279b1797b5dfff6c02ebf90b9658464
- file:
name: 1765507778-break-on-fielddata-when-building-global-ordinals.yaml
checksum: 70d197d96752c05b6595edffe6fe3ba3d055c845
- By default these values match your
--input-products(even if the changelogs have more products). To specify different product metadata, use the--output-productsoption.
You can use the --prs option to create a bundle of the changelogs that relate to those pull requests.
You can provide either a comma-separated list of PRs (--prs "https://github.com/owner/repo/pull/123,12345") or a path to a newline-delimited file (--prs /path/to/file.txt).
In the latter case, the file should contain one PR URL or number per line.
Pull requests can be identified by a full URL (such as https://github.com/owner/repo/pull/123), a short format (such as owner/repo#123), or just a number (in which case you must also provide --owner and --repo options).
docs-builder changelog bundle --prs "108875,135873,136886" \
--repo elasticsearch \
--owner elastic \
--output-products "elasticsearch 9.2.2 ga"
- The comma-separated list of pull request numbers to seek.
- The repository in the pull request URLs. Not required when using full PR URLs, or when
bundle.repois set in the changelog configuration. - The owner in the pull request URLs. Not required when using full PR URLs, or when
bundle.owneris set in the changelog configuration. - The product metadata for the bundle. If it is not provided, it will be derived from all the changelog product values.
In Mode 3, the rule context product is the first alphabetically from --output-products (or from aggregated changelog products if omitted). To apply a different product's per-product rules, use a bundle whose output_products contains only that product (separate command or profile).
If you have changelog files that reference those pull requests, the command creates a file like this:
products:
- product: elasticsearch
target: 9.2.2
lifecycle: ga
entries:
- file:
name: 1765507819-fix-ml-calendar-event-update-scalability-issues.yaml
checksum: 069b59edb14594e0bc3b70365e81626bde730ab7
- file:
name: 1765507798-convert-bytestransportresponse-when-proxying-respo.yaml
checksum: c6dbd4730bf34dbbc877c16c042e6578dd108b62
- file:
name: 1765507839-use-ivf_pq-for-gpu-index-build-for-large-datasets.yaml
checksum: 451d60283fe5df426f023e824339f82c2900311e
You can use the --issues option to create a bundle of changelogs that relate to those GitHub issues.
Provide either a comma-separated list of issues (--issues "https://github.com/owner/repo/issues/123,456") or a path to a newline-delimited file (--issues /path/to/file.txt).
Issues can be identified by a full URL (such as https://github.com/owner/repo/issues/123), a short format (such as owner/repo#123), or just a number (in which case --owner and --repo are required — or set via bundle.owner and bundle.repo in the configuration).
docs-builder changelog bundle --issues "12345,12346" \
--repo elasticsearch \
--owner elastic \
--output-products "elasticsearch 9.2.2 ga"
If you have a file that lists pull requests (such as PRs associated with a GitHub release), you can pass it to --prs.
For example, if you have a file that contains full pull request URLs like this:
https://github.com/elastic/elasticsearch/pull/108875
https://github.com/elastic/elasticsearch/pull/135873
https://github.com/elastic/elasticsearch/pull/136886
https://github.com/elastic/elasticsearch/pull/137126
You can use the --prs option with the file path to create a bundle of the changelogs that relate to those pull requests.
You can also combine multiple --prs options:
./docs-builder changelog bundle \
--prs "https://github.com/elastic/elasticsearch/pull/108875,135873" \
--prs test/9.2.2.txt \
--output-products "elasticsearch 9.2.2 ga"
--resolve
- Comma-separated list of pull request URLs or numbers.
- The path for the file that lists the pull requests. If the file contains only PR numbers, you must add
--repoand--ownercommand options. - The product metadata for the bundle. If it is not provided, it will be derived from all the changelog product values.
- Optionally include the contents of each changelog in the output file.
You can use these files with profile-based bundling too. Refer to changelog bundle cli command.
If you have changelog files that reference those pull requests, the command creates a file like this:
products:
- product: elasticsearch
target: 9.2.2
lifecycle: ga
entries:
- file:
name: 1765507778-break-on-fielddata-when-building-global-ordinals.yaml
checksum: 70d197d96752c05b6595edffe6fe3ba3d055c845
type: bug-fix
title: Break on FieldData when building global ordinals
products:
- product: elasticsearch
areas:
- Aggregations
prs:
- https://github.com/elastic/elasticsearch/pull/108875
...
When a changelog matches multiple --input-products filters, it appears only once in the bundle. This deduplication applies even when using --all or --prs.
If you have GitHub releases with automated release notes (the default format or Release Drafter format), you can use the --release-version option to derive the PR list from those release notes.
For example:
docs-builder changelog bundle \
--release-version v1.34.0 \
--repo apm-agent-dotnet --owner elastic
- The repo and repo owner are used to fetch the release and follow these rules of precedence:
- Repo:
--repoflag >bundle.repoinchangelog.yml(one source is required) - Owner:
--ownerflag >bundle.ownerinchangelog.yml>elastic
This command creates a bundle of changelogs that match the list of PRs found in the v1.34.0 GitHub release notes.
The bundle's product metadata is inferred automatically from the release tag and repository name; you can override that behavior with the --output-products option.
If you are not creating changelogs when you create your pull requests, consider the docs-builder changelog gh-release command as a one-shot alternative to the changelog add and changelog bundle commands.
It parses the release notes, creates one changelog file per pull request found, and creates a changelog-bundle.yaml file — all in a single step. Refer to changelog gh-release cli command
You can use the --hide-features option to embed feature IDs that should be hidden when the bundle is rendered. This is useful for features that are not yet ready for public documentation.
docs-builder changelog bundle \
--input-products "elasticsearch 9.3.0 *" \
--hide-features "feature:hidden-api,feature:experimental" \
--output /path/to/bundles/9.3.0.yaml
- Feature IDs to hide. Changelogs with matching
feature-idvalues will be commented out when rendered.
The bundle output will include a hide-features field:
products:
- product: elasticsearch
target: 9.3.0
hide-features:
- feature:hidden-api
- feature:experimental
entries:
- file:
name: 1765495972-new-feature.yaml
checksum: 6c3243f56279b1797b5dfff6c02ebf90b9658464
When this bundle is rendered (either via the changelog render command or the {changelog} directive), changelogs with feature-id values matching any of the listed features will be commented out in the output.
The --hide-features option on the render command and the hide-features field in bundles are combined. If you specify --hide-features on both the bundle and render commands, all specified features are hidden. The {changelog} directive automatically reads hide-features from all loaded bundles and applies them.
A changelog can reference multiple pull requests and issues in the prs and issues array fields.
To comment out links that are not in your allowlist in all changelogs in your bundles, refer to changelog bundle.
If you are working in a private repo and do not want any pull request or issue links to appear (even if they target a public repo), you also have the option to configure link visibiblity in the changelog directive and changelog render command.
You must run the docs-builder changelog bundle command with the --resolve option or set bundle.resolve to true in the changelog configuration file (so that bundle files are self-contained) in order to hide the private links.
When you need to add changelogs to an existing bundle, you can use the docs-builder changelog bundle-amend command, which creates amend bundles.
For example:
docs-builder changelog bundle-amend \
./docs/releases/9.3.0.yaml \
--add "./docs/changelog/138723.yaml,./docs/changelog/1770424335.yaml"
Amend bundles follow a specific naming convention: {parent-bundle-name}.amend-{N}.yaml where {N} is a sequence number.
There is currently no command to remove changelogs from a bundle. You must edit the bundle file manually or else re-generate the bundle with an updated source of truth or a new rule that excludes the changelog.
When bundles are turned into docs (either via the changelog render command or the {changelog} directive), amend files are automatically merged with their parent bundles.
The changelogs from all matching amend files are combined with the parent bundle's changelogs and the result is rendered as a single release.
Don't explicitly list the amend bundles in the --input option of the docs-builder changelog render command--you'll get duplicate entries in the output files. List only the original/parent bundles.
For more details and examples, go to changelog bundle-amend cli command.
A single changelog file might be applicable to multiple releases (for example, it might be delivered in both Stack and Serverless releases or Elastic Cloud Hosted and Enterprise releases on different timelines). After it has been included in all of the relevant bundles, it is reasonable to delete the changelog to keep your repository clean.
If you create docs with changelog directives, run the docs-builder changelog bundle command with the --resolve option or set bundle.resolve to true in the changelog configuration file (so that bundle files are self-contained).
Otherwise, the build will fail if you remove changelogs that the directive requires.
Likewise, the docs-builder changelog render command fails for "unresolved" bundles after you delete the changelogs.
You can use the docs-builder changelog remove command to remove changelogs.
If you created profiles, you can use them like this:
docs-builder changelog remove <profile> <version|report|url-list>
For example, if the source of truth for what was shipped in each release is:
a list of GitHub pull requests or issues:
docs-builder changelog remove elasticsearch-release ./prs.txta buildkite promotion report:
docs-builder changelog remove serverless-report ./promotion-report.htmlautomated release notes for GitHub releases:
docs-builder changelog remove agent-gh-release 1.34.1NoteThis method requires a
GITHUB_TOKENorGH_TOKENenvironment variable (or an activeghlogin) to fetch release details from the GitHub API.all changelog files that exist in a specific folder:
docs-builder changelog remove release-all '*'all changelog files that match specific products, versions, and lifecycles:
docs-builder changelog remove serverless-monthly 2026-02
Before deleting, the command automatically scans for bundles that still hold unresolved (file:) references to the matching changelog files.
If any are found, the command reports an error for each dependency.
This check prevents the {changelog} directive from failing at build time with missing file errors.
To proceed with removal even when unresolved bundle dependencies exist, use --force.
To preview what would be removed without deleting anything, use --dry-run.
For full option details, go to changelog remove cli command.
The following sections provide more details about optional and advanced steps.
Not everything that was shipped in a release and has a changelog necessarily belongs in the release bundle.
If you want to automatically include or exclude changelogs from bundles based on their areas, types, or products, you can accomplish this with rules in your changelog configuration file. Bundle rules run as a secondary stage after the candidate changelogs are collected (for example, based on a PR list, promotion report, or other valid source of truth).
For example, you might choose to omit other or docs types of changelogs.
Or you might choose to omit all changelogs related to specific features (areas) from a product's release bundles.
You can define rules at the global level (applies to all products) like this:
rules:
bundle:
exclude_products: elasticsearch
exclude_types: deprecation
exclude_areas:
- Internal
Alternatively, you can define product-specific rules:
rules:
bundle:
products:
cloud-serverless:
include_areas:
- "Search"
- "Monitoring"
elasticsearch:
exclude_areas:
- Autoscaling
Product-specific rules override the global rules entirely—they do not merge. For details, refer to Changelog configuration reference > rules.bundle and Changelog configuration reference > Advanced rule examples.
Changelogs have an optional feature-id field that you can use to associate the change with a specific feature or project.
If there are features or projects that are not yet ready for public documentation, you can list those IDs in the hide_features setting:
bundle:
directory: docs/changelog
output_directory: docs/releases
repo: elasticsearch
owner: elastic
resolve: true
profiles:
serverless-report:
output: "serverless/{version}.yaml"
output_products: "cloud-serverless {version}"
hide_features:
- feature-flag-1
- feature-flag-2
- The feature identifiers to hide.
When you use this profile to create a bundle, the list is carried forward into its metadata.
Any changelogs with matching feature-id values are commented out when you publish the bundle.
A changelog can reference multiple pull requests and issues in its prs and issues fields.
You can allowlist links to certain repos with the link_allow_repos setting:
bundle:
directory: docs/changelog
output_directory: docs/releases
repo: elasticsearch
owner: elastic
resolve: true
link_allow_repos:
- elastic/elasticsearch
- elastic/kibana
- elastic/roadmap
- Only links to these owner/repo pairs are shown in the release docs. Others are rewritten to
# PRIVATE:sentinels.
There are no implicit values for this setting. You must list every repo whose links should appear, including the current repo. When this setting is omitted entirely, no link filtering is applied. For more details, refer to PR and issue link allowlist.
You must set bundle.resolve to true in the changelog configuration file (so that bundle files are self-contained) in order to hide the private links. The bundle's changelog entries are sanitized but the individual changelog files are unchanged.
If you are working in a private repo and do not want any pull request or issue links to appear (even if they target a public repo), you can also configure link visibility in the changelog directive and changelog render command.
After you've created release bundles, you can use them to generate release docs.