fix(ci): keep an expression matrix directive out of the comparison

`include:` or `exclude:` written as `${{ ... }}` read back as a string, and
the sweep treated that as the directive being absent, so it expanded every
combination GitHub would have dropped. A job whose `name:` holds no matrix
value then looked like it repeated one name across combinations that never
run. An absent directive still means no rows; anything that is not a list
of rows now joins the names left out of the comparison
This commit is contained in:
mateo-berri 2026-09-06 02:59:16 -07:00
parent 5a27e11263
commit 4edf6f4dc5
2 changed files with 35 additions and 1 deletions

View file

@ -162,8 +162,10 @@ def listed_values(matrix: Mapping[str, object]) -> tuple[tuple[str, tuple[str, .
def directive_rows(matrix: Mapping[str, object], directive: str) -> tuple[Mapping[str, str], ...] | Opaque:
"""One `include` or `exclude` row, or why the combinations they shape cannot be worked out."""
rows: Final = matrix.get(directive)
if not isinstance(rows, Sequence) or isinstance(rows, str):
if rows is None:
return ()
if not isinstance(rows, Sequence) or isinstance(rows, str):
return Opaque(f"a matrix `{directive}` is itself an expression rather than a list of rows")
mappings: Final = tuple(row for row in rows if isinstance(row, Mapping))
if len(mappings) != len(rows):
return Opaque(f"a matrix `{directive}` row is not a mapping of values")

View file

@ -846,3 +846,35 @@ def test_a_file_holding_two_yaml_documents_is_reported_rather_than_raising() ->
assert len(unreadable(sources)) == 1
assert exit_code(sources) == 1
def test_an_exclude_that_is_itself_an_expression_is_reported_rather_than_ignored() -> None:
sources: Final = {
"a.yml": (
"on: pull_request\njobs:\n one:\n name: build\n runs-on: ubuntu-latest\n"
" strategy:\n matrix:\n python: ['3.11', '3.12']\n"
" exclude: ${{ fromJson(vars.SKIP) }}\n"
),
}
found: Final = blind_spots(sources)
assert collisions(sources) == ()
assert len(found) == 1
assert "a matrix `exclude` is itself an expression" in found[0]
def test_an_include_that_is_itself_an_expression_is_reported_rather_than_ignored() -> None:
sources: Final = {
"a.yml": (
"on: pull_request\njobs:\n one:\n name: build-${{ matrix.python }}\n runs-on: ubuntu-latest\n"
" strategy:\n matrix:\n python: ['3.11']\n"
" include: ${{ fromJson(vars.EXTRA) }}\n"
),
}
found: Final = blind_spots(sources)
assert collisions(sources) == ()
assert len(found) == 1
assert "a matrix `include` is itself an expression" in found[0]