Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,12 @@ Two keys, and the difference matters:
the filename, so `pr-title / conventional title` names both the file to open
and what it did. A matrix job's `name:` has to interpolate the matrix value
(`pytest ${{ matrix.python-version }}`) or all three legs produce checks
called the same thing. `atdr/contrail-gh` enforces this in CI; here it is
convention. The `Analyze (python)` and `Analyze (actions)` checks are the
exception and always will be: CodeQL runs from default setup, which is a repo
setting rather than a file, so its name and its timeout are GitHub's to
choose.
called the same thing. `tests/test_workflow_naming.py` enforces this, the
same guard `atdr/contrail-gh#7` added as a shell step in CI there because
that repo has no test suite to hold it instead. The `Analyze (python)` and
`Analyze (actions)` checks are the exception and always will be: CodeQL runs
from default setup, which is a repo setting rather than a file, so its name
and its timeout are GitHub's to choose.
- **Every job that can carry `timeout-minutes` sets one.** GitHub's default is
six hours, and the failure that matters is a stall rather than an error: a
`pip` or `npx` fetch that hangs never fails on its own. Ten minutes
Expand Down
34 changes: 34 additions & 0 deletions tests/test_workflow_naming.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
"""Every workflow's top-level `name:` must equal its own filename.

GitHub labels a check `<workflow name> / <job name>` and never shows the
filename, so a workflow named for what it does leaves a reader guessing which
file under `.github/workflows/` produced a given check. Keeping the name equal
to the filename makes that mapping mechanical; the description goes on the
job instead. See atdr/contrail-gh#7, which added the same guard as a shell
step because that repo has no test suite to host it in — contrail does, so it
belongs here instead of prose in AGENTS.md that a change can silently ignore.
"""

from __future__ import annotations

from pathlib import Path

import yaml

WORKFLOW_DIR = Path(__file__).parent.parent / ".github" / "workflows"
WORKFLOW_PATHS = sorted(WORKFLOW_DIR.glob("*.yml")) + sorted(WORKFLOW_DIR.glob("*.yaml"))


def test_there_are_workflows_to_check():
"""A guard reading the wrong directory would otherwise pass by finding nothing."""
assert WORKFLOW_PATHS, f"no workflow files found under {WORKFLOW_DIR}"


def test_every_workflow_is_named_after_its_file():
for path in WORKFLOW_PATHS:
stem = path.stem
name = yaml.safe_load(path.read_text()).get("name")
assert name == stem, (
f"{path.name} is named {name!r} but its checks should read {stem!r} "
"so a reader can tell which file produced them"
)