Skip to content

Commit 2dc1fa8

Browse files
Tox to nox (#14)
1 parent 830d728 commit 2dc1fa8

File tree

3 files changed

+135
-107
lines changed

3 files changed

+135
-107
lines changed

.github/workflows/check.yaml

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
name: Check
2+
23
on:
34
workflow_dispatch:
45
pull_request:
@@ -13,39 +14,35 @@ jobs:
1314
test:
1415
runs-on: ubuntu-latest
1516
env:
16-
COVERAGE_XML: .tox/coverage.xml
17+
COVERAGE_XML: coverage-${{ matrix.python-version }}.xml
1718
strategy:
1819
fail-fast: false
1920
matrix:
20-
python_versions:
21-
- "3.9"
22-
- "3.10"
23-
- "3.11"
24-
- "3.12"
25-
- "3.13"
21+
python-version: [ "3.9", "3.10", "3.11", "3.12", "3.13" ]
2622
steps:
2723
- name: Checkout repository
2824
uses: actions/checkout@v5
2925
with:
3026
fetch-depth: 0
3127

32-
- name: Install the latest version of uv
28+
- name: Install uv
3329
uses: astral-sh/setup-uv@v6
3430
with:
35-
enable-cache: false
31+
enable-cache: true
3632
cache-dependency-glob: "pyproject.toml"
3733
github-token: ${{ secrets.GITHUB_TOKEN }}
3834

39-
- name: Install Python interpreter
40-
run: uv python install --python-preference only-managed ${{ matrix.python_versions }}
35+
- name: Install Python ${{ matrix.python-version }}
36+
run: uv python install ${{ matrix.python-version }}
4137

42-
- name: Install tox
43-
run: uv tool install --python-preference only-managed --python 3.13 tox --with tox-uv
38+
- name: Install nox
39+
run: uv tool install --python 3.13 nox
4440

45-
- name: Run tox
46-
run: tox run -vv --skip-missing-interpreters false -e ${{ matrix.python_versions }}
41+
- name: Run nox
42+
run: nox -v -s tests-${{ matrix.python-version }}
4743
env:
4844
PYTEST_ADDOPTS: "-vv --durations=20"
45+
DEBUG: "1"
4946

5047
- name: Upload coverage to Codecov
5148
uses: codecov/codecov-action@v5
@@ -61,7 +58,7 @@ jobs:
6158
strategy:
6259
fail-fast: false
6360
matrix:
64-
check: [ "lint", "type_hints", "pkg-meta" ]
61+
check: [ "lint", "type_hints", "pkg_meta" ]
6562
steps:
6663
- name: Checkout repository
6764
uses: actions/checkout@v5
@@ -75,8 +72,13 @@ jobs:
7572
cache-dependency-glob: "pyproject.toml"
7673
github-token: ${{ secrets.GITHUB_TOKEN }}
7774

78-
- name: Install tox
79-
run: uv tool install --python-preference only-managed --python 3.13 tox --with tox-uv
75+
- name: Install Python 3.13
76+
run: uv python install 3.13
8077

81-
- name: Run lint checks
82-
run: tox run --skip-pkg-install -e ${{ matrix.check }}
78+
- name: Install nox
79+
run: uv tool install --python 3.13 nox
80+
81+
- name: Run nox ${{ matrix.check }}
82+
run: nox -v -s ${{ matrix.check }}
83+
env:
84+
DEBUG: "1"

noxfile.py

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
from __future__ import annotations
2+
3+
import os
4+
from dataclasses import dataclass
5+
from pathlib import Path
6+
7+
import nox
8+
9+
nox.options.error_on_missing_interpreters = True
10+
nox.options.reuse_existing_virtualenvs = True
11+
nox.options.default_venv_backend = "uv"
12+
13+
ROOT = Path(__file__).parent
14+
PYPROJECT_TOML_PATH = ROOT / "pyproject.toml"
15+
TESTS_DIR = ROOT / "tests"
16+
PYTEST_ENVX_DIR = ROOT / "src" / "pytest_envx"
17+
NOXFILE_PATH = ROOT / "noxfile.py"
18+
19+
PYPROJECT_TOML = nox.project.load_toml("pyproject.toml")
20+
PYTHON_VERSIONS = nox.project.python_versions(PYPROJECT_TOML)
21+
22+
PACKAGE = "pytest_envx"
23+
24+
TEST_DEPENDENCIES = nox.project.dependency_groups(PYPROJECT_TOML, "test")
25+
TYPE_HINTS_DEPENDENCIES = nox.project.dependency_groups(PYPROJECT_TOML, "type_hints")
26+
LINT_DEPENDENCIES = nox.project.dependency_groups(PYPROJECT_TOML, "lint")
27+
PKG_META_DEPENDENCIES = nox.project.dependency_groups(PYPROJECT_TOML, "pkg-meta")
28+
29+
30+
@dataclass(frozen=True, slots=True)
31+
class EnvConfig:
32+
junit_xml: str
33+
coverage_xml: str
34+
coverage_html: str
35+
coverage_file: str
36+
diff_against: str
37+
xdist_workers: str
38+
39+
@classmethod
40+
def from_env(cls, env_location: Path) -> EnvConfig:
41+
return cls(
42+
junit_xml=os.getenv("JUNIT_XML", str(env_location / "junit.xml")),
43+
coverage_xml=os.getenv("COVERAGE_XML", str(env_location / ".coverage.xml")),
44+
coverage_html=os.getenv("COVERAGE_HTML", str(env_location / "htmlcov")),
45+
coverage_file=os.getenv("COVERAGE_FILE", str(env_location / ".coverage")),
46+
diff_against=os.getenv("DIFF_AGAINST", "origin/master"),
47+
xdist_workers=os.getenv("PYTEST_XDIST_AUTO_NUM_WORKERS", "auto"),
48+
)
49+
50+
51+
@nox.session(python=PYTHON_VERSIONS) # type: ignore[misc]
52+
def tests(session: nox.Session) -> None:
53+
env_location = Path(session.virtualenv.location)
54+
config = EnvConfig.from_env(env_location)
55+
session.log("EnvConfig: %s", config)
56+
57+
session.env["COVERAGE_FILE"] = config.coverage_file
58+
59+
session.install(*TEST_DEPENDENCIES)
60+
session.install(".") # Download as package
61+
62+
# fmt: off
63+
session.run(
64+
"pytest",
65+
"-p", "no:pytest_envx",
66+
"-v",
67+
"-n", config.xdist_workers,
68+
"--junitxml", config.junit_xml,
69+
"--no-cov-on-fail",
70+
"--cov", PACKAGE,
71+
"--cov", TESTS_DIR,
72+
"--cov-config", PYPROJECT_TOML_PATH,
73+
"--cov-context", "test",
74+
"--cov-report", "term-missing",
75+
"--cov-report", f"html:{config.coverage_html}",
76+
"--cov-report", f"xml:{config.coverage_xml}",
77+
)
78+
79+
session.run(
80+
"diff-cover",
81+
"--compare-branch", config.diff_against,
82+
config.coverage_xml,
83+
)
84+
# fmt: on
85+
86+
87+
@nox.session # type: ignore[misc]
88+
def lint(session: nox.Session) -> None:
89+
session.install(*LINT_DEPENDENCIES)
90+
session.run("pre-commit", "run", "--all-files", "--show-diff-on-failure")
91+
92+
93+
@nox.session # type: ignore[misc]
94+
def type_hints(session: nox.Session) -> None:
95+
session.install(*TYPE_HINTS_DEPENDENCIES)
96+
session.run("mypy", "--config", PYPROJECT_TOML_PATH, PYTEST_ENVX_DIR, TESTS_DIR, NOXFILE_PATH)
97+
98+
99+
@nox.session # type: ignore[misc]
100+
def pkg_meta(session: nox.Session) -> None:
101+
session.install(*PKG_META_DEPENDENCIES)
102+
103+
tmp_dir = Path(session.create_tmp())
104+
105+
session.run("uv", "build", "--sdist", "--wheel", "--out-dir", tmp_dir, ".")
106+
session.run("twine", "check", tmp_dir / "*")
107+
session.run("check-wheel-contents", "--no-config", tmp_dir)

pyproject.toml

Lines changed: 6 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -36,26 +36,26 @@ classifiers = [
3636
"Topic :: Software Development :: Testing",
3737
]
3838
dependencies = [
39-
"pytest>=8.4.1",
40-
"python-dotenv>=1.1.0",
41-
"tomli>=2.2.1; python_version<'3.11'",
39+
"pytest>=7.0.0",
40+
"python-dotenv>=1.0.0",
41+
"tomli>=0.2.0; python_version<'3.11'",
4242
]
4343

4444
[dependency-groups]
4545
dev = [
4646
{ include-group = "test" },
47-
{ include-group = "type" },
47+
{ include-group = "type_hints" },
4848
{ include-group = "lint" },
4949
]
5050
test = [
5151
"coverage>=7.9.1",
52-
"pytest>=8.3.4",
52+
"pytest>=7.0.0",
5353
"pytest-cov>=6.2.1",
5454
"pytest-xdist>=3.7.0",
5555
"diff-cover>=9.4.1",
5656
"covdefaults>=2.3.0"
5757
]
58-
type = [
58+
type_hints = [
5959
"mypy>=1.16.1",
6060
"pytest-stub>=1.1.0"
6161
]
@@ -140,9 +140,6 @@ show_contexts = true
140140
[tool.coverage.path]
141141
source = [
142142
"src",
143-
".tox*/*/lib/python*/site-packages",
144-
".tox*/pypy*/site-packages",
145-
".tox*\\*\\Lib\\site-packages",
146143
"*/src",
147144
"*\\src",
148145
]
@@ -156,81 +153,3 @@ omit = [
156153
"src/pytest_envx/__version__.py"
157154
]
158155
show_missing = true
159-
160-
# ==============================
161-
# Tox
162-
# ==============================
163-
[tool.tox]
164-
requires = [
165-
"tox>=4.27.0",
166-
"tox-uv>=1.26.1",
167-
]
168-
env_list = [
169-
"3.13",
170-
"3.12",
171-
"3.11",
172-
"3.10",
173-
"3.9",
174-
"lint",
175-
"type_hints",
176-
"pkg-meta",
177-
]
178-
skip_missing_interpreters = true
179-
180-
[tool.tox.env_run_base]
181-
description = "Execute pytest tests for the specified Python environment"
182-
dependency_groups = ["test"]
183-
set_env.COVERAGE_FILE = { replace = "env", name = "COVERAGE_FILE", default = "{toxworkdir}{/}.coverage.{env_name}" }
184-
set_env.COVERAGE_XML = { replace = "env", name = "COVERAGE_XML", default = "{env_tmp_dir}{/}coverage.{env_name}.xml" }
185-
package = "wheel"
186-
wheel_build_env = ".pkg"
187-
pass_env = ["PYTEST_*", "COVERAGE_*"]
188-
commands = [
189-
[
190-
"pytest", { replace = "posargs", extend = true, default = [
191-
"-p", "no:pytest_envx",
192-
"-v",
193-
"-n", { replace = "env", name = "PYTEST_XDIST_AUTO_NUM_WORKERS", default = "auto" },
194-
"--junitxml", "{toxworkdir}{/}junit.{env_name}.xml",
195-
"--no-cov-on-fail",
196-
"--cov", "{env_site_packages_dir}{/}pytest_envx",
197-
"--cov", "{tox_root}{/}tests",
198-
"--cov-config", "{tox_root}{/}pyproject.toml",
199-
"--cov-context", "test",
200-
"--cov-report", "term-missing",
201-
"--cov-report", "html:{env_tmp_dir}{/}htmlcov",
202-
"--cov-report", "xml:{env:COVERAGE_XML}"
203-
] }
204-
],
205-
[
206-
"diff-cover", "--compare-branch", "{env:DIFF_AGAINST:origin/master}", "{env:COVERAGE_XML}"
207-
]
208-
]
209-
210-
211-
[tool.tox.env.lint]
212-
description = "Format code according to style guidelines and report unfixable issues"
213-
skip_install = true
214-
dependency_groups = ["lint"]
215-
pass_env = [{ replace = "ref", of = ["env_run_base", "pass_env"], extend = true }, "PROGRAMDATA", "DISABLE_PRE_COMMIT_UV_PATCH"]
216-
commands = [
217-
["pre-commit", "run", "--all-files", "--show-diff-on-failure", { replace = "posargs", extend = true }]
218-
]
219-
220-
[tool.tox.env.type_hints]
221-
description = "Perform static type checking on the code base"
222-
skip_install = true
223-
dependency_groups = ["type"]
224-
commands = [
225-
["mypy", "src{/}pytest_envx", "tests"]
226-
]
227-
228-
[tool.tox.env.pkg-meta]
229-
description = "Validate package metadata and build artifacts"
230-
skip_install = true
231-
dependency_groups = ["pkg_meta"]
232-
commands = [
233-
["uv", "build", "--sdist", "--wheel", "--out-dir", "{env_tmp_dir}", "."],
234-
["twine", "check", "{env_tmp_dir}{/}*"],
235-
["check-wheel-contents", "--no-config", "{env_tmp_dir}"]
236-
]

0 commit comments

Comments
 (0)