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 13 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
2 changes: 2 additions & 0 deletions changelog/2664.internal.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Converted the |tox| environment for regenerating the requirements files
used in continuous integration checks to |nox|.
113 changes: 107 additions & 6 deletions noxfile.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,109 @@
"""Experimental nox configuration file."""
"""
Configuration file for nox.

To invoke a nox session, run `nox -s <session>`, where <session> is
replaced with the name of the session.
"""

import nox

nox.options.default_venv_backend = "uv"
nox.options.sessions = ["requirements"]

supported_python_versions = ("3.10", "3.11", "3.12")

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

requirements_directory = "ci_requirements"


def get_requirements_file(
category: str,
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!

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]
if resolution != "highest":
specifiers.append(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.39")

maxpython = "3.12"
category_version_resolution = [
("all", maxpython, "highest"),
("docs", maxpython, "highest"),
("tests", minpython, "lowest-direct"),
]

doc_requirements = ("-r", "ci_requirements/requirements_docs_py312.txt")
category_version_resolution += [
("tests", version, "highest") for version in supported_python_versions
]

category_flags = {
"all": ("--all-extras",),
"docs": ("--extra", "docs"),
"tests": ("--extra", "tests"),
}

command = (
"python",
"-m",
"uv",
"pip",
"compile",
"pyproject.toml",
"--upgrade",
)

flags = (
"--quiet",
"--custom-compile-command", # defines command to be included in file header
"nox -s requirements",
)

for category, version, resolution in category_version_resolution:
filename = get_requirements_file(category, version, resolution)
session.run(
*command,
"--python-version",
version,
*category_flags[category],
"--output-file",
filename,
"--resolution",
resolution,
*flags,
)


# Environments for building documentation

sphinx_commands = (
"sphinx-build",
Expand All @@ -20,25 +116,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)
# Environments for static type checking
ejohnson-96 marked this conversation as resolved.
Show resolved Hide resolved


@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