From f64cd798b277f4084a8b357e2e3f0935996c5c57 Mon Sep 17 00:00:00 2001 From: Cristian Girlea Date: Thu, 15 Oct 2026 10:24:46 +0300 Subject: [PATCH 1/2] test: narrow the runner-shape guards to runs-on values and local steps The guard against a self-hosted runner read the whole workflow text, so a comment saying "self-hosted" failed it; it now reads only runs-on values. The guard against the Compose install action checked that no .github/actions directory exists, which also failed on a checkout with leftover untracked files; it now checks that no step uses a local path. --- tests/python/test_workflows.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/tests/python/test_workflows.py b/tests/python/test_workflows.py index 2ccb963..16dacfe 100644 --- a/tests/python/test_workflows.py +++ b/tests/python/test_workflows.py @@ -43,22 +43,25 @@ def test_every_job_runs_on_github_hosted_ubuntu(self): self.assertEqual([line for line in lines if line.startswith("runs-on:")], [RUNS_ON]) def test_no_workflow_names_a_self_hosted_runner_or_a_runner_variable(self): - # A `runs-on` expression is how a self-hosted runner or a fallback to one would come back. + # A `runs-on` expression is how a self-hosted runner or a fallback to one would come back. Only the + # `runs-on` values are read for the label, so a comment may say "self-hosted". for path in WORKFLOWS: text = path.read_text(encoding="utf-8") with self.subTest(workflow=path.name): self.assertNotIn("vars.CI_RUNNER", text) self.assertNotIn("runner.environment", text) - self.assertNotRegex(text, r"(?i)self-hosted") self.assertNotRegex(text, r"runs-on: *\$\{\{") self.assertNotRegex(text, r"runs-on: *\[") + for line in re.findall(r"^\s*runs-on:.*$", text, re.MULTILINE): + self.assertNotIn("self-hosted", line.lower(), line) - def test_no_workflow_installs_compose_through_a_local_action(self): + def test_no_step_uses_a_local_action(self): # GitHub's runner images ship the Docker Compose plugin; the lab-only install action is gone with the lab. - self.assertFalse((REPO / ".github" / "actions").exists()) + # What matters is that no step runs one, not whether a directory exists in a checkout. for path in WORKFLOWS: - with self.subTest(workflow=path.name): - self.assertNotIn(".github/actions/", path.read_text(encoding="utf-8")) + for name, lines in jobs(path.read_text(encoding="utf-8")).items(): + with self.subTest(workflow=path.name, job=name): + self.assertEqual([line for line in lines if re.match(r"- uses: *\./", line)], []) def test_every_job_that_runs_compose_checks_the_repository_out_first(self): for path in WORKFLOWS: From be7d2dcce9ffb560e1aa2e368ebdf5d76d656c97 Mon Sep 17 00:00:00 2001 From: Cristian Girlea Date: Thu, 15 Oct 2026 10:29:23 +0300 Subject: [PATCH 2/2] test: catch a local action after name: and check every runs-on line The review found that a step written as name: then uses: loses its dash once the parser strips the line, so the local-action check missed it, as it missed a quoted path. The runs-on check now compares every runs-on line in the file with the expected value, so a block form or a job the parser skipped cannot hide a self-hosted label. --- tests/python/test_workflows.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/python/test_workflows.py b/tests/python/test_workflows.py index 16dacfe..b3354c5 100644 --- a/tests/python/test_workflows.py +++ b/tests/python/test_workflows.py @@ -52,8 +52,10 @@ def test_no_workflow_names_a_self_hosted_runner_or_a_runner_variable(self): self.assertNotIn("runner.environment", text) self.assertNotRegex(text, r"runs-on: *\$\{\{") self.assertNotRegex(text, r"runs-on: *\[") + # Every runs-on line in the file, whatever jobs() made of the job around it: a block form + # (`runs-on:` followed by `- self-hosted`) is a bare `runs-on:` line, which is not RUNS_ON. for line in re.findall(r"^\s*runs-on:.*$", text, re.MULTILINE): - self.assertNotIn("self-hosted", line.lower(), line) + self.assertEqual(line.strip(), RUNS_ON, line) def test_no_step_uses_a_local_action(self): # GitHub's runner images ship the Docker Compose plugin; the lab-only install action is gone with the lab. @@ -61,7 +63,8 @@ def test_no_step_uses_a_local_action(self): for path in WORKFLOWS: for name, lines in jobs(path.read_text(encoding="utf-8")).items(): with self.subTest(workflow=path.name, job=name): - self.assertEqual([line for line in lines if re.match(r"- uses: *\./", line)], []) + # A step's `uses:` may follow its `name:` (no dash once stripped) and may quote the path. + self.assertEqual([line for line in lines if re.match(r"""(?:-\s+)?uses:\s*['"]?\./""", line)], []) def test_every_job_that_runs_compose_checks_the_repository_out_first(self): for path in WORKFLOWS: