From 56df6db28b3425e81547c33c173e41ae747e93a8 Mon Sep 17 00:00:00 2001 From: Ashwini Rathi Date: Fri, 25 Sep 2026 09:13:42 +0300 Subject: [PATCH] [XPU] Detect per-commit XPU tests dynamically in CI path filter --- .github/workflows/pr-test-xpu.yml | 17 ++++++-- scripts/ci/xpu/detect_xpu_test_changes.py | 51 +++++++++++++++++++++++ 2 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 scripts/ci/xpu/detect_xpu_test_changes.py diff --git a/.github/workflows/pr-test-xpu.yml b/.github/workflows/pr-test-xpu.yml index 9b2530101a38..110ece20f7b4 100644 --- a/.github/workflows/pr-test-xpu.yml +++ b/.github/workflows/pr-test-xpu.yml @@ -28,8 +28,8 @@ jobs: check-changes: runs-on: ubuntu-latest outputs: - changes_exist: ${{ steps.filter.outputs.main_package == 'true' || steps.filter.outputs.multimodal_gen == 'true' || steps.run-mode.outputs.run_all_tests == 'true' }} - main_package: ${{ steps.filter.outputs.main_package == 'true' || steps.run-mode.outputs.run_all_tests == 'true' }} + changes_exist: ${{ steps.filter.outputs.main_package == 'true' || steps.filter.outputs.multimodal_gen == 'true' || steps.xpu-tests.outputs.changed == 'true' || steps.run-mode.outputs.run_all_tests == 'true' }} + main_package: ${{ steps.filter.outputs.main_package == 'true' || steps.xpu-tests.outputs.changed == 'true' || steps.run-mode.outputs.run_all_tests == 'true' }} multimodal_gen: ${{ steps.filter.outputs.multimodal_gen == 'true' || steps.run-mode.outputs.run_all_tests == 'true' }} steps: - name: Checkout code @@ -54,9 +54,13 @@ jobs: uses: dorny/paths-filter@v3 if: steps.run-mode.outputs.run_all_tests != 'true' with: + list-files: json filters: | + # Baseline list below; any other changed test/registered/ file with a + # per-commit register_xpu_ci is also picked up by the next step. + registered_tests: + - "test/registered/**/*.py" main_package: - # Extend test/registered/ entries when adding a non-nightly register_xpu_ci. - "python/sglang/!(multimodal_gen|kernels|cli|test)/**/!(*.md)" - "python/sglang/test/*.py" - "python/sglang/test/!(ascend|observability|mock_model|manual|external_models|kernels)/**/!(*.md)" @@ -94,6 +98,13 @@ jobs: - "docker/xpu.Dockerfile" - "scripts/ci/xpu/**" + - name: Detect changed per-commit XPU tests + id: xpu-tests + if: steps.filter.outputs.registered_tests == 'true' + env: + CHANGED_FILES: ${{ steps.filter.outputs.registered_tests_files }} + run: echo "changed=$(python3 scripts/ci/xpu/detect_xpu_test_changes.py)" >> "$GITHUB_OUTPUT" + # ==================== PR Gate ==================== # pr-gate: needs: check-changes diff --git a/scripts/ci/xpu/detect_xpu_test_changes.py b/scripts/ci/xpu/detect_xpu_test_changes.py new file mode 100644 index 000000000000..e17dbe585379 --- /dev/null +++ b/scripts/ci/xpu/detect_xpu_test_changes.py @@ -0,0 +1,51 @@ +"""Decide whether changed test files need per-commit XPU CI. + +Reads a JSON list of changed paths (dorny/paths-filter `list-files: json`) +from the CHANGED_FILES env var or argv[1], and prints `true` if any of them +carries a non-nightly `register_xpu_ci`, else `false`. +""" + +import json +import os +import sys +from pathlib import Path + +REPO_ROOT = Path(__file__).resolve().parents[3] + +# ci_register.py is stdlib-only; import it directly (bypassing the sglang +# package __init__, which pulls in torch) so this runs on ubuntu-latest. +sys.path.insert(0, str(REPO_ROOT / "python" / "sglang" / "test" / "ci")) + +from ci_register import HWBackend, ut_parse_one_file # noqa: E402 + + +def xpu_per_commit_files(paths): + hits = [] + for rel in paths: + path = REPO_ROOT / rel + # Deleted files cannot be parsed; the job no longer runs them anyway. + if path.suffix != ".py" or not path.is_file(): + continue + try: + registries, _ = ut_parse_one_file(str(path)) + except (SyntaxError, ValueError) as e: + # Unparseable test file: run XPU CI so run_suite surfaces the error. + print(f"::warning::{rel}: {e}", file=sys.stderr) + hits.append(rel) + continue + if any(r.backend == HWBackend.XPU and not r.nightly for r in registries): + hits.append(rel) + return hits + + +def main(): + raw = sys.argv[1] if len(sys.argv) > 1 else os.environ.get("CHANGED_FILES", "") + paths = json.loads(raw) if raw.strip() else [] + hits = xpu_per_commit_files(paths) + for rel in hits: + print(f"XPU per-commit test changed: {rel}", file=sys.stderr) + print("true" if hits else "false") + + +if __name__ == "__main__": + main()