From f7338c5e5db1b652b0f9262ce9616420b7c3795f Mon Sep 17 00:00:00 2001 From: "Molecule AI Dev Engineer A (Kimi)" Date: Mon, 8 Jun 2026 23:14:37 +0000 Subject: [PATCH] ci(test-ops-scripts): fail-closed when unittest collects 0 tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces the exit-code-5 guard (which never fired under Python 3.12) with a count-based fail-closed check: - scripts/ — SKIP when no test_*.py files exist; FAIL when files exist but 0 tests are collected (broken import / empty file). - scripts/ops — FAIL when >0 tests are not collected. Also removes the continue-on-error mask so the gate is actually blocking. Fixes #2448 Co-Authored-By: Claude Opus 4.8 --- .gitea/workflows/test-ops-scripts.yml | 31 ++++++++++++++++++--------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/.gitea/workflows/test-ops-scripts.yml b/.gitea/workflows/test-ops-scripts.yml index a788eb72f..d664372be 100644 --- a/.gitea/workflows/test-ops-scripts.yml +++ b/.gitea/workflows/test-ops-scripts.yml @@ -48,9 +48,8 @@ jobs: test: name: Ops scripts (unittest) runs-on: ubuntu-latest - # Phase 3 (RFC #219 §1): surface broken workflows without blocking. - # mc#1982: pre-existing continue-on-error mask; root-fix and remove, do not renew silently. - continue-on-error: true + # mc#1982: removed continue-on-error; this gate now fails closed. + continue-on-error: false steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 @@ -61,19 +60,31 @@ jobs: - name: Run scripts/ unittests, if any # Top-level scripts/ tests live alongside their target file. The # runtime packaging tests moved to molecule-ai-workspace-runtime, so - # this pass may legitimately find no tests. + # this pass may legitimately find no tests. We fail-closed: no files + # → SKIP; files present but 0 collected → FAIL (broken import/empty). working-directory: scripts run: | - set +e - python -m unittest discover -t . -p 'test_*.py' -v - rc=$? - if [ "$rc" -eq 5 ]; then + files=$(find . -maxdepth 1 -name 'test_*.py' | wc -l) + count=$(python3 -c "import unittest; print(unittest.TestLoader().discover('.', pattern='test_*.py').countTestCases())") + if [ "$files" -eq 0 ]; then echo "No top-level scripts/ unittest files found; skipping." exit 0 fi - exit "$rc" + if [ "$count" -eq 0 ]; then + echo "FAIL: test files present but 0 tests collected (broken import / empty test file)." + exit 1 + fi + python3 -m unittest discover -t . -p 'test_*.py' -v - name: Run scripts/ops/ unittests (sweep_cf_decide, ...) + # Fail-closed: assert >0 tests collected so deletion or broken import + # cannot pass green by running 0 tests. working-directory: scripts/ops - run: python -m unittest discover -p 'test_*.py' -v + run: | + count=$(python3 -c "import unittest; print(unittest.TestLoader().discover('.', pattern='test_*.py').countTestCases())") + if [ "$count" -eq 0 ]; then + echo "FAIL: ops scripts tests collected 0 tests (broken import / missing test files)." + exit 1 + fi + python3 -m unittest discover -p 'test_*.py' -v - name: Run .gitea/scripts pytest suite run: python -m pytest .gitea/scripts/tests -q -- 2.52.0