From 8e72fe3d41c0599635200806300cbcb4611a8788 Mon Sep 17 00:00:00 2001 From: Chemaclass Date: Thu, 13 Aug 2026 20:39:39 +0200 Subject: [PATCH 1/2] test(ci): fail when a CI-path extractor stops matching The guards collect workflow paths that do not resolve and assert the set is empty, so an extractor that stops matching finds nothing to check and the assertion holds. Renaming the test_path: pattern left all three tests in this file green -- nothing went red at all. This file exists because CI path rot has shipped twice: #960 moving paths, and coverage.yml globbing in a shell step while its non-blocking nightly run sat red for days. Assert both extractors still find what they parse. The floors sit under the current counts: 18 test_path: keys, and 3 distinct tests/ references once the workflows are deduplicated -- fewer than it looks, because most jobs share the same paths. Verified against two mutations: a broken test_path: pattern, and a workflow directory that does not exist. Closes #1161 --- tests/unit/project/ci_test_paths_test.sh | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/unit/project/ci_test_paths_test.sh b/tests/unit/project/ci_test_paths_test.sh index e9967ad1..7d374202 100644 --- a/tests/unit/project/ci_test_paths_test.sh +++ b/tests/unit/project/ci_test_paths_test.sh @@ -38,6 +38,23 @@ function ci_test_paths() { grep -oE 'test_path: "[^"]+"' "$WORKFLOW" | sed 's/test_path: "//; s/"$//' } +# Both checks below collect what did NOT resolve and assert that set is empty, +# so an extractor that stops matching -- the `test_path:` key renamed, the +# workflow directory moved -- makes them pass by finding nothing to check. +# Proven by mutation: breaking the `test_path:` pattern leaves all three tests +# in this file green, and this file exists because CI path rot has shipped +# twice already (#960, and the coverage.yml case documented below). +# +# The floors sit under the current counts -- 18 `test_path:` keys, and 3 +# distinct `tests/` references once the workflows are deduplicated (fewer than +# it looks, because most jobs share the same paths). They catch an extractor +# returning nothing, which is what rot looks like. +function test_the_extractors_still_find_the_paths_they_parse() { + assert_greater_than 8 "$(cd "$ROOT_DIR" && ci_test_paths | wc -l)" + assert_greater_than 1 "$(cd "$ROOT_DIR" && ci_referenced_test_paths | wc -l)" +} + + function test_every_ci_test_path_resolves_to_at_least_one_test_file() { local unresolved="" local line From 3a8cc7a3086fb2d975b7bacc9e240f09dff75625 Mon Sep 17 00:00:00 2001 From: Chemaclass Date: Thu, 13 Aug 2026 20:50:03 +0200 Subject: [PATCH 2/2] test(ci): make the workflow-path extractor work on BusyBox grep The new guard failed on Alpine, and the reason is the bug it was written to find: BusyBox grep does not honour --include, so `grep -r ... --include='*.yml'` produced nothing there and 'every tests/ path a workflow names resolves' had been passing on Alpine by having no paths to check. The workflows directory is flat, so an explicit glob is equivalent on GNU grep and works on BusyBox. Verified in an alpine:3 container: 0 paths before, 3 after, matching macOS. --- tests/unit/project/ci_test_paths_test.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/unit/project/ci_test_paths_test.sh b/tests/unit/project/ci_test_paths_test.sh index 7d374202..f2ec54b7 100644 --- a/tests/unit/project/ci_test_paths_test.sh +++ b/tests/unit/project/ci_test_paths_test.sh @@ -112,7 +112,11 @@ function ci_referenced_test_paths() { # The match is anchored on a boundary so `sample_tests/pass_test.sh` -- a file # test-action.yml writes at runtime -- is not read as a `tests/` path. An # unanchored `tests/` matched its tail and reported it missing. - "$GREP" -rhv '^[[:space:]]*#' "$ROOT_DIR"/.github/workflows/ --include='*.yml' 2>/dev/null | + # An explicit glob rather than `-r --include`: BusyBox grep does not honour + # --include, so on Alpine this produced nothing at all and the check below + # passed by having no paths to resolve. The directory is flat, so the glob + # is equivalent everywhere else (#1161). + "$GREP" -hv '^[[:space:]]*#' "$ROOT_DIR"/.github/workflows/*.yml 2>/dev/null | "$GREP" -oE '(^|[[:space:]"'"'"'=])tests/[A-Za-z0-9_*/.-]+' | sed 's/^[^t]//' | LC_ALL=C sort -u }