diff --git a/packages/zarr-http-server/changes/4311.doc.md b/packages/zarr-http-server/changes/4311.doc.md
new file mode 100644
index 0000000000..674389780c
--- /dev/null
+++ b/packages/zarr-http-server/changes/4311.doc.md
@@ -0,0 +1,2 @@
+The docs now render the release notes as a page instead of linking to
+`CHANGELOG.md` on GitHub, so each docs version shows its own changelog.
diff --git a/packages/zarr-http-server/docs/index.md b/packages/zarr-http-server/docs/index.md
index 271de6445e..f44c087e77 100644
--- a/packages/zarr-http-server/docs/index.md
+++ b/packages/zarr-http-server/docs/index.md
@@ -67,5 +67,5 @@ Reads are all that is enabled by default: `GET` and `HEAD` are served, and
- [User guide](guide.md) — building apps, running them, byte ranges, CORS,
writes, notebooks, and Uvicorn configuration
- [API reference](api/index.md)
-- [Changelog](https://github.com/zarr-developers/zarr-python/blob/main/packages/zarr-http-server/CHANGELOG.md)
+- [Release notes](release-notes.md)
- [License (MIT)](https://github.com/zarr-developers/zarr-python/blob/main/packages/zarr-http-server/LICENSE.txt)
diff --git a/packages/zarr-http-server/docs/release-notes.md b/packages/zarr-http-server/docs/release-notes.md
new file mode 100644
index 0000000000..767cd56a84
--- /dev/null
+++ b/packages/zarr-http-server/docs/release-notes.md
@@ -0,0 +1,8 @@
+
+
+--8<-- "CHANGELOG.md"
diff --git a/packages/zarr-http-server/mkdocs.yml b/packages/zarr-http-server/mkdocs.yml
index 7ebfe8c017..44978f0223 100644
--- a/packages/zarr-http-server/mkdocs.yml
+++ b/packages/zarr-http-server/mkdocs.yml
@@ -16,7 +16,7 @@ nav:
- guide.md
- API Reference:
- api/index.md
- - Changelog: https://github.com/zarr-developers/zarr-python/blob/main/packages/zarr-http-server/CHANGELOG.md
+ - Release notes: release-notes.md
watch:
- src
@@ -98,3 +98,11 @@ markdown_extensions:
line_spans: __span
pygments_lang_class: true
- pymdownx.inlinehilite
+ - pymdownx.snippets:
+ # The package root lets docs/release-notes.md include the
+ # towncrier-managed CHANGELOG.md without moving it out of the package
+ # root, where PyPI and GitHub readers expect it.
+ base_path: [docs, .]
+ # Fail the build on an unresolvable include instead of silently
+ # rendering nothing.
+ check_paths: true
diff --git a/packages/zarr-indexing/changes/4311.doc.md b/packages/zarr-indexing/changes/4311.doc.md
new file mode 100644
index 0000000000..674389780c
--- /dev/null
+++ b/packages/zarr-indexing/changes/4311.doc.md
@@ -0,0 +1,2 @@
+The docs now render the release notes as a page instead of linking to
+`CHANGELOG.md` on GitHub, so each docs version shows its own changelog.
diff --git a/packages/zarr-indexing/docs/index.md b/packages/zarr-indexing/docs/index.md
index 1dd151d8ca..3a858454cf 100644
--- a/packages/zarr-indexing/docs/index.md
+++ b/packages/zarr-indexing/docs/index.md
@@ -49,5 +49,5 @@ the chain stays one description, and where the materialization boundary is.
- [Design notes](design-notes.md) — TensorStore lineage, box vs query, and
deliberate limits.
- [API reference](api/index.md)
-- [Changelog](https://github.com/zarr-developers/zarr-python/blob/main/packages/zarr-indexing/CHANGELOG.md)
+- [Release notes](release-notes.md)
· [License (MIT)](https://github.com/zarr-developers/zarr-python/blob/main/packages/zarr-indexing/LICENSE.txt)
diff --git a/packages/zarr-indexing/docs/release-notes.md b/packages/zarr-indexing/docs/release-notes.md
new file mode 100644
index 0000000000..767cd56a84
--- /dev/null
+++ b/packages/zarr-indexing/docs/release-notes.md
@@ -0,0 +1,8 @@
+
+
+--8<-- "CHANGELOG.md"
diff --git a/packages/zarr-indexing/mkdocs.yml b/packages/zarr-indexing/mkdocs.yml
index d97e63b150..cc38b5fc81 100644
--- a/packages/zarr-indexing/mkdocs.yml
+++ b/packages/zarr-indexing/mkdocs.yml
@@ -23,7 +23,7 @@ validation:
omitted_files: warn
# Top-level rank is consistent: collections (Guide, Examples, API Reference)
-# and standalone artifacts (landing, ndsel spec, design notes, changelog).
+# and standalone artifacts (landing, ndsel spec, design notes, release notes).
# Guide mirrors the docs/guide/ directory — its three pages are one
# collection (learn / look up / integrate), pydantic's Concepts pattern at
# small scale; navigation.indexes makes the Guide entry itself land on the
@@ -56,7 +56,7 @@ nav:
- ' zarr_indexing.errors': api/errors.md
- ' zarr_indexing.testing.stateful': api/testing_stateful.md
- ' zarr_indexing.testing.strategies': api/testing_strategies.md
- - Changelog: https://github.com/zarr-developers/zarr-python/blob/main/packages/zarr-indexing/CHANGELOG.md
+ - Release notes: release-notes.md
# This site is a Read the Docs subproject of zarr-python; give readers a way
# back to the parent docs, which list every companion package.
- 'zarr-python ↪': https://zarr.readthedocs.io/
@@ -148,7 +148,10 @@ markdown_extensions:
- pymdownx.tabbed:
alternate_style: true
- pymdownx.snippets:
- base_path: [docs, examples]
+ # The package root is last so docs/release-notes.md can include the
+ # towncrier-managed CHANGELOG.md without moving it out of the package
+ # root, where PyPI and GitHub readers expect it.
+ base_path: [docs, examples, .]
# Fail the build on an unresolvable include or missing region instead
# of silently rendering nothing. tests/test_doc_examples.py mirrors
# base_path when it verifies the include graph.
diff --git a/packages/zarr-indexing/tests/test_doc_examples.py b/packages/zarr-indexing/tests/test_doc_examples.py
index 240bd48531..a4833296da 100644
--- a/packages/zarr-indexing/tests/test_doc_examples.py
+++ b/packages/zarr-indexing/tests/test_doc_examples.py
@@ -44,7 +44,7 @@
# Mirrors `pymdownx.snippets: base_path` in mkdocs.yml. If that list changes,
# change this one in the same commit.
-SNIPPET_BASE_PATHS = (DOCS, STANDALONE_EXAMPLES)
+SNIPPET_BASE_PATHS = (DOCS, STANDALONE_EXAMPLES, PACKAGE_ROOT)
_INCLUDE = re.compile(r'--8<--\s+"(?P[^":\n]+?)(?::(?P[^"\n]+))?"')
diff --git a/packages/zarr-metadata/changes/4311.doc.md b/packages/zarr-metadata/changes/4311.doc.md
new file mode 100644
index 0000000000..674389780c
--- /dev/null
+++ b/packages/zarr-metadata/changes/4311.doc.md
@@ -0,0 +1,2 @@
+The docs now render the release notes as a page instead of linking to
+`CHANGELOG.md` on GitHub, so each docs version shows its own changelog.
diff --git a/packages/zarr-metadata/docs/index.md b/packages/zarr-metadata/docs/index.md
index 58e4f290c6..0163dda5c1 100644
--- a/packages/zarr-metadata/docs/index.md
+++ b/packages/zarr-metadata/docs/index.md
@@ -94,5 +94,5 @@ and everything past that belongs to consumer libraries.
## Reference
- [API reference](api/index.md)
-- [Changelog](https://github.com/zarr-developers/zarr-python/blob/main/packages/zarr-metadata/CHANGELOG.md)
+- [Release notes](release-notes.md)
- [License (MIT)](https://github.com/zarr-developers/zarr-python/blob/main/packages/zarr-metadata/LICENSE.txt)
diff --git a/packages/zarr-metadata/docs/release-notes.md b/packages/zarr-metadata/docs/release-notes.md
new file mode 100644
index 0000000000..767cd56a84
--- /dev/null
+++ b/packages/zarr-metadata/docs/release-notes.md
@@ -0,0 +1,8 @@
+
+
+--8<-- "CHANGELOG.md"
diff --git a/packages/zarr-metadata/mkdocs.yml b/packages/zarr-metadata/mkdocs.yml
index 18e1fc8c35..98a51e3645 100644
--- a/packages/zarr-metadata/mkdocs.yml
+++ b/packages/zarr-metadata/mkdocs.yml
@@ -24,7 +24,7 @@ nav:
- ' zarr_metadata.v3.chunk_key_encoding': api/v3/chunk_key_encoding.md
- ' zarr_metadata.v3.codec': api/v3/codec.md
- ' zarr_metadata.v3.data_type': api/v3/data_type.md
- - Changelog: https://github.com/zarr-developers/zarr-python/blob/main/packages/zarr-metadata/CHANGELOG.md
+ - Release notes: release-notes.md
# This site is a Read the Docs subproject of zarr-python; give readers a way
# back to the parent docs, which list every companion package.
- 'zarr-python ↪': https://zarr.readthedocs.io/
@@ -109,3 +109,11 @@ markdown_extensions:
line_spans: __span
pygments_lang_class: true
- pymdownx.inlinehilite
+ - pymdownx.snippets:
+ # The package root lets docs/release-notes.md include the
+ # towncrier-managed CHANGELOG.md without moving it out of the package
+ # root, where PyPI and GitHub readers expect it.
+ base_path: [docs, .]
+ # Fail the build on an unresolvable include instead of silently
+ # rendering nothing.
+ check_paths: true