Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion config/changelog.example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -234,11 +234,15 @@ bundle:
# Used by the {changelog} directive to generate correct PR/issue links when the product ID
# differs from the GitHub repository name. Can be overridden per profile.
# repo: elasticsearch
# Optional: default GitHub owner applied to all profiles that do not specify their own.
# Optional: default GitHub owner applied to all profiles that do not specify their own. Can be overridden per profile.
# owner: elastic
# Optional: branch whose CDN changelog pool (changelog/{org}/{repo}/{branch}/...) is sourced from when
# bundling entries from the CDN. Defaults to "main" when unset. Can be overridden per profile.
# branch: main
# Optional: source changelog entries from the local directory instead of the public CDN.
# Default (false)
# Set to true only when you need local-only bundling (or use --force-local)
# use_local_changelogs: true
# Optional: control auto-population of release-date for all profiles by default.
# When true (default), auto-populate release dates. Profiles can override this setting.
# release_dates: true
Expand Down
33 changes: 21 additions & 12 deletions docs/cli/changelog/cmd-bundle.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ docs-builder changelog bundle elasticsearch-release 9.2.0 ./promotion-report.htm
```

The second positional argument accepts:

- A version string (e.g. `9.2.0`, `9.2.0-beta.1`) — lifecycle is inferred automatically (`ga`, `beta`, `rc`)
- A promotion report URL or file path
- A plain-text URL list file (one fully-qualified GitHub PR or issue URL per line)
Expand Down Expand Up @@ -147,6 +148,26 @@ Set `bundle.link_allow_repos` in `changelog.yml` to an explicit list of `owner/r
`bundle.link_allow_repos` requires a **resolved** bundle. Set `bundle.resolve: true` or pass `--resolve`.
:::

## Entry sourcing [changelog-bundle-entry-sourcing]

You can choose to pull changelog files from the local folder or from the public CDN.

Files in the local folder are used when:

- `bundle.use_local_changelogs` is set to `true` in the changelog configuration file,
- the `--force-local`, `--files`, or `--directory` command options are used,
- a path-list file is used with profile-based `changelog bundle` commands, or
- the repo cannot be determined (`bundle.repo` is not set and `--repo` is not specified)

Files in the public CDN are used when the repo is known (`bundle.repo` is set in the changelog configuration file or the `--repo` command option is used) and local sourcing is not forced.

:::{note}
The public CDN (CloudFront) caches changelog entry YAML and the entry `registry.json` with a default "time to live" (TTL) of about one hour (minimum 60 seconds).
After you upload or edit entries, the copy in the private S3 bucket can be newer than what `changelog bundle` downloads from the CDN.
If you rely on CDN sourcing, wait at least an hour after last-minute changelog updates before bundling.
Alternatively, if changelogs are also stored in the repo, you can force local entry sourcing so the command reads files locally instead.
:::

## Examples

### Bundle by GitHub release [changelog-bundle-release-version]
Expand Down Expand Up @@ -352,18 +373,6 @@ docs-builder changelog bundle serverless-release 2026-07-07 ./docs/temp/changelo

`--files` / path-list selection always reads the named files from disk (local entry sourcing). It does not fetch entries from the CDN. `rules.bundle` still applies after selection.

### Force local entry sourcing [changelog-bundle-force-local]

When a repository defaults to CDN entry sourcing, you can use `--force-local` to read changelog YAML files from the local folder.
This option overrides the `bundle.use_local_changelogs` setting in your `changelog.yml` and is useful for ad hoc bundles that include freshly authored local files that are not on the CDN yet.

```sh
docs-builder changelog bundle serverless-release 2026-07-07 ./docs/temp/prs.txt --force-local
```

`--force-local` is allowed in both option-based and profile-based commands.
Path-list / `--files` filters already force local sourcing, so `--force-local` is optional in that case.

