fix(ci): run existing script contracts in quick checks (#7203)

* fix(ci): share quick checks and lint workflows

* fix(ci): install actionlint from its verified release

* fix(ci): reject dependencies on required quick checks

* fix(ci): run existing script contracts in quick checks
This commit is contained in:
Zhengchao An
2026-09-06 00:50:06 +08:00
committed by GitHub
parent a6b5da64f2
commit 8f763fb1a2
3 changed files with 21 additions and 19 deletions
+9 -5
View File
@@ -567,7 +567,7 @@ def check_quick_checks(root: Path) -> list[str]:
errors.append(f"{relative}: missing composite action")
return errors
steps = yaml_block(runs, "steps", 2) or []
for command in ("shellcheck --version && actionlint", "./scripts/check_error_other_format_ratchet.sh"):
for command in ("shellcheck --version && actionlint", "./scripts/check_error_other_format_ratchet.sh", "make script-tests"):
step = workflow_step_block(steps, command, key="run", indent=4)
if step is None:
errors.append(f"{relative}: missing direct execution of {command}")
@@ -906,6 +906,7 @@ class SelfTests(unittest.TestCase):
" - name: Lint workflows\n shell: bash\n run: shellcheck --version && actionlint\n"
" - name: Error format ratchet\n shell: bash\n"
" run: ./scripts/check_error_other_format_ratchet.sh\n"
" - name: Script tests\n shell: bash\n run: make script-tests\n"
)
sources = {
".github/workflows/ci.yml": caller.replace(
@@ -964,6 +965,8 @@ class SelfTests(unittest.TestCase):
"only installed actionlint": action.replace("run: shellcheck --version && actionlint", "run: echo actionlint"),
"missing shellcheck preflight": action.replace("shellcheck --version && ", ""),
"missing ratchet": action.replace("run: ./scripts/check_error_other_format_ratchet.sh", "run: echo skipped"),
"missing script tests": action.replace("run: make script-tests", "run: echo skipped"),
"swallowed script failure": action.replace("run: make script-tests", "run: make script-tests || true"),
"swallowed lint failure": action.replace("&& actionlint", "&& actionlint || true"),
"swallowed ratchet failure": action.replace("ratchet.sh", "ratchet.sh || true"),
"conditional lint": action.replace("run: shellcheck", "if: false\n run: shellcheck"),
@@ -973,7 +976,7 @@ class SelfTests(unittest.TestCase):
"name: Lint workflows", "name: |\n run: shellcheck --version && actionlint"
).replace("\n run: shellcheck --version && actionlint\n", "\n run: shellcheck --version && actionlint\n || true\n"),
}
for command in ("shellcheck --version && actionlint", "./scripts/check_error_other_format_ratchet.sh"):
for command in ("shellcheck --version && actionlint", "./scripts/check_error_other_format_ratchet.sh", "make script-tests"):
for key in ("'if' : false", '"if": false', "'continue-on-error': true", '"continue-on-error" : true'):
mutations[f"quoted {command} {key}"] = action.replace(f"run: {command}", f"{key}\n run: {command}")
for separator in ("", "\n", " # continued command\n"):
@@ -994,9 +997,10 @@ class SelfTests(unittest.TestCase):
root = Path(tmp)
(root / "scripts").mkdir()
commands = ("shellcheck", "actionlint", "./scripts/check_error_other_format_ratchet.sh")
for failing in commands:
(root / "Makefile").write_text(".PHONY: script-tests\nscript-tests:\n\texit 17\n")
for failing in (*commands, "make script-tests"):
with self.subTest(command=failing):
run = "shellcheck --version && actionlint" if failing != commands[-1] else failing
run = "shellcheck --version && actionlint" if failing in ("shellcheck", "actionlint") else failing
step = workflow_step_block(steps, run, key="run", indent=4)
self.assertIsNotNone(step)
run_index = next(index for index, line in enumerate(step[1]) if line.startswith(" run:"))
@@ -1011,7 +1015,7 @@ class SelfTests(unittest.TestCase):
cwd=root, env=dict(os.environ, PATH=f"{root}{os.pathsep}{os.environ['PATH']}"),
capture_output=True, text=True,
)
self.assertEqual(result.returncode, 17, result.stderr)
self.assertEqual(result.returncode, 2 if failing == "make script-tests" else 17, result.stderr)
def test_validate_includes_quick_checks(self) -> None:
error = "Quick Checks wiring regression"