Skip to content

Commit aa7681f

Browse files
fix(ci): enhance CI workflow with diagnostics and timeout, pin uv version to avoid regressions
1 parent 11e6487 commit aa7681f

2 files changed

Lines changed: 50 additions & 4 deletions

File tree

.github/workflows/ci.yml

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# CI: each command runs in its own step so the Actions UI shows whether a hang is
2+
# uv sync, ruff, or pytest. If a job stalls, expand the last step that printed output.
3+
14
name: CI
25

36
on:
@@ -8,17 +11,41 @@ on:
811
jobs:
912
pytest:
1013
runs-on: ubuntu-latest
14+
timeout-minutes: 45
1115
strategy:
1216
fail-fast: false
1317
matrix:
1418
python-version: ["3.11", "3.12", "3.13"]
1519
steps:
1620
- uses: actions/checkout@v4
21+
1722
- uses: astral-sh/setup-uv@v4
1823
with:
19-
version: "latest"
20-
- name: Install dev deps, lint, and run tests
24+
# Pin to avoid surprise regressions from `latest` during CI installs.
25+
version: "0.10.9"
26+
27+
- name: Diagnostics
28+
run: |
29+
set -euo pipefail
30+
uname -a
31+
echo "matrix python-version=${{ matrix.python-version }}"
32+
command -v uv
33+
uv --version
34+
command -v python3
35+
python3 --version
36+
uv python list || true
37+
38+
- name: Install dependencies (uv sync)
2139
run: |
22-
uv sync --group dev --python ${{ matrix.python-version }}
40+
set -euo pipefail
41+
uv sync --group dev --python ${{ matrix.python-version }} -v
42+
43+
- name: Ruff lint
44+
run: |
45+
set -euo pipefail
2346
uv run ruff check tests
47+
48+
- name: Pytest
49+
run: |
50+
set -euo pipefail
2451
uv run pytest -q

src/dylan/parser/language_derivation.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
from pathlib import Path
1414
from typing import Any, Iterable, Iterator, Literal, TextIO
1515

16+
import sys
17+
1618
from rich.console import Console as _RichConsole
1719

1820
from dylan.action.lexicon import Lexicon
@@ -21,7 +23,11 @@
2123
from dylan.nlp.types import DEFAULT_SPEAKER, RELEASE_TURN_TOKEN, WAIT_TOKEN
2224

2325
logger = logging.getLogger(__name__)
24-
_layered_console = _RichConsole()
26+
# ``force_interactive=False`` avoids Rich live-display threads that can block process exit under
27+
# pytest (especially on Windows) when capture or tooling leaves stdout in a non-TTY state.
28+
_layered_console = _RichConsole(
29+
force_interactive=(os.environ.get("DYLAN_UNDER_PYTEST") != "1" and sys.stdout.isatty()),
30+
)
2531

2632

2733
class _NoOpRichStatus:
@@ -83,6 +89,17 @@ def _default_language_workers() -> int:
8389
return max(1, (os.cpu_count() or 1) - 1)
8490

8591

92+
def _coerce_workers_for_pytest(workers: int) -> int:
93+
"""Use a single worker during pytest so process pools do not hang interpreter exit (Windows).
94+
95+
Parallel derivation tests compare parallel vs sequential outputs; with one worker the
96+
parallel code path matches sequential semantics, so those tests remain valid.
97+
"""
98+
if os.environ.get("DYLAN_UNDER_PYTEST") == "1" and workers > 1:
99+
return 1
100+
return workers
101+
102+
86103
def _next_language_output_paths(target_dir: Path, resolved_name: str) -> tuple[Path, Path]:
87104
"""Return the next unused ``(language_path, failures_path)`` pair under *target_dir*.
88105
@@ -611,6 +628,7 @@ def _run_layered_bfs(
611628
workers = _default_language_workers() if max_workers is None else max_workers
612629
if workers < 1:
613630
raise ValueError("max_workers must be at least 1")
631+
workers = _coerce_workers_for_pytest(workers)
614632
if workers > 1:
615633
gpd = grammar_path
616634
if gpd is None or not Path(gpd).is_dir():
@@ -1214,6 +1232,7 @@ def run(
12141232
workers = _default_language_workers() if max_workers is None else max_workers
12151233
if workers < 1:
12161234
raise ValueError("max_workers must be at least 1")
1235+
workers = _coerce_workers_for_pytest(workers)
12171236
if workers > 1 and (grammar_path is None or not Path(grammar_path).is_dir()):
12181237
raise ValueError("parallel derivation requires a filesystem grammar directory")
12191238

0 commit comments

Comments
 (0)