### Hide features [changelog-bundle-hide-features]

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.
Expand Down
12 changes: 12 additions & 0 deletions docs/contribute/bundle-changelogs.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,18 @@ For example, you can configure [rules](/contribute/create-changelogs.md#rules) t
Your release workflow should not assume there will be a one-to-one mapping between what was shipped and what will be documented.
:::

## Identify where to find changelogs

As noted in the [changelog creation step](/contribute/create-changelogs.md#prerequisites), you can store your changelog files in both the public CDN and your GitHub repository.

By default, when you create a bundle the commands and GitHub actions pull the changelogs from the public CDN.

If you're making last-minute changes and ad hoc releases with changelog files that aren't uploaded to the public CDN yet, pass the `--force-local` command option to `changelog bundle`.

If you rely on CDN sourcing, wait at least an hour after your final changelog updates before you create the bundle.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

why is this an hour @cotti ?


For more details, refer to [Entry sourcing](/cli/changelog/bundle.md#changelog-bundle-entry-sourcing).

## Create profiles

The [changelog bundle](/cli/changelog/bundle.md) command has two modes of operation.
Expand Down
24 changes: 6 additions & 18 deletions docs/contribute/configure-changelogs-ref.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,15 @@ These settings are relevant to one or all of the `changelog bundle`, `changelog

| Setting | Description |
| ------------------------- | ----------- |
| `bundle.branch` | Branch whose CDN changelog pool (`changelog/{org}/{repo}/{branch}/...`) entries are sourced from when bundling (default: `main`). Refer to [Entry sourcing](#bundle-entry-sourcing). |
| `bundle.branch` | Branch whose CDN changelog pool (`changelog/{org}/{repo}/{branch}/...`) entries are sourced from when bundling (default: `main`). Refer to [Entry sourcing](/cli/changelog/bundle.md#changelog-bundle-entry-sourcing). |
| `bundle.directory` | Input directory containing changelog YAML files (default: `docs/changelog`). |
| `bundle.link_allow_repos` | List of `owner/repo` pairs whose PR/issue links are preserved. When set (including empty `[]`), links to unlisted repos become `# PRIVATE:` sentinels. Requires `bundle.resolve: true` |
| `bundle.output_directory` | Output directory for bundled files (default: `docs/releases`). |
| `bundle.owner` | Default GitHub repository owner (for example, `elastic`). Also the org segment of uploaded changelog-entry keys (`changelog/{org}/{repo}/{branch}/...`) and CDN entry sourcing. |
| `bundle.release_dates` | When `true`, bundles include a `release-date` field (default: true). |
| `bundle.repo` | Default GitHub repository name (for example, `elasticsearch`). Used by the `{changelog}` directive to generate correct PR and issue links, and to scope uploaded changelog-entry keys (`changelog/{org}/{repo}/{branch}/...`) and CDN entry sourcing. Only needed when the product ID doesn't match the GitHub repository name (or to override the git remote). |
| `bundle.repo` | Default GitHub repository name (for example, `elasticsearch`). Used by the `{changelog}` directive to generate correct PR and issue links, to scope uploaded changelog file locations (`changelog/{org}/{repo}/{branch}/...`), and for CDN entry sourcing when bundling. Only needed when the product ID doesn't match the GitHub repository name. Refer to [Entry sourcing](/cli/changelog/bundle.md#changelog-bundle-entry-sourcing). |
| `bundle.resolve` | When `true`, changelog contents are copied into bundle (default: `true`). |
| `bundle.use_local_changelogs` | When `true`, always source entries from the local folder and never from the CDN (default: `false`). Refer to [Entry sourcing](#bundle-entry-sourcing). |
| `bundle.use_local_changelogs` | When `true`, always source entries from the local folder and never from the CDN (default: `false`). Refer to [Entry sourcing](/cli/changelog/bundle.md#changelog-bundle-entry-sourcing). |

:::

Expand All @@ -65,21 +65,6 @@ When `bundle.link_allow_repos` is omitted, no link filtering occurs.
- For public repos, add your `owner/repo` to the list at a minimum.
:::

### Entry sourcing [bundle-entry-sourcing]

`changelog bundle` reads the individual changelog entries it aggregates either from the local folder or from the public CDN. Entries are stored on the CDN per **authoring org/repo/branch** (`changelog/{org}/{repo}/{branch}/...`), not per product, so CDN sourcing keys off the resolvable authoring org/repo/branch rather than the bundle's target products.

The authoring repo is resolved with the same precedence as `changelog upload`: `--repo` > `bundle.repo` in `changelog.yml` > the git remote origin. The owner is resolved from `--owner` > `bundle.owner` (default `elastic`), and the branch from `--branch` > `bundle.branch` (default `main`).

Sourcing is decided per run:

- **Local folder.** Used when `bundle.use_local_changelogs: true`, when `--force-local` is passed, when `--files` / a path-list filter is used, when `--directory` is passed, or when the authoring repo cannot be resolved. The folder must contain the changelog files.
- **CDN (default when a repo resolves).** Used when the authoring repo resolves, local sourcing is not forced, and a CDN base URL is configured (`DOCS_BUILDER_CHANGELOG_CDN`, defaulting to the public distribution). The command fetches `changelog/{org}/{repo}/{branch}/registry.json` and the entries it lists, then applies the bundle's own product/PR/issue filters to the downloaded set.

Use `--force-local` for uncommon ad hoc runs that need the local folder without editing `changelog.yml`. Path-list / `--files` filters always force local sourcing because they select files by path on disk.

Because entries are org/repo/branch-scoped, one repository can produce a bundle for a shared product (for example, `cloud-serverless`) while sourcing its own entries from `changelog/{org}/{repo}/{branch}/`, without that product appearing in the repository's `docset.yml`. The `{changelog}` directive's `:cdn:` mode still consumes product-scoped *bundles*, so a repository that also renders its own release notes declares each product under `release_notes` as before.

### Bundle descriptions [bundle-descriptions]

You can add introductory text to bundles using the `description` field. This text appears at the top of rendered changelogs, after the release heading but before the entry sections.
Expand Down Expand Up @@ -117,6 +102,9 @@ They work with both `changelog bundle` and `changelog remove` commands.

These settings are located in the `bundle.profiles.<name>` section of the configuration file:

`branch`:
: Overrides the global [bundle.branch](#bundle-basic).

`description`
: Overrides the global [bundle.description](#bundle-descriptions).

Expand Down
26 changes: 25 additions & 1 deletion docs/contribute/create-changelogs.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,16 @@ These files are ultimately used to generate release documentation.

This page describes how to create these files both from the [command line](#command-line) and from [GitHub actions](#github-actions).

## Before you begin
## Before you begin [prerequisites]

Create a changelog configuration file to define all the default behavior and PR label mappings.
Refer to [](/contribute/configure-changelogs.md).

Choose whether you want to store the changelogs only in the public CDN or in both your GitHub repository and the CDN:

- If you have a large volume of notable changes every release, you will likely choose to store them *only* in the public CDN.
- If you have a small volume of changes or the content churns a lot before and after releases, you will likely choose to store them in *both* the repo and the public CDN.

## Create changelog files from command line [command-line]

These steps describe how to use the [changelog add](/cli/changelog/add.md) command.
Expand Down Expand Up @@ -93,6 +98,25 @@ Some of the fields in the schema accept only a specific set of values:
You can further limit the possible values with the [products](/contribute/configure-changelogs-ref.md#products) and [lifecycles](/contribute/configure-changelogs-ref.md#lifecycles) options in the changelog configuration file.
:::

## Upload changelog files [upload]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We shouldn't document folks manually uploading changelogs on the command line.

Everything should be automated through our github actions and the timing of publishing these should not be arbitrary.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think the need for that will persist for the ad hoc releases and things like known issues, security issues, feature announcements, etc that aren't ncessary tied to a PR or release. AFAIK those aren't uploaded automatically yet.


After you're satisfied with the content of your changelog files, the last step is to upload them to the public CDN.

:::{important}
All changelog files should be uploaded to the public CDN, irrespective of whether you also want to maintain a copy in your GitHub repo.
:::

- If you create changelog files from the command line, use the [changelog upload](/cli/changelog/upload.md) command to upload them.
- If you create your changelogs from GitHub actions, add an upload workflow. Refer to [Uploading to S3](https://github.com/elastic/docs-actions/blob/main/changelog/README.md#uploading-to-s3) and [changelog-upload.yml](https://github.com/elastic/docs-actions/blob/main/.github/workflows/changelog-upload.yml).

Files land in a private bucket, which is the internal source of truth.
A scrubber Lambda automatically mirrors sanitized copies (with private repository references removed) to the public bucket.
Changelog entries are uploaded into `changelog/{org}/{repo}/{branch}/{filename}`.

:::{note}
It can take between 60 seconds to an hour before updates appear in the public CDN.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is a bug, lets zoom in

:::

## Examples

### Control changelog creation [rules]
Expand Down
19 changes: 12 additions & 7 deletions docs/development/changelog-bundle-registry.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,9 +182,11 @@ entries from the local folder or fetch the **authoring pool's** published entrie
`CdnChangelogEntryFetcher`).

Under the artifact-root layout, entries are org/repo/branch-scoped — not product-scoped — so CDN
entry sourcing keys off the resolvable authoring pool (repo with the same precedence as upload:
`--repo` > `bundle.repo` > git remote; owner from `--owner` > `bundle.owner`, default `elastic`;
branch from `--branch` > `bundle.branch`, default `main`), **not** off the bundle's target products.
entry sourcing keys off the resolvable authoring pool (`--repo` > profile `repo` >
`bundle.repo`; owner from `--owner` > profile `owner` > `bundle.owner`, default `elastic`;
branch from `--branch` > profile `branch` > `bundle.branch`, default `main`). Git remote and
checkout branch are **not** used for bundle entry sourcing (unlike `changelog upload`). The pool
is keyed by authoring org/repo/branch, **not** by the bundle's target products.
This is what lets one repo (for example `kibana`) produce a bundle for a shared product (for example
`cloud-serverless`) while sourcing its own entries from `changelog/elastic/kibana/main/`, without that
product appearing in the repo's own `docset.yml`. The decision is made per run by
Expand Down Expand Up @@ -294,10 +296,13 @@ logic still applies via `assembler.yml`, exactly as for local bundles.
- **`serve` mode staleness.** The prefetch runs per reload, but within a single `serve` process a
product's CDN content is pinned until the next reload. Acceptable for now (serve targets local
markdown authoring, not changelog bundles); revisit alongside the disk cache.
- **CDN staleness.** The distribution caches the manifest with a 1h default TTL (60s min), so a
freshly uploaded bundle may not appear in the CDN-served `registry.json` for up to an
hour. If faster propagation is needed the producer (or a docs-actions step) would issue a
CloudFront invalidation on registry write.
- **CDN staleness.** The distribution caches objects with a 1h default TTL (60s min). That applies
to `registry.json` manifests **and** to individual entry YAML under
`changelog/{org}/{repo}/{branch}/` that `changelog bundle` fetches when sourcing from the CDN.
After upload and scrub, the private bucket can hold newer entry content than the CDN serves for
up to an hour. Operators who bundle immediately after last-minute entry edits can see stale data until the cache expires. If faster propagation is
needed the producer (or a docs-actions step) would issue a CloudFront invalidation on write.
User-facing guidance: [Entry sourcing](/cli/changelog/bundle.md#changelog-bundle-entry-sourcing).
- **Caching key.** When the disk cache lands, use the CDN response ETag (not the registry
`etag` field) for revalidation.

Expand Down
Loading