diff --git a/AGENTS.md b/AGENTS.md index e4c4e60..19a4eb1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -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 diff --git a/tests/test_workflow_naming.py b/tests/test_workflow_naming.py new file mode 100644 index 0000000..6881693 --- /dev/null +++ b/tests/test_workflow_naming.py @@ -0,0 +1,34 @@ +"""Every workflow's top-level `name:` must equal its own filename. + +GitHub labels a check ` / ` 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" + )