# `DocShell.Generate.Changelog`
[🔗](https://github.com/futhr/doc_shell/blob/v2.0.0/lib/doc_shell/generate/changelog.ex#L1)

Extracts the host's changelog or release notes into renderer-neutral release
entries.

The default source reads a conventional Markdown changelog (Keep a Changelog,
git_ops, and friends) as a sequence of release headings:

    ## [v1.2.0](https://host/compare/v1.1.0...v1.2.0) (2026-08-01)
    ## [1.2.0] - 2026-08-01

Keep a Changelog reference links (`[1.2.0]: https://...`) and inline links
are preserved as `"compare_url"`; linked and unlinked prerelease versions
are accepted.

Each release becomes one entry whose `"ast"` is the release's own
Markdown body parsed through `DocShell.Ast`, so navigation, search, and
content projection treat releases exactly like guides — no special
cases downstream. Version, date, and compare link land in `"meta"`.

Hosts are not limited to files. Set `:changelog_source` to a module that
implements `DocShell.Generate.Changelog.Source` to read release notes from a
graph database, CMS, API, or any other store. A dynamic source can either
return fully formed entries or fetch Markdown and call `from_markdown/2`.

A missing file extracts to an empty list: hosts without a changelog do
not fail their documentation build over it.

# `extract`

```elixir
@spec extract(keyword() | Path.t() | nil) :: {:ok, [map()]} | {:error, term()}
```

Extracts release entries from a configured source or a Markdown file path.

Passing a keyword config uses `:changelog_source` and `:changelog_options`.
Passing a path is kept for file-backed callers. Returns `{:ok, entries}`
newest-first, or `{:error, reason}` when a release body or source fails.

# `from_markdown`

```elixir
@spec from_markdown(String.t(), String.t()) :: {:ok, [map()]} | {:error, term()}
```

Parses conventional changelog Markdown into DocShell changelog entries.

`source_ref` is stored in each entry's metadata. Use a file path for file
sources or an opaque locator such as `graph://release-notes/example` for dynamic
sources.

# `validate`

```elixir
@spec validate(term()) :: {:ok, [map()]} | {:error, term()}
```

Validates source-provided changelog entries.

Custom sources return the same string-keyed entry maps the built-in Markdown
parser emits. Invalid source output fails the build before any artifact is
written.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
