Skip to content

Commit

Permalink
gh-283: set up nox for developers and CI (#287)
Browse files Browse the repository at this point in the history
- Adds `noxfile` to support `nox` sessions for testing, docs, and
linting/formatting.
- `Nox` is now used to run everything in the CI.
- Adds documentation about the new infrastructure in contributing
guidelines.

Closes: #283

---------

Co-authored-by: Patrick J. Roddy <[email protected]>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
3 people authored Oct 1, 2024
1 parent 9277128 commit a1f5e14
Show file tree
Hide file tree
Showing 6 changed files with 159 additions and 6 deletions.
10 changes: 9 additions & 1 deletion .github/workflows/examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }}

env:
# The "FORCE_COLOR" variable, when set to 1,
# tells Nox to colorize itself.
FORCE_COLOR: "1"

jobs:
test-examples:
name: Test examples
Expand All @@ -36,4 +41,7 @@ jobs:
with:
python-version: 3.x
cache: pip
- run: pipx run --spec '.[examples]' jupyter execute examples/**/*.ipynb
- name: Install nox
run: pip install nox
- name: Run examples
run: nox -s examples
31 changes: 26 additions & 5 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }}

env:
# The "FORCE_COLOR" variable, when set to 1,
# tells Nox to colorize itself.
FORCE_COLOR: "1"

jobs:
tests:
name: Tests
Expand All @@ -39,8 +44,18 @@ jobs:
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- run: pip install -c .github/test-constraints.txt -e '.[test]'
- run: pytest --cov=glass --doctest-plus
- name: Install nox and coverage.py
run: pip install coverage[toml] nox
- name: Run doctests
run:
nox -s doctests-${{ matrix.python-version.key || matrix.python-version
}} --verbose
- name: Run tests and generate coverage report
run:
nox -s coverage-${{ matrix.python-version.key || matrix.python-version
}} --verbose
- name: Coveralls requires XML report
run: coverage xml
- uses: coverallsapp/github-action@v2
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
Expand All @@ -53,7 +68,10 @@ jobs:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- run: pipx run build
- name: Install nox
run: pip install nox
- name: Build SDist and wheel
run: nox -s build --verbose

docs:
name: Docs
Expand All @@ -63,7 +81,10 @@ jobs:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- run: |
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install pandoc
- run: pipx run --spec '.[docs]' sphinx-build -W -b html docs _build/html
pip install nox
- name: Build docs
run: nox -s docs --verbose
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ build
dist
.env
.coverage*
coverage*
46 changes: 46 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,52 @@ long as there have been changes.
The current version number is automatically inferred from the last release (i.e.
git tag), subsequent unreleased commits, and local changes, if any.

## Nox

`GLASS` supports running various critical commands using
[nox](https://github.com/wntrblm/nox) to make them less intimidating for new
developers. All of these commands (or sessions in the language of `nox`) -
`lint`, `tests`, `coverage`, `doctests`, `docs`, and `build` - are defined in
[noxfile.py](https://github.com/glass-dev/glass/main/noxfile.py).

`nox` can be installed via `pip` using -

```bash
pip install nox
```

The default sessions (`lint` and `tests`) can be executed using -

```bash
nox
```

A particular session (for example `tests`) can be run with `nox` on all
supported Python versions using -

```bash
nox -s tests
```

Only `tests`, `coverage`, and the `doctests` session run on all supported Python
versions by default.

To specify a particular Python version (for example `3.11`), use the following
syntax -

```bash
nox -s tests-3.11
```

The following command can be used to deploy the docs on `localhost` -

```bash
nox -s docs -- serve
```

The `nox` environments created for each type of session on the first run is
saved under `.nox/` and reused by default.

## Contributing workflow

Every change to the repository should come out of an issue where the change is
Expand Down
75 changes: 75 additions & 0 deletions noxfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
"""Nox config."""

from __future__ import annotations

import nox

# Options to modify nox behaviour
nox.options.default_venv_backend = "uv|virtualenv"
nox.options.reuse_existing_virtualenvs = True
nox.options.sessions = ["lint", "tests"]

ALL_PYTHON = ["3.8", "3.9", "3.10", "3.11", "3.12"]


@nox.session
def lint(session: nox.Session) -> None:
"""Run the linter."""
session.install("pre-commit")
session.run("pre-commit", "run", "--all-files", *session.posargs)


@nox.session(python=ALL_PYTHON)
def tests(session: nox.Session) -> None:
"""Run the unit tests."""
session.install("-c", ".github/test-constraints.txt", "-e", ".[test]")
session.run(
"pytest",
*session.posargs,
)


@nox.session(python=ALL_PYTHON)
def coverage(session: nox.Session) -> None:
"""Run tests and compute coverage."""
session.posargs.append("--cov=glass")
tests(session)


@nox.session(python=ALL_PYTHON)
def doctests(session: nox.Session) -> None:
"""Run the doctests."""
session.posargs.append("--doctest-plus")
session.posargs.append("glass")
tests(session)


@nox.session
def examples(session: nox.Session) -> None:
"""Run the example notebooks."""
session.install("-e", ".[examples]")
session.run("jupyter", "execute", "examples/**/*.ipynb", *session.posargs)


@nox.session
def docs(session: nox.Session) -> None:
"""Build the docs. Pass "serve" to serve."""
session.install("-e", ".[docs]")
session.chdir("docs")
session.run("sphinx-build", "-M", "html", ".", "_build")

port = 8001

if session.posargs:
if "serve" in session.posargs:
print(f"Launching docs at http://localhost:{port}/ - use Ctrl-C to quit")
session.run("python", "-m", "http.server", f"{port}", "-d", "_build/html")
else:
print("Unsupported argument to docs")


@nox.session
def build(session: nox.Session) -> None:
"""Build an SDist and wheel."""
session.install("build")
session.run("python", "-m", "build")
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@ lint.per-file-ignores = {"__init__.py" = [
"T201", # print
], "glass*" = [
"PLR2004", # TODO: magic-value-comparison
], "noxfile.py" = [
"T201", # print
], "tests*" = [
"ANN001", # TODO: missing-type-function-argument
"ANN201", # TODO: issing-return-type-undocumented-public-function
Expand Down

0 comments on commit a1f5e14

Please sign in to comment.