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

Add a nox session for regenerating pinned requirements files used in CI #2664

Merged
merged 18 commits into from
May 9, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
101 changes: 96 additions & 5 deletions noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,96 @@

nox.options.default_venv_backend = "uv"

supported_python_versions = ["3.10", "3.11", "3.12"]

maxpython = "3.12"
maxpython = max(supported_python_versions)
minpython = min(supported_python_versions)

doc_requirements = ("-r", "ci_requirements/requirements_docs_py312.txt")
requirements_directory = "ci_requirements"


def get_requirements_file(
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One of the benefits of switching to nox is that we can define functions to help create testing environments!

category: str, version: str, resolution: str = "highest"
) -> str:
"""
Return the file path to the requirements file.

Parameters
----------
category : str
The category for determining requirements: "docs", "tests", or
"all".

version : str
The version of Python to get the requirements for.

resolution : str
The resolution strategy to be used by ``uv pip compile``
``uv pip compile``.

Returns
-------
str
The path to the requirements file.
"""
specifiers = [category, version, resolution]
return f"{requirements_directory}/{'-'.join(specifiers)}.txt"


@nox.session
def requirements(session):
"""Regenerate pinned requirements files used during CI."""

session.install("uv >= 0.1.37")

command = (
"python",
"-m",
"uv",
"pip",
"compile",
"pyproject.toml",
"--upgrade",
"--quiet",
)
namurphy marked this conversation as resolved.
Show resolved Hide resolved

# Generate documentation requirements file for the most recent
# version of Python and the newest versions of dependencies.

doc_requirements_file = get_requirements_file(category="docs", version=maxpython)
session.run(
*command, "-p", maxpython, "--extra", "docs", "-o", doc_requirements_file
)

# Generate testing requirements files for all versions of Python with
# the newest versions of dependencies.

for version in supported_python_versions:
requirements_file = get_requirements_file(category="tests", version=version)

session.run(
*command, "-p", version, "--extra", "tests", "-o", requirements_file
)

# Generate testing requirements using the lowest-direct resolution strategy

minimal_requirements_file = get_requirements_file(
category="tests",
version=minpython,
resolution="lowest-direct",
)

session.run(
*command,
"-p",
minpython,
"-o",
minimal_requirements_file,
"--resolution=lowest-direct",
)


# Environments for building documentation

sphinx_commands = (
"sphinx-build",
Expand All @@ -20,25 +106,30 @@

html = ("-b", "html")
check_hyperlinks = ("-b", "linkcheck", "-q")
documentation_requirements = get_requirements_file(category="docs", version=maxpython)


@nox.session(python=maxpython)
def docs(session):
"""Build documentation with Sphinx."""
session.install(*doc_requirements)

session.install("-r", documentation_requirements)
session.install(".")
session.run(*sphinx_commands, *html, *session.posargs)


@nox.session(python=maxpython)
def linkcheck(session):
"""Check hyperlinks in documentation."""
session.install(*doc_requirements)
session.install("-r", documentation_requirements)
session.install(".")
session.run(*sphinx_commands, *check_hyperlinks, *session.posargs)


@nox.session(python=maxpython)
ejohnson-96 marked this conversation as resolved.
Show resolved Hide resolved
# Environments for static type checking


@nox.session
def mypy(session):
"""Perform static type checking with mypy."""
mypy_command = ("mypy", ".")
Expand Down
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ docs = [
"docutils >= 0.20.1",
"jinja2 >= 3.1.3",
"nbsphinx >= 0.9.3",
"nox >= 2024.4.15",
"numpydoc >= 1.6.0",
"pillow >= 10.2.0",
"pygments >= 2.17.2",
Expand Down Expand Up @@ -110,6 +111,7 @@ docs = [
# requirements to ensure that tests are run in consistent environments.
tests = [
"hypothesis >= 6.97.4",
"nox >= 2024.4.15",
"pre-commit >= 3.6.0",
"pytest >= 8.0.2",
"pytest-regressions >= 2.5.0",
Expand Down