Skip to content

Commit 562efcc

Browse files
committed
Attempt to update GitHub Actions to new approach.
This synchronizes the GH Actions setup to what I'm using in a couple other projects, and also fixes some errors that crept into the previous commits setting up PDM usage -- it *seems* like PDM is not actually needed, which is good because it was messing with the installed Django versions.
1 parent 249a8ca commit 562efcc

File tree

6 files changed

+316
-86
lines changed

6 files changed

+316
-86
lines changed

.github/workflows/ci.yml

Lines changed: 166 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,43 +4,193 @@ name: CI
44
on:
55
push:
66
branches: [trunk]
7-
tags: ["*"]
87
pull_request:
9-
branches: [trunk]
108
workflow_dispatch:
119

1210
env:
1311
FORCE_COLOR: "1"
14-
PIP_DISABLE_VERSION_CHECK: "1"
12+
PIP_DISABLE_PIP_VERSION_CHECK: "1"
13+
PIP_NO_PYTHON_VERSION_WARNING: "1"
1514

16-
permissions:
17-
contents: read
15+
permissions: {}
1816

1917
jobs:
20-
tests:
21-
name: nox on ${{ matrix.python-version }}
18+
build-package:
19+
name: Build and verify package
2220
runs-on: ubuntu-latest
2321

22+
steps:
23+
- uses: actions/checkout@v4
24+
with:
25+
fetch-depth: 0
26+
27+
- uses: hynek/build-and-inspect-python-package@v2
28+
id: baipp
29+
30+
outputs:
31+
python-versions: ${{ steps.baipp.outputs.supported_python_classifiers_json_array }}
32+
33+
tests:
34+
name: Tests on Python ${{ matrix.python-version }}
35+
needs: build-package
36+
runs-on: ubuntu-latest
2437
strategy:
2538
fail-fast: false
2639
matrix:
27-
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
40+
python-version: ${{ fromJson(needs.build-package.outputs.python-versions) }}
2841

