G7.3: pin Python 3.12 in CI and cap job runtime
Some checks failed
check / gate (push) Failing after 7s
Some checks failed
check / gate (push) Failing after 7s
The first real CI run wedged for 14 minutes. Not a network problem, not the isolation work — catthehacker/ubuntu:act-22.04 ships Python 3.10.12 while this project declares requires-python >=3.12, and pip answered that by backtracking through the entire release history of every dependency looking for something 3.10-compatible. At 100% CPU, with -q hiding every line of it, and it would have churned until the runner's 30m timeout. A version mismatch presenting as a hang rather than an error is worth a test, so there is one: the workflow's python image must satisfy pyproject's requires-python, checked by parsing both rather than by eyeballing them. Also: every job now has timeout-minutes. A wedged step should be a red check in minutes, not an occupied runner for half an hour. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1 +0,0 @@
|
|||||||
ci: re-run after routing fix
|
|
||||||
@@ -16,6 +16,18 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
gate:
|
gate:
|
||||||
runs-on: veron-1
|
runs-on: veron-1
|
||||||
|
# Run IN a Python 3.12 image rather than trusting the runner image's
|
||||||
|
# toolchain. The first real CI run wedged here: catthehacker/ubuntu:act-22.04
|
||||||
|
# ships Python 3.10.12, this project declares requires-python >=3.12, and pip
|
||||||
|
# answered that by backtracking through the entire release history of every
|
||||||
|
# dependency looking for something 3.10-compatible. It churned for 14 minutes
|
||||||
|
# at 100% CPU with `-q` hiding all of it, and would have churned until the
|
||||||
|
# runner timeout. A version mismatch presenting as a hang, not an error.
|
||||||
|
container:
|
||||||
|
image: python:3.12-bookworm
|
||||||
|
# And a hard ceiling, so a wedged step is a red check in minutes rather than
|
||||||
|
# an occupied runner for half an hour.
|
||||||
|
timeout-minutes: 12
|
||||||
services:
|
services:
|
||||||
postgres:
|
postgres:
|
||||||
image: postgres:16-alpine
|
image: postgres:16-alpine
|
||||||
@@ -32,8 +44,10 @@ jobs:
|
|||||||
|
|
||||||
- name: install
|
- name: install
|
||||||
run: |
|
run: |
|
||||||
|
python3 --version
|
||||||
python3 -m venv .venv
|
python3 -m venv .venv
|
||||||
.venv/bin/pip install -q -e ".[dev]"
|
.venv/bin/pip install -q --upgrade pip
|
||||||
|
.venv/bin/pip install -e ".[dev]"
|
||||||
|
|
||||||
- name: lint
|
- name: lint
|
||||||
run: .venv/bin/ruff check api scripts
|
run: .venv/bin/ruff check api scripts
|
||||||
|
|||||||
@@ -461,3 +461,33 @@ def test_g75_workflows_use_a_label_this_runner_actually_provides():
|
|||||||
continue
|
continue
|
||||||
label = ln.split("runs-on:")[1].strip()
|
label = ln.split("runs-on:")[1].strip()
|
||||||
assert label in provided, f"{wf.name}: '{label}' is not a provided label"
|
assert label in provided, f"{wf.name}: '{label}' is not a provided label"
|
||||||
|
|
||||||
|
|
||||||
|
def test_g73_workflow_pins_a_python_that_satisfies_requires_python():
|
||||||
|
"""The first real CI run wedged for 14 minutes because the runner image
|
||||||
|
ships Python 3.10 and this project requires 3.12: pip answered by
|
||||||
|
backtracking through every historical version of every dependency, at full
|
||||||
|
CPU, silently. A version mismatch presenting as a hang rather than an
|
||||||
|
error."""
|
||||||
|
import re as _re
|
||||||
|
|
||||||
|
pyproject = (ROOT / "pyproject.toml").read_text()
|
||||||
|
m = _re.search(r'requires-python\s*=\s*">=(\d+)\.(\d+)"', pyproject)
|
||||||
|
assert m, "pyproject declares no requires-python"
|
||||||
|
major, minor = int(m.group(1)), int(m.group(2))
|
||||||
|
|
||||||
|
for wf in ROOT.rglob(".gitea/workflows/*.y*ml"):
|
||||||
|
text = wf.read_text()
|
||||||
|
img = _re.search(r"image:\s*python:(\d+)\.(\d+)", text)
|
||||||
|
assert img, f"{wf.name}: job does not pin a python image"
|
||||||
|
assert (int(img.group(1)), int(img.group(2))) >= (major, minor), (
|
||||||
|
f"{wf.name}: pins python {img.group(0)} but the project requires "
|
||||||
|
f">={major}.{minor}"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_g73_every_job_has_a_timeout():
|
||||||
|
"""A wedged step should be a red check in minutes, not an occupied runner
|
||||||
|
for half an hour."""
|
||||||
|
for wf in ROOT.rglob(".gitea/workflows/*.y*ml"):
|
||||||
|
assert "timeout-minutes:" in wf.read_text(), f"{wf.name}: no job timeout"
|
||||||
|
|||||||
Reference in New Issue
Block a user