﻿---
title: changelog add cli command
description: Create a changelog file that describes a single item in the release documentation. For details and examples, go to Create changelogs. By default, output...
url: https://docs-v3-preview.elastic.dev/elastic/docs-builder/pull/3809/cli/changelog/add
products:
  - Elastic Docs Builder
---

# changelog add cli command
```bash
docs-builder changelog add [options]
```

Create a changelog file that describes a single item in the release documentation.
For details and examples, go to [Create changelogs](https://docs-v3-preview.elastic.dev/elastic/docs-builder/pull/3809/data/release-notes/create).

## Options

<definitions>
  <definition term="--products string">
    Products affected in format `"product target lifecycle, ..."` (for example, `"elasticsearch 9.2.0 ga, cloud-serverless 2025-08-05"`).
    The valid product identifiers are listed in [products.yml](https://github.com/elastic/docs-builder/blob/main/config/products.yml).
    For more information about valid product and lifecycle values, go to [Product format](#product-format-and-resolution).
  </definition>
  <definition term="--action string">
    Optional: What users must do to mitigate
  </definition>
  <definition term="--areas string[]">
    Optional: Area(s) affected (comma-separated or specify multiple times)
    **Repeatable:** pass `--areas` multiple times to supply more than one value
  </definition>
  <definition term="--[no-]concise">
    Optional: Omit schema reference comments from generated YAML files. Useful in CI to produce compact output.
    **Default:** `false`
  </definition>
  <definition term="--config string">
    Optional: Path to the changelog.yml configuration file. Defaults to 'docs/changelog.yml'
    **Constraints:** symbolic links not allowed, must exist, extensions: yml, yaml
  </definition>
  <definition term="--description string">
    Optional: Additional information about the change (max 600 characters)
  </definition>
  <definition term="--[no-]no-extract-release-notes">
    Turn off extraction of release notes from PR or issue descriptions.
    By default, the behavior is determined by the [extract.release_notes](/elastic/docs-builder/pull/3809/data/release-notes/configure-ref#extract) changelog configuration setting. Release notes are extracted when using `--prs` or `--report` (and from issues when using `--issues`).
    **Default:** `false`
  </definition>
  <definition term="--[no-]no-extract-issues">
    Optional: Turn off extraction of linked references. When using --prs: turns off extraction of linked issues from the PR body (e.g., "Fixes #123"). When using --issues: turns off extraction of linked PRs from the issue body (e.g., "Fixed by #123"). By default, linked references are extracted in both cases.
    **Default:** `false`
  </definition>
  <definition term="--feature-id string">
    Optional: Feature flag ID
  </definition>
  <definition term="--[no-]highlight">
    Optional: Include in release highlights
  </definition>
  <definition term="--impact string">
    Optional: How the user's environment is affected
  </definition>
  <definition term="--issues string[]">
    Optional: Issue URL(s) or number(s) (comma-separated), or a path to a newline-delimited file containing issue URLs or numbers. Can be specified multiple times. Each occurrence can be either comma-separated issues (e.g., `--issues "https://github.com/owner/repo/issues/123,456"`) or a file path (e.g., `--issues /path/to/file.txt`). If --owner and --repo are provided, issue numbers can be used instead of URLs. If specified, --title can be derived from the issue. Creates one changelog file per issue. Mutually exclusive with --release-version and --report.
    **Repeatable:** pass `--issues` multiple times to supply more than one value
  </definition>
  <definition term="--owner string">
    Optional: GitHub repository owner (used when --prs or --issues contains just numbers, or when using --release-version). Falls back to bundle.owner in changelog.yml when not specified. If that value is also absent, "elastic" is used.
  </definition>
  <definition term="--output string">
    Optional: Output directory for the changelog. Falls back to bundle.directory in changelog.yml when not specified. Defaults to current directory.
  </definition>
  <definition term="--prs string[]">
    Optional: Pull request URL(s) or PR number(s) (comma-separated), or a path to a newline-delimited file containing PR URLs or numbers. Can be specified multiple times. Each occurrence can be either comma-separated PRs (e.g., `--prs "https://github.com/owner/repo/pull/123,6789"`) or a file path (e.g., `--prs /path/to/file.txt`). When specifying PRs directly, provide comma-separated values. When specifying a file path, provide a single value that points to a newline-delimited file. If --owner and --repo are provided, PR numbers can be used instead of URLs. If specified, --title can be derived from the PR. If mappings are configured, --areas and --type can also be derived from the PR. Creates one changelog file per PR. Mutually exclusive with --release-version and --report.
    **Repeatable:** pass `--prs` multiple times to supply more than one value
  </definition>
  <definition term="--report string">
    Optional: URL or file path to a promotion report HTML document. Extracts GitHub pull request URLs and creates one changelog per PR (same parsing as `changelog bundle --report`). Mutually exclusive with --prs, --issues, and --release-version.
  </definition>
  <definition term="--release-version string">
    Optional: GitHub release tag to fetch PRs from (e.g., "v9.2.0" or "latest"). When specified, creates one changelog per PR in the release notes. Requires --repo (or bundle.repo in changelog.yml). Mutually exclusive with --prs, --issues, and --report. Does not create a bundle; use 'changelog gh-release' for that.
  </definition>
  <definition term="--repo string">
    Optional: GitHub repository name (used when --prs or --issues contains just numbers, or when using --release-version). Falls back to bundle.repo in changelog.yml when not specified.
  </definition>
  <definition term="--[no-]strip-title-prefix">
    Optional: When used with --prs or --report, remove square brackets and text within them from the beginning of PR titles, and also remove a colon if it follows the closing bracket (e.g., "[Inference API] Title" becomes "Title", "[ES|QL]: Title" becomes "Title", "Discover][ESQL] Title" becomes "Title")
    **Default:** `false`
  </definition>
  <definition term="--[no-]strict-fetch">
    Treat a failure to fetch any PR or issue from GitHub (when using `--prs`, `--issues`, or `--report`) as an error that exits non-zero, instead of a warning.
    Refer to [Fetch failures](#fetch-failures).
    **Default:** `false`
  </definition>
  <definition term="--subtype string">
    Optional: Subtype for breaking changes (api, behavioral, configuration, etc.)
  </definition>
  <definition term="--title string">
    Optional: A short, user-facing title (max 80 characters). Required if neither --prs, --issues, nor --report is specified. If --prs and --title are specified, the latter value is used instead of what exists in the PR.
  </definition>
  <definition term="--type string">
    Optional: Type of change (feature, enhancement, bug-fix, breaking-change, etc.). Required if neither --prs, --issues, nor --report is specified. If mappings are configured, type can be derived from the PR or issue.
  </definition>
  <definition term="--[no-]use-pr-number">
    Use PR numbers for filenames instead of the configured `filename` strategy.
    Requires `--prs`, `--issues`, or `--report`. Mutually exclusive with `--use-issue-number`.
    Refer to [Filenames](#filenames).
    **Default:** `false`
  </definition>
  <definition term="--[no-]use-issue-number">
    Use issue numbers for filenames instead of the configured `filename` strategy.
    Requires `--prs` or `--issues`. Mutually exclusive with `--use-pr-number`.
    Refer to [Filenames](#filenames).
    **Default:** `false`
  </definition>
  <definition term="-l --log-level enum">
    Minimum log level.
    **Values:** trace, debug, information, warning, error, critical, none
    **Default:** `information`
  </definition>
  <definition term="-c --config-source enum">
    Override the configuration source: local, remote
    **Values:** local, remote, embedded
  </definition>
  <definition term="--[no-]skip-private-repositories">
    Skip cloning private repositories
  </definition>
</definitions>


## Global Options

<definitions>
  <definition term="-l --log-level enum">
    Minimum log level.
    **Values:** trace, debug, information, warning, error, critical, none
    **Default:** `information`
  </definition>
  <definition term="-c --config-source enum">
    Override the configuration source: local, remote
    **Values:** local, remote, embedded
  </definition>
  <definition term="--[no-]skip-private-repositories">
    Skip cloning private repositories
  </definition>
</definitions>


## Filenames

By default, output files are named according to the `filename` strategy in `changelog.yml`:

| Strategy              | Example filename                                          | Description                                        |
|-----------------------|-----------------------------------------------------------|----------------------------------------------------|
| `timestamp` (default) | `1735689600-fixes-enrich-and-lookup-join-resolution.yaml` | Uses a Unix timestamp with a sanitized title slug. |
| `pr`                  | `137431.yaml`                                             | Uses the PR number.                                |
| `issue`               | `2571.yaml`                                               | Uses the issue number.                             |

Refer to [changelog.example.yml](https://github.com/elastic/docs-builder/blob/main/config/changelog.example.yml) or [Changelog configuration reference](https://docs-v3-preview.elastic.dev/elastic/docs-builder/pull/3809/data/release-notes/configure-ref).
You can override those settings with the `--use-pr-number` or `--use-issue-number` flags:
```sh
docs-builder changelog add \
  --prs 1234 \
  --products "elasticsearch 9.2.3" \
  --use-pr-number

docs-builder changelog add \
  --issues 4567 \
  --products "elasticsearch 9.3.0" \
  --use-issue-number
```

<important>
  `--use-pr-number` and `--use-issue-number` are mutually exclusive; specify only one. `--use-pr-number` requires `--prs`, `--issues`, or `--report`. `--use-issue-number` requires `--prs` or `--issues`. The numbers are extracted from the URLs or identifiers you provide or from linked references in the issue or PR body when extraction is enabled.**Precedence**: CLI flags (`--use-pr-number` / `--use-issue-number`) > `filename` in `changelog.yml` > default (`timestamp`).
</important>


## Product format and resolution

The `--products` option accepts values with the format `"product target lifecycle, ..."` where:
- `product` is a product ID that exists in [products.yml](https://github.com/elastic/docs-builder/blob/main/config/products.yml) (required)
- `target` is the target version or date (optional)
- `lifecycle` exists in [Lifecycle.cs](https://github.com/elastic/docs-builder/blob/main/src/Elastic.Documentation/Lifecycle.cs) (optional)

You can further limit the possible values with the [products](/elastic/docs-builder/pull/3809/data/release-notes/configure-ref#products) and [lifecycles](/elastic/docs-builder/pull/3809/data/release-notes/configure-ref#lifecycles) options in the changelog configuration file.
For example:
- `"kibana 9.2.0 ga"`
- `"cloud-serverless 2025-08-05"`
- `"cloud-enterprise 4.0.3, cloud-hosted 2025-10-31"`

The `changelog add` command resolves product values in the following order:
1. The `--products` CLI option always takes priority.
2. If `pivot.products` is defined in the changelog configuration file and the PR or issue has labels that match, those products are used. Multiple matching entries are all applied.
3. If `products.default` is defined in the changelog configuration file, those default products are used.
4. If `--repo` is specified (or `bundle.repo` is set in the changelog configuration file), the repository name is matched against known product IDs in `products.yml` and the derived value is used.

The same order applies when using `--report` (after PR URLs are resolved from the promotion report), and when using batch `--prs` with multiple pull requests.
If none of these steps yield at least one product, the command returns an error.

## Feature ID resolution

The optional `feature-id` field associates a changelog with a feature flag or project.
The `changelog add` command resolves it in the following order:
1. The `--feature-id` CLI option always takes priority.
2. If `pivot.features` is defined in the changelog configuration file and the PR or issue has labels that match, that feature ID is used.
   If the PR or issue has multiple labels that map to different feature IDs, the first match is used and a warning is emitted.

When you map unreleased features in `pivot.features`, also list those feature IDs under the relevant bundle profile's [`hide_features`](/elastic/docs-builder/pull/3809/data/release-notes/configure-ref#bundle-profiles) setting so the entries stay commented out until the feature is ready to publish.
For more information, refer to [Bundle changelogs > Hide features](/elastic/docs-builder/pull/3809/data/release-notes/bundle#changelog-bundle-hide-features).

## Configuration checks

By default, the command checks `docs/changelog.yml` for a configuration file. You can specify a different path with `--config`.
If a configuration file exists, the command validates its values before generating changelog files:
- If the configuration file contains `lifecycles`, `products`, `subtype`, or `type` values that don't match the known valid values, validation fails.
- If the configuration file contains `areas` values and they don't match what you specify in `--areas`, validation fails.
- If the configuration file contains `lifecycles` or `products` values that are a subset of the available values and you try to create a changelog with values outside that subset, validation fails.

In each of these cases where validation fails, a changelog file is not created.
If the configuration file contains `rules.create` definitions and a PR or issue has a blocking label, that PR is skipped and no changelog file is created for it.
For more information, refer to [Create changelogs > Control changelog creation](/elastic/docs-builder/pull/3809/data/release-notes/create#rules).

## Fetch failures

`rules.create` label filtering and automatic `title`/`type` derivation both depend on fetching each PR or issue from GitHub.
When a fetch fails (for example, a missing or unauthorized `GITHUB_TOKEN`, a private or cross-repository reference, or API rate limiting), the affected entry **bypasses `rules.create` filtering** and is written with its `title` and `type` commented out.
Such entries later cause `changelog bundle` to fail with `missing required field: title`.
By default, each fetch failure is a warning and a single summary is emitted at the end of bulk creation (for example, `3 of 225 pull request(s) could not be fetched from GitHub`).
The command still exits `0` so a best-effort changelog is produced for offline or partial-access workflows.
Pass `--strict-fetch` to escalate fetch failures to an error so the command exits non-zero.
Use this in CI so a token or rate-limit problem fails the run loudly instead of silently producing unfiltered changelogs with missing titles.
The generated files are still written so you can inspect them.
```sh
docs-builder changelog add --report ./promotion-report.html --strict-fetch
```

<tip>
  If you hit this, verify that `GITHUB_TOKEN` is set and can access every repository referenced by your PRs or promotion report, then delete the generated changelog files and re-run.
</tip>


## CI auto-detection

When running inside GitHub Actions, `changelog add` automatically reads the following environment variables to fill in arguments not provided on the command line:

| Environment variable    | Fills           | Set from                             |
|-------------------------|-----------------|--------------------------------------|
| `CHANGELOG_PR_NUMBER`   | `--prs`         | `github.event.pull_request.number`   |
| `CHANGELOG_TITLE`       | `--title`       | `steps.evaluate.outputs.title`       |
| `CHANGELOG_DESCRIPTION` | `--description` | `steps.evaluate.outputs.description` |
| `CHANGELOG_TYPE`        | `--type`        | `steps.evaluate.outputs.type`        |
| `CHANGELOG_PRODUCTS`    | `--products`    | `steps.evaluate.outputs.products`    |
| `CHANGELOG_OWNER`       | `--owner`       | `github.repository_owner`            |
| `CHANGELOG_REPO`        | `--repo`        | `github.event.repository.name`       |

Explicit CLI arguments always take priority over environment variables.
`CHANGELOG_DESCRIPTION` has additional precedence rules related to release note extraction:
- If `--description` is provided on the command line, it always wins.
- If `--no-extract-release-notes` is passed (or `extract.release_notes: false` is set in the changelog configuration), `CHANGELOG_DESCRIPTION` is ignored.
- Otherwise, `CHANGELOG_DESCRIPTION` fills `--description` when it is not set on the command line.

This allows the CI action to invoke `changelog add` with a minimal command line:
```sh
docs-builder changelog add --config docs/changelog.yml --output /tmp/staging --concise --strip-title-prefix
```