2942
steps:
30-
- uses: actions/checkout@v4
43+
- name: Download pre-built packages
44+
uses: actions/download-artifact@v4
45+
with:
46+
name: Packages
47+
path: dist
48+
- run: tar xf dist/*.tar.gz --strip-components=1
3149
- uses: actions/setup-python@v5
3250
with:
3351
python-version: ${{ matrix.python-version }}
34-
- name: Set up PDM
35-
uses: pdm-project/setup-pdm@v4
52+
allow-prereleases: true
53+
- name: Install test runner
54+
run: |
55+
python -VV
56+
python -Im site
57+
python -Im pip install --upgrade nox
58+
python -Im nox --version
59+
- name: Run tests
60+
run: "python -Im nox --non-interactive --error-on-external-run --tag tests --python ${{ matrix.python-version }}"
61+
- name: Upload coverage data
62+
uses: actions/upload-artifact@v4
3663
with:
37-
python-version: ${{ matrix.python-version }}
38-
- name: "Install dependencies"
64+
name: coverage-data-${{ matrix.python-version }}
65+
path: .coverage.*
66+
include-hidden-files: true
67+
if-no-files-found: ignore
68+
69+
70+
coverage:
71+
name: Combine and check coverage
72+
needs: tests
73+
runs-on: ubuntu-latest
74+
75+
steps:
76+
- uses: actions/checkout@v4
77+
- uses: actions/setup-python@v5
78+
with:
79+
python-version: "3.12"
80+
- uses: actions/download-artifact@v4
81+
with:
82+
pattern: coverage-data-*
83+
merge-multiple: true
84+
85+
- name: Combine coverage & fail under 100%
86+
run: |
87+
python -Im pip install --upgrade "coverage[toml]"
88+
89+
coverage combine
90+
coverage html --skip-covered --skip-empty
91+
92+
# Report and write to summary.
93+
coverage report --format=markdown >> $GITHUB_STEP_SUMMARY
94+
95+
# Report again and fail if under 100%.
96+
coverage report --fail-under=100
97+
98+
- name: Upload HTML report if check failed.
99+
uses: actions/upload-artifact@v4
100+
with:
101+
name: html-report
102+
path: htmlcov
103+
if: ${{ failure() }}
104+
105+
106+
docs:
107+
name: Check documentation
108+
needs: build-package
109+
runs-on: ubuntu-latest
110+
steps:
111+
- name: Download pre-built packages
112+
uses: actions/download-artifact@v4
113+
with:
114+
name: Packages
115+
path: dist
116+
- run: tar xf dist/*.tar.gz --strip-components=1
117+
- uses: actions/setup-python@v5
118+
with:
119+
python-version: "3.12"
120+
- name: Set up test runner
121+
run: |
122+
python -VV
123+
python -Im site
124+
python -Im pip install --upgrade nox
125+
python -Im nox --version
126+
- name: Run documentation checks
127+
run: "python -Im nox --non-interactive --error-on-external-run --tag docs"
128+
129+
130+
lint-format:
131+
name: Lint code and check formatting
132+
needs: build-package
133+
runs-on: ubuntu-latest
134+
steps:
135+
- name: Download pre-built packages
136+
uses: actions/download-artifact@v4
137+
with:
138+
name: Packages
139+
path: dist
140+
- run: tar xf dist/*.tar.gz --strip-components=1
141+
- uses: actions/setup-python@v5
142+
with:
143+
python-version: "3.12"
144+
- name: Set up test runner
145+
run: |
146+
python -VV
147+
python -Im site
148+
python -Im pip install --upgrade nox
149+
python -Im nox --version
150+
- name: Check code formatting
151+
run: "python -Im nox --non-interactive --error-on-external-run --tag formatters --python 3.13"
152+
- name: Lint code
153+
run: "python -Im nox --non-interactive --error-on-external-run --tag linters --python 3.13"
154+
155+
156+
check-package:
157+
name: Additional package checks
158+
needs: build-package
159+
runs-on: ubuntu-latest
160+
steps:
161+
- name: Download pre-built packages
162+
uses: actions/download-artifact@v4
163+
with:
164+
name: Packages
165+
path: dist
166+
- run: tar xf dist/*.tar.gz --strip-components=1
167+
- uses: actions/setup-python@v5
168+
with:
169+
python-version: "3.12"
170+
- name: Set up test runner
39171
run: |
40172
python -VV
41173
python -Im site
42-
python -Im pip install --upgrade pip setuptools wheel
43174
python -Im pip install --upgrade nox
44175
python -Im nox --version
45-
- name: "Run CI suite with nox"
46-
run: "python -Im nox --non-interactive --python ${{ matrix.python-version }}"
176+
- name: Check package
177+
run: "python -Im nox --non-interactive --error-on-external-run --tag packaging --python 3.12"
178+
179+
180+
required-checks-pass:
181+
name: Ensure required checks pass for branch protection
182+
if: always()
183+
184+
needs:
185+
- check-package
186+
- coverage
187+
- docs
188+
- lint-format
189+
190+
runs-on: ubuntu-latest
191+
192+
steps:
193+
- name: Decide whether the jobs succeeded or failed
194+
uses: re-actors/alls-green@release/v1
195+
with:
196+
jobs: ${{ toJSON(needs) }}

noxfile.py

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@
2323
nox.options.default_venv_backend = "venv"
2424
nox.options.reuse_existing_virtualenvs = True
2525

26-
os.environ.update({"PDM_IGNORE_SAVED_PYTHON": "1"})
27-
26+
IS_CI = bool(os.getenv("CI", False))
2827
PACKAGE_NAME = "django_registration"
2928

3029
NOXFILE_PATH = pathlib.Path(__file__).parents[0]
@@ -73,8 +72,7 @@ def tests_with_coverage(session: nox.Session, django: str) -> None:
7372
Run the package's unit tests, with coverage report.
7473
7574
"""
76-
session.install(f"Django~={django}.0")
77-
session.run_always("pdm", "install", "-dG", "tests", external=True)
75+
session.install(f"Django~={django}.0", ".[tests]")
7876
python_version = session.run(
7977
f"{session.bin}/python{session.python}", "--version", silent=True
8078
).strip()
@@ -98,27 +96,40 @@ def tests_with_coverage(session: nox.Session, django: str) -> None:
9896
"runtests.py",
9997
env={"DJANGO_SETTINGS_MODULE": "tests.settings"},
10098
)
99+
clean()
100+
101+
102+
@nox.session(python=["3.13"], tags=["tests"])
103+
def coverage_report(session: nox.Session) -> None:
104+
"""
105+
Combine coverage from the various test runs and output the report.
106+
107+
"""
108+
# In CI this job does not run because we substitute one that integrates with the CI
109+
# system.
110+
if IS_CI:
111+
session.skip(
112+
"Running in CI -- skipping nox coverage job in favor of CI coverage job"
113+
)
114+
session.install("coverage[toml]")
115+
session.run(f"python{session.python}", "-Im", "coverage", "combine")
101116
session.run(
102-
f"{session.bin}/python{session.python}",
103-
"-Im",
104-
"coverage",
105-
"report",
106-
"--show-missing",
117+
f"python{session.python}", "-Im", "coverage", "report", "--show-missing"
107118
)
108-
clean()
119+
session.run(f"python{session.python}", "-Im", "coverage", "erase")
109120

110121

111122
# Tasks which test the package's documentation.
112123
# -----------------------------------------------------------------------------------
113124

114125

115-
@nox.session(python=["3.12"], tags=["docs"])
126+
@nox.session(python=["3.13"], tags=["docs"])
116127
def docs_build(session: nox.Session) -> None:
117128
"""
118129
Build the package's documentation as HTML.
119130
120131
"""
121-
session.run_always("pdm", "install", "-dG", "docs", external=True)
132+
session.install(".[docs]")
122133
build_dir = session.create_tmp()
123134
session.run(
124135
f"{session.bin}/python{session.python}",
@@ -137,7 +148,7 @@ def docs_build(session: nox.Session) -> None:
137148
clean()
138149

139150

140-
@nox.session(python=["3.12"], tags=["docs"])
151+
@nox.session(python=["3.13"], tags=["docs"])
141152
def docs_docstrings(session: nox.Session) -> None:
142153
"""
143154
Enforce the presence of docstrings on all modules, classes, functions, and
@@ -160,13 +171,13 @@ def docs_docstrings(session: nox.Session) -> None:
160171
clean()
161172

162173

163-
@nox.session(python=["3.12"], tags=["docs"])
174+
@nox.session(python=["3.13"], tags=["docs"])
164175
def docs_spellcheck(session: nox.Session) -> None:
165176
"""
166177
Spell-check the package's documentation.
167178
168179
"""
169-
session.run_always("pdm", "install", "-dG", "docs", external=True)
180+
session.install(".[docs]")
170181
session.install("pyenchant", "sphinxcontrib-spelling")
171182
build_dir = session.create_tmp()
172183
session.run(
@@ -197,7 +208,7 @@ def docs_spellcheck(session: nox.Session) -> None:
197208
# -----------------------------------------------------------------------------------
198209

199210

200-
@nox.session(python=["3.12"], tags=["formatters"])
211+
@nox.session(python=["3.13"], tags=["formatters"])
201212
def format_black(session: nox.Session) -> None:
202213
"""
203214
Check code formatting with Black.
@@ -219,7 +230,7 @@ def format_black(session: nox.Session) -> None:
219230
clean()
220231

221232

222-
@nox.session(python=["3.12"], tags=["formatters"])
233+
@nox.session(python=["3.13"], tags=["formatters"])
223234
def format_isort(session: nox.Session) -> None:
224235
"""
225236
Check code formating with Black.
@@ -245,7 +256,7 @@ def format_isort(session: nox.Session) -> None:
245256
# -----------------------------------------------------------------------------------
246257

247258

248-
@nox.session(python=["3.12"], tags=["linters", "security"])
259+
@nox.session(python=["3.13"], tags=["linters", "security"])
249260
def lint_bandit(session: nox.Session) -> None:
250261
"""
251262
Lint code with the Bandit security analyzer.
@@ -266,7 +277,7 @@ def lint_bandit(session: nox.Session) -> None:
266277
clean()
267278

268279

269-
@nox.session(python=["3.12"], tags=["linters"])
280+
@nox.session(python=["3.13"], tags=["linters"])
270281
def lint_flake8(session: nox.Session) -> None:
271282
"""
272283
Lint code with flake8.
@@ -286,7 +297,7 @@ def lint_flake8(session: nox.Session) -> None:
286297
clean()
287298

288299

289-
@nox.session(python=["3.12"], tags=["linters"])
300+
@nox.session(python=["3.13"], tags=["linters"])
290301
def lint_pylint(session: nox.Session) -> None:
291302
"""
292303
Lint code with Pylint.
@@ -305,7 +316,7 @@ def lint_pylint(session: nox.Session) -> None:
305316
# -----------------------------------------------------------------------------------
306317

307318

308-
@nox.session(python=["3.12"], tags=["packaging"])
319+
@nox.session(python=["3.13"], tags=["packaging"])
309320
def package_build(session: nox.Session) -> None:
310321
"""
311322
Check that the package builds.
@@ -317,7 +328,7 @@ def package_build(session: nox.Session) -> None:
317328
session.run(f"{session.bin}/python{session.python}", "-Im", "build")
318329

319330

320-
@nox.session(python=["3.12"], tags=["packaging"])
331+
@nox.session(python=["3.13"], tags=["packaging"])
321332
def package_description(session: nox.Session) -> None:
322333
"""
323334
Check that the package description will render on the Python Package Index.
@@ -345,7 +356,7 @@ def package_description(session: nox.Session) -> None:
345356
clean()
346357

347358

348-
@nox.session(python=["3.12"], tags=["packaging"])
359+
@nox.session(python=["3.13"], tags=["packaging"])
349360
def package_manifest(session: nox.Session) -> None:
350361
"""
351362
Check that the set of files in the package matches the set under version
@@ -362,7 +373,7 @@ def package_manifest(session: nox.Session) -> None:
362373
clean()
363374

364375

365-
@nox.session(python=["3.12"], tags=["packaging"])
376+
@nox.session(python=["3.13"], tags=["packaging"])
366377
def package_pyroma(session: nox.Session) -> None:
367378
"""
368379
Check package quality with pyroma.
@@ -378,7 +389,7 @@ def package_pyroma(session: nox.Session) -> None:
378389
clean()
379390

380391

381-
@nox.session(python=["3.12"], tags=["packaging"])
392+
@nox.session(python=["3.13"], tags=["packaging"])
382393
def package_wheel(session: nox.Session) -> None:
383394
"""
384395
Check the built wheel package for common errors.

0 commit comments

Comments
 (0)