From 063653ff996c506a3f31a4917be358063d64f52e Mon Sep 17 00:00:00 2001 From: gouyt13clear Date: Wed, 21 Oct 2026 22:59:12 +0800 Subject: [PATCH] ci: summarize Python matrix for stable required checks --- .github/scripts/test_ci_aggregates.py | 29 ++++++++++++++++++++------- .github/workflows/python.yml | 19 ++++++++++++++++++ docs/maintaining.md | 14 +++++++++---- 3 files changed, 51 insertions(+), 11 deletions(-) diff --git a/.github/scripts/test_ci_aggregates.py b/.github/scripts/test_ci_aggregates.py index 9cd0cde1..dbebcfb6 100644 --- a/.github/scripts/test_ci_aggregates.py +++ b/.github/scripts/test_ci_aggregates.py @@ -7,16 +7,29 @@ import unittest from pathlib import Path -WORKFLOW = Path(__file__).resolve().parents[1] / "workflows" / "test.yaml" +WORKFLOWS = Path(__file__).resolve().parents[1] / "workflows" class MatrixSummaryTest(unittest.TestCase): def test_matrix_verdicts_and_dependencies(self): - workflow = WORKFLOW.read_text() - for job, dependency in ( - ("clang-result", "clang"), - ("core-consumer-result", "core-consumer"), + for filename, job, dependency, output, selection_var in ( + ("test.yaml", "clang-result", "clang", "cpp", "CPP_SELECTED"), + ( + "test.yaml", + "core-consumer-result", + "core-consumer", + "cpp", + "CPP_SELECTED", + ), + ( + "python.yml", + "python-result", + "python-build", + "python_build", + "PYTHON_SELECTED", + ), ): + workflow = (WORKFLOWS / filename).read_text() block = re.search( rf"^ {job}:\n(.*?)(?=^ [\w-]+:|\Z)", workflow, @@ -26,7 +39,9 @@ def test_matrix_verdicts_and_dependencies(self): self.assertIn("if: ${{ always() }}", block) self.assertIn(f"MATRIX_RESULT: ${{{{ needs.{dependency}.result }}}}", block) self.assertIn("CHANGES_RESULT: ${{ needs.changes.result }}", block) - self.assertIn("CPP_SELECTED: ${{ needs.changes.outputs.cpp }}", block) + self.assertIn( + f"{selection_var}: ${{{{ needs.changes.outputs.{output} }}}}", block + ) command = textwrap.dedent(block.split(" run: |\n", 1)[1]) for detection in ("success", "failure", "cancelled", "skipped"): for selected in ("true", "false", ""): @@ -47,7 +62,7 @@ def test_matrix_verdicts_and_dependencies(self): env=dict( os.environ, CHANGES_RESULT=detection, - CPP_SELECTED=selected, + **{selection_var: selected}, MATRIX_RESULT=matrix, ), capture_output=True, diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 391cc83d..08df90ea 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -78,6 +78,25 @@ jobs: tests/python/test_qgkmeans.py::test_train_populates_faiss_style_outputs tests/python/test_rabitqkmeans.py::test_flat_parameters_and_outputs + python-result: + name: Python validation + needs: [changes, python-build] + if: ${{ always() }} + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Require selected Python versions + env: + CHANGES_RESULT: ${{ needs.changes.result }} + PYTHON_SELECTED: ${{ needs.changes.outputs.python_build }} + MATRIX_RESULT: ${{ needs.python-build.result }} + run: | + if [ "$CHANGES_RESULT" = success ] && [ "$PYTHON_SELECTED" = false ]; then + test "$MATRIX_RESULT" = skipped || test "$MATRIX_RESULT" = success + else + test "$MATRIX_RESULT" = success + fi + python-windows: needs: changes if: ${{ !cancelled() && (needs.changes.result != 'success' || needs.changes.outputs.python_build == 'true') }} diff --git a/docs/maintaining.md b/docs/maintaining.md index 39889a1f..d88ea96f 100644 --- a/docs/maintaining.md +++ b/docs/maintaining.md @@ -70,17 +70,23 @@ coverage, not a performance result or proof of every SIMD backend executing. ## Matrix summary checks -`Clang validation` and `Core and FastScan validation` provide stable check names -for the corresponding matrices. They run even when a dependency fails or is +`Clang validation`, `Core and FastScan validation`, and `Python validation` +provide stable check names for the corresponding matrices. `Python validation` +covers the Linux Python 3.11/3.14 source-install matrix; Windows Python and wheel +checks retain their separate gates. They run even when a dependency fails or is skipped. A successful matrix passes. A skipped matrix passes only when change -detection succeeded and explicitly selected no C++ checks; failure, cancellation, +detection succeeded and explicitly selected no checks for that matrix +(`cpp` or `python_build`); failure, cancellation, or an unexpected skip fails the summary. If detection fails, the existing fallback runs the matrix and its success is required. After these checks have appeared and been validated on GitHub, add their exact names to main's required status checks. Workflow definitions do not update branch protection automatically. Keep existing protections until that transition is -complete; these summaries do not cover unrelated jobs. +complete; these summaries do not cover unrelated jobs. Once `Python validation` +is verified, replace the individual required `Python 3.11` and `Python 3.14` +contexts with it: a skipped matrix does not emit those expanded names, which +otherwise leaves documentation-only PRs waiting indefinitely. ## Publishing a release