From 906b740bb5a0627e48b28d56909fe9c41977f6da Mon Sep 17 00:00:00 2001 From: gouyt13clear Date: Wed, 21 Oct 2026 21:02:52 +0800 Subject: [PATCH] ci: refine support-file triggers and lint coverage --- .github/scripts/ci_changes.py | 27 +++++++++++++++++++++-- .github/scripts/test_ci_changes.py | 35 ++++++++++++++++++++++++++++++ .github/workflows/test.yaml | 9 +++++++- docs/development.md | 6 ++--- docs/maintaining.md | 9 +++++++- scripts/check-python.sh | 8 +++++-- 6 files changed, 85 insertions(+), 9 deletions(-) diff --git a/.github/scripts/ci_changes.py b/.github/scripts/ci_changes.py index aad7260b..04a08ac6 100644 --- a/.github/scripts/ci_changes.py +++ b/.github/scripts/ci_changes.py @@ -35,7 +35,12 @@ def classify(paths): for path in paths: if path.startswith("docs/") or path.endswith(".md"): continue - if path in (".github/workflows/docs.yml", ".github/release.yml", "LICENSE"): + if path.startswith(".github/ISSUE_TEMPLATE/") or path in ( + ".github/workflows/docs.yml", + ".github/release.yml", + ".github/CODEOWNERS", + "LICENSE", + ): continue if path in ( ".github/workflows/changes.yml", @@ -44,7 +49,24 @@ def classify(paths): ".editorconfig", ): return set(GROUPS) - if path == "pyproject.toml": + if path == "benchmarks/plot_homepage.py": + selected.add("python_quality") + elif path in ( + "sample/run_cpp.sh", + "sample/run_python.sh", + "example.sh", + "example_py.sh", + ): + # These orchestration examples are linted, not used to build CI artifacts. + # Keep retired names for deletions in the complete push/PR diff. + selected.add("shell") + elif path in ("python/ivf.py", "python/utils/io.py"): + # Retired example locations; deletions still need example coverage. + selected.update(("python_quality", "python_build", "wheels")) + elif path.startswith("tests/fixtures/core_api_v1/"): + # Frozen compatibility fixture; excluded from clang-format by design. + selected.add("cpp") + elif path == "pyproject.toml": selected.update(("python_quality", "python_build", "wheels")) elif path == "CMakeLists.txt" or path.startswith("cmake/"): selected.update(("cpp", "cpp_tidy", "python_build", "wheels")) @@ -64,6 +86,7 @@ def classify(paths): "tests/dispatch/", "tests/common/", "tests/consumer/", + "tests/core_consumer/", "sample/cpp/", ) ) diff --git a/.github/scripts/test_ci_changes.py b/.github/scripts/test_ci_changes.py index 8dfa2341..0266cb60 100644 --- a/.github/scripts/test_ci_changes.py +++ b/.github/scripts/test_ci_changes.py @@ -24,6 +24,41 @@ def test_docs_only_skip_builds(self): set(), ) + def test_known_support_paths_do_not_select_unrelated_builds(self): + cases = { + ".github/ISSUE_TEMPLATE/config.yml": set(), + ".github/ISSUE_TEMPLATE/bug_report.yml": set(), + ".github/CODEOWNERS": set(), + "benchmarks/plot_homepage.py": {"python_quality"}, + "sample/run_cpp.sh": {"shell"}, + "sample/run_python.sh": {"shell"}, + "example.sh": {"shell"}, # Deleted paths still occur in a push diff. + "example_py.sh": {"shell"}, + "python/ivf.py": {"python_quality", "python_build", "wheels"}, + "python/utils/io.py": {"python_quality", "python_build", "wheels"}, + "tests/core_consumer/run.cmake": {"cpp"}, + "tests/fixtures/core_api_v1/consumer.cpp": {"cpp"}, + } + for path, expected in cases.items(): + with self.subTest(path=path): + self.assertEqual(classify([path]), expected) + + def test_support_paths_do_not_mask_source_or_unknown_changes(self): + support = [".github/ISSUE_TEMPLATE/config.yml", "benchmarks/plot_homepage.py"] + self.assertEqual( + classify(support + ["src/core/api.cpp"]), + { + "cpp", + "cpp_format", + "cpp_tidy", + "python_build", + "python_quality", + "wheels", + }, + ) + self.assertEqual(classify(support + ["unknown-build-input"]), set(GROUPS)) + self.assertEqual(classify(["benchmarks/new_kernel.cpp"]), set(GROUPS)) + def test_shared_code_runs_cpp_and_python(self): for path in ("include/rabitqlib/index/ivf/ivf.hpp", "src/simd/dispatch.cpp"): with self.subTest(path=path): diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 685be714..27d8c5d4 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -86,7 +86,14 @@ jobs: sudo apt-get update -qq sudo apt-get install -y shellcheck - name: Check scripts - run: shellcheck scripts/*.sh + run: | + files=(scripts/*.sh) + for runner in sample/run_cpp.sh sample/run_python.sh; do + if [[ -f "$runner" ]]; then + files+=("$runner") + fi + done + shellcheck "${files[@]}" ubuntu: needs: changes diff --git a/docs/development.md b/docs/development.md index 1a7f78b2..ae66bdac 100644 --- a/docs/development.md +++ b/docs/development.md @@ -234,8 +234,8 @@ To apply Python formatting and safe automatic lint fixes before running the check: ```bash -ruff check --fix python_bindings sample/python tests/python -ruff format python_bindings sample/python tests/python +ruff check --fix python_bindings sample/python tests/python benchmarks/plot_homepage.py +ruff format python_bindings sample/python tests/python benchmarks/plot_homepage.py ``` ## Shell scripts @@ -244,7 +244,7 @@ Run ShellCheck after changing a contributor or automation script: ```bash sudo apt-get install shellcheck -shellcheck scripts/*.sh +shellcheck scripts/*.sh sample/run_cpp.sh sample/run_python.sh ``` This matches CI's script set. Also pass any changed shell scripts outside diff --git a/docs/maintaining.md b/docs/maintaining.md index be6fcb62..d2b4244f 100644 --- a/docs/maintaining.md +++ b/docs/maintaining.md @@ -11,6 +11,10 @@ only the affected job groups: | Changes | Checks | | --- | --- | | Documentation and Markdown only | Documentation workflow for `docs/`; no C++ or Python builds | +| Issue forms/configuration and CODEOWNERS | No C++/Python builds | +| `benchmarks/plot_homepage.py` | Python lint, including the plotting script; no index or wheel builds | +| `sample/run_cpp.sh`, `sample/run_python.sh` | ShellCheck, including these runners | +| `tests/core_consumer/`, `tests/fixtures/core_api_v1/` | C++ checks; the frozen v1 fixture is excluded from formatting | | C++ headers or library sources | C++ formatting, clang-tidy, platform tests, sanitizers, consumer build, and Python builds/wheels | | C++ tests or examples | C++ formatting and platform tests; no clang-tidy | | Compiled Python bindings | C++ formatting and clang-tidy, plus Python builds and wheel tests | @@ -30,7 +34,10 @@ The optional include-cleaner report is available through `./scripts/check-includes.sh` and no longer runs on every C++ change. Shared headers still trigger broad regression suites; CI does not infer individual test dependencies from C++ function changes. Unknown paths run all -checks. Pushes compare the complete pushed range; pull requests compare against +checks. Retired example paths are recognized when deleted: `example.sh` and +`example_py.sh` select ShellCheck; `python/ivf.py` and `python/utils/io.py` select +Python example checks and wheels. Other unrecognized paths keep the full fallback. +Pushes compare the complete pushed range; pull requests compare against their base. Renames and deletions are included. Relevant jobs also run if change detection fails, so a detection error cannot silently waive a check. diff --git a/scripts/check-python.sh b/scripts/check-python.sh index 75ae6fd6..eb71fa52 100755 --- a/scripts/check-python.sh +++ b/scripts/check-python.sh @@ -18,5 +18,9 @@ if [[ "$($ruff --version)" != "ruff 0.16.1" ]]; then fi cd "$repo_root" -"$ruff" format --check python_bindings sample/python tests/python -"$ruff" check python_bindings sample/python tests/python +paths=(python_bindings sample/python tests/python) +if [[ -f benchmarks/plot_homepage.py ]]; then + paths+=(benchmarks/plot_homepage.py) +fi +"$ruff" format --check "${paths[@]}" +"$ruff" check "${paths[@]}"