Skip to content

Commit

Permalink
(feat): use towncrier for changelog automations (#1604)
Browse files Browse the repository at this point in the history
Co-authored-by: Philipp A. <[email protected]>
  • Loading branch information
ilan-gold and flying-sheep authored Aug 27, 2024
1 parent 229e2a6 commit 21a3a6d
Show file tree
Hide file tree
Showing 19 changed files with 156 additions and 128 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ __pycache__/
/src/anndata/_version.py
/requirements*.lock
/.python-version
/hatch.toml

# Test results (nunit/junit) and coverage
/test-data/
Expand Down
2 changes: 1 addition & 1 deletion ci/scripts/min-deps.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def min_dep(req: Requirement) -> Requirement:
-------
>>> min_dep(Requirement("numpy>=1.0"))
"numpy==1.0"
<Requirement('numpy==1.0.*')>
"""
req_name = req.name
if req.extras:
Expand Down
4 changes: 3 additions & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,11 @@
"sphinx.ext.linkcode",
"nbsphinx",
"IPython.sphinxext.ipython_console_highlighting",
"patch_sphinx_toolbox_autoprotocol",
"patch_sphinx_toolbox_autoprotocol", # internal extension
"sphinx_toolbox.more_autodoc.autoprotocol",
# other internal extensions
"patch_myst_cite",
"release_notes",
]
myst_enable_extensions = [
"html_image", # So README.md can be used on github and sphinx docs
Expand Down
111 changes: 111 additions & 0 deletions docs/extensions/release_notes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
from __future__ import annotations

import itertools
import re
from pathlib import Path
from typing import TYPE_CHECKING

from docutils import nodes
from packaging.version import Version
from sphinx.util.docutils import SphinxDirective

if TYPE_CHECKING:
from collections.abc import Iterable, Sequence
from typing import ClassVar

from myst_parser.mdit_to_docutils.base import DocutilsRenderer
from sphinx.application import Sphinx


FULL_VERSION_RE = re.compile(r"^(\d+)\.(\d+)\.(\d+)$")


class ReleaseNotes(SphinxDirective):
required_arguments: ClassVar = 1

def run(self) -> Sequence[nodes.Node]:
dir_ = Path(self.arguments[0])
# resolve relative dir
if not dir_.is_absolute():
src_file = Path(self.get_source_info()[0])
if not src_file.is_file():
msg = f"Cannot find relative path to: {src_file}"
raise self.error(msg)
dir_ = src_file.parent / self.arguments[0]
if not dir_.is_dir():
msg = f"Not a directory: {dir_}"
raise self.error(msg)

versions = sorted(
(
(Version(f.stem), f)
for f in dir_.iterdir()
if FULL_VERSION_RE.match(f.stem)
),
reverse=True, # descending
)
version_groups = itertools.groupby(
versions, key=lambda vf: (vf[0].major, vf[0].minor)
)
for (major, minor), versions in version_groups:
self.render_version_group(major, minor, versions)
return []

def render_version_group(
self, major: int, minor: int, versions: Iterable[tuple[Version, Path]]
) -> None:
target = nodes.target(
ids=[f"v{major}-{minor}"],
names=[f"v{major}.{minor}"],
)
section = nodes.section(
"",
nodes.title("", f"Version {major}.{minor}"),
ids=[],
names=[f"version {major}.{minor}"],
)
self.state.document.note_implicit_target(section)
self.state.document.note_explicit_target(target)
# append target and section to parent
self.renderer.current_node.append(target)
self.renderer.update_section_level_state(section, 2)
# append children to section
with self.renderer.current_node_context(section):
for _, p in versions:
self.render_include(p)

def render_include(self, path: Path) -> None:
# hacky solution because of https://github.com/executablebooks/MyST-Parser/issues/967
from docutils.parsers.rst.directives.misc import Include
from myst_parser.mocking import MockIncludeDirective

srcfile, lineno = self.get_source_info()
parent_dir = Path(srcfile).parent

d = MockIncludeDirective(
renderer=self.renderer,
name=type(self).__name__,
klass=Include, # type: ignore # wrong type hint
arguments=[str(path.relative_to(parent_dir))],
options={},
body=[],
lineno=lineno,
)
d.run()

# TODO: replace the above with this once the above mentioned bug is fixed
# from sphinx.util.parsing import nested_parse_to_nodes
# return nested_parse_to_nodes(
# self.state,
# path.read_text(),
# source=str(path),
# offset=self.content_offset,
# )

@property
def renderer(self) -> DocutilsRenderer:
return self.state._renderer


def setup(app: Sphinx) -> None:
app.add_directive("release-notes", ReleaseNotes)
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

See {doc}`/release-notes/index`,
particularly {ref}`v0.10` for the current release,
and {ref}`v0.11` for the upcoming release,
and [the `.feature` fragments](https://github.com/scverse/anndata/tree/main/docs) for the upcoming release,

```{toctree}
:hidden: true
Expand Down
21 changes: 0 additions & 21 deletions docs/release-notes/0.10.9.md

This file was deleted.

1 change: 1 addition & 0 deletions docs/release-notes/1147.bugfix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix writing large number of columns for `h5` files {user}`ilan-gold` {user}`selmanozleyen`
1 change: 1 addition & 0 deletions docs/release-notes/1501.bugfix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add warning for setting `X` on a view with repeated indices {user}`ilan-gold`
1 change: 1 addition & 0 deletions docs/release-notes/1504.performance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Support for `concat_on_disk` outer join {user}`ilan-gold`
1 change: 1 addition & 0 deletions docs/release-notes/1516.bugfix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Coerce {class}`numpy.matrix` classes to arrays when trying to store them in `AnnData` {user}`flying-sheep`
1 change: 1 addition & 0 deletions docs/release-notes/1532.bugfix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix for setting a dense `X` view with a sparse matrix {user}`ilan-gold`
1 change: 1 addition & 0 deletions docs/release-notes/1540.bugfix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Upper bound {mod}`numpy` for `gpu` installation on account of {issue}`cupy/cupy#8391`{user}`ilan-gold`
1 change: 1 addition & 0 deletions docs/release-notes/1557.doc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
add `callback` typing for {func}`~anndata.experimental.read_dispatched` and {func}`~anndata.experimental.write_dispatched` {user}`ilan-gold`
1 change: 1 addition & 0 deletions docs/release-notes/1580.bugfix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Upper bound dask on account of {issue}`1579` {user}`ilan-gold`
1 change: 1 addition & 0 deletions docs/release-notes/1586.bugfix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Ensure setting {attr}`pandas.DataFrame.index` on a view of a {class}`~anndata.AnnData` instantiates the {class}`~pandas.DataFrame` from the view {user}`ilan-gold`
1 change: 1 addition & 0 deletions docs/release-notes/1589.bugfix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Disallow using {class}`~pandas.DataFrame`s with multi-index columns {user}`ilan-gold`
104 changes: 1 addition & 103 deletions docs/release-notes/index.md
Original file line number Diff line number Diff line change
@@ -1,106 +1,4 @@
# Release notes

(v0.11)=
## Version 0.11

```{include} /release-notes/0.11.0.md
```

(v0.10)=
## Version 0.10

```{include} /release-notes/0.10.9.md
```

```{include} /release-notes/0.10.8.md
```

```{include} /release-notes/0.10.7.md
```

```{include} /release-notes/0.10.6.md
```

```{include} /release-notes/0.10.5.md
```

```{include} /release-notes/0.10.4.md
```

```{include} /release-notes/0.10.3.md
```

```{include} /release-notes/0.10.2.md
```

```{include} /release-notes/0.10.1.md
```

```{include} /release-notes/0.10.0.md
```

(v0.9)=
## Version 0.9

```{include} /release-notes/0.9.2.md
```

```{include} /release-notes/0.9.1.md
```

```{include} /release-notes/0.9.0.md
```

(v0.8)=
## Version 0.8

```{include} /release-notes/0.8.0.md
```

(v0.7)=
## Version 0.7

```{include} /release-notes/0.7.8.md
```

```{include} /release-notes/0.7.7.md
```

```{include} /release-notes/0.7.6.md
```

```{include} /release-notes/0.7.5.md
```

```{include} /release-notes/0.7.4.md
```

```{include} /release-notes/0.7.3.md
```

```{include} /release-notes/0.7.2.md
```

```{include} /release-notes/0.7.0.md
```

(v0.6)=
## Version 0.6

```{include} /release-notes/0.6.x.md
```

```{include} /release-notes/0.6.0.md
```

(v0.5)=
## Version 0.5

```{include} /release-notes/0.5.0.md
```

(v0.4)=
## Version 0.4

```{include} /release-notes/0.4.0.md
```{release-notes} .
```
11 changes: 11 additions & 0 deletions hatch.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[envs.default]
installer = "uv"
features = ["dev"]

[envs.docs]
features = ["doc"]
dependencies = ["setuptools"] # https://bitbucket.org/pybtex-devs/pybtex/issues/169

[envs.docs.scripts]
build = "sphinx-build -M html docs docs/_build -W --keep-going {args}"
clean = "git clean -fX -- docs"
18 changes: 18 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ dev = [
"setuptools_scm",
# test speedups
"pytest-xdist",
"towncrier>=24.8.0",
]
doc = [
"sphinx>=7.4.6",
Expand Down Expand Up @@ -147,6 +148,7 @@ python_files = "test_*.py"
testpaths = [
"anndata", # docstrings (module name due to --pyargs)
"./tests", # unit tests
"./ci/scripts", # CI script tests
"./docs/concatenation.rst", # further doctests
]
# For some reason this effects how logging is shown when tests are run
Expand Down Expand Up @@ -192,3 +194,19 @@ strict = true
[tool.codespell]
skip = ".git,*.pdf,*.svg"
ignore-words-list = "theis,coo,homogenous"

[tool.towncrier]
package = "anndata"
directory = "docs/release-notes"
filename = "docs/release-notes/{version}.md"
single_file = false
package_dir = "src"
issue_format = "{{pr}}`{issue}`"
title_format = "(v{version})=\n### {version} {{small}}`{project_date}`"
[tool.towncrier.fragment.bugfix]
[tool.towncrier.fragment.doc]
[tool.towncrier.fragment.feature]
[tool.towncrier.fragment.misc]

[tool.towncrier.fragment.performance]
name = "Performance"

0 comments on commit 21a3a6d

Please sign in to comment.