Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(feat): use towncrier for changelog automations #1604

Merged
merged 23 commits into from
Aug 27, 2024
Merged
Show file tree
Hide file tree
Changes from 20 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
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}"],
ilan-gold marked this conversation as resolved.
Show resolved Hide resolved
)
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 {pr}`1147` {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 {pr}`1501` {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 {pr}`1504` {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` {pr}`1516` {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 {pr}`1532` {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` {pr}`1540` {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` {pr}`1557` {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` {pr}`1580` {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 {pr}`1586` {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 {pr}`1589` {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 = "{{issue}}`{issue}`"
ilan-gold marked this conversation as resolved.
Show resolved Hide resolved
ilan-gold marked this conversation as resolved.
Show resolved Hide resolved
title_format = "(v{version})=\n### {version} `{project_date}`"
[tool.towncrier.fragment.bugfix]
[tool.towncrier.fragment.doc]
[tool.towncrier.fragment.feature]
[tool.towncrier.fragment.misc]

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