name: Check Changes on: workflow_call: inputs: git_ref: type: string default: '' run_all_tests: type: boolean default: false force_continue_on_error: type: boolean default: false pr_test_yml: description: 'Workflow YAML whose stage `run_timeout_minutes` drives partition sizing.' type: string default: '.github/workflows/pr-test.yml' outputs: main_package: value: ${{ jobs.run.outputs.main_package }} sgl_kernel: value: ${{ jobs.run.outputs.sgl_kernel }} jit_kernel: value: ${{ jobs.run.outputs.jit_kernel }} multimodal_gen: value: ${{ jobs.run.outputs.multimodal_gen }} partitions: value: ${{ jobs.run.outputs.partitions }} partition_model_sha: value: ${{ jobs.run.outputs.partition_model_sha }} runs_on_map: value: ${{ jobs.run.outputs.runs_on_map }} enable_retry: value: ${{ jobs.run.outputs.enable_retry }} continue_on_error: value: ${{ jobs.run.outputs.continue_on_error }} jobs: run: name: check-changes runs-on: ubuntu-latest outputs: main_package: ${{ steps.filter.outputs.main_package || steps.run-mode.outputs.run_all_tests }} sgl_kernel: ${{ steps.filter.outputs.sgl_kernel }} jit_kernel: ${{ steps.filter.outputs.jit_kernel || steps.run-mode.outputs.run_all_tests }} multimodal_gen: ${{ steps.filter.outputs.multimodal_gen || steps.run-mode.outputs.run_all_tests }} partitions: ${{ steps.partitions.outputs.partitions }} partition_model_sha: ${{ steps.partition-model-sha.outputs.sha }} runs_on_map: ${{ steps.runner-map.outputs.runs_on_map }} enable_retry: ${{ steps.set-retry.outputs.enable_retry }} continue_on_error: ${{ steps.set-continue-on-error.outputs.continue_on_error }} steps: - name: Checkout code uses: actions/checkout@v4 with: ref: ${{ inputs.git_ref || github.sha }} - uses: ./.github/actions/check-maintenance - name: Determine run mode id: run-mode run: | # Run all tests for scheduled runs and workflow_call (when ref input is provided) # Note: github.event_name is inherited from caller, so we detect workflow_call by checking inputs.git_ref if [[ "${{ github.event_name }}" == "schedule" || "${{ inputs.run_all_tests }}" == "true" ]]; then echo "run_all_tests=true" >> $GITHUB_OUTPUT echo "Run mode: ALL TESTS (schedule=${{ github.event_name == 'schedule' }}, run_all_tests=${{ inputs.run_all_tests }})" else echo "run_all_tests=false" >> $GITHUB_OUTPUT echo "Run mode: FILTERED (triggered by ${{ github.event_name }})" fi - name: Detect file changes id: filter uses: dorny/paths-filter@v3 if: steps.run-mode.outputs.run_all_tests != 'true' with: filters: | main_package: - ".github/workflows/pr-test.yml" - ".github/workflows/pr-gate.yml" - ".github/actions/**" - "python/pyproject.toml" - "python/sglang/!(multimodal_gen)/**/!(*.md)" - "scripts/ci/cuda/*" - "scripts/ci/utils/*" - "test/**/!(*.md)" multimodal_gen: - ".github/workflows/pr-test.yml" - ".github/workflows/pr-test-multimodal-gen.yml" - "python/pyproject.toml" - "python/sglang/multimodal_gen/**/!(*.md|*.ipynb)" - "python/sglang/srt/model_executor/runner_backend_utils/breakable_cuda_graph/**" - "python/sglang/srt/observability/**" - "python/sglang/jit_kernel/**" - "test/registered/jit/diffusion/**" - "test/registered/jit/benchmark/diffusion/**" - "python/sglang/cli/**" jit_kernel: - ".github/workflows/pr-test.yml" - ".github/workflows/pr-test-jit-kernel.yml" - "python/pyproject.toml" - "python/sglang/jit_kernel/**" - "test/registered/jit/**" sgl_kernel: # Intentionally excludes ".github/workflows/pr-test-sgl-kernel.yml" — # see API-side detector below for rationale. - "sgl-kernel/**/!(*.md|THIRDPARTYNOTICES.txt|LICENSE)" - name: Determine full-parallel mode id: parallel-mode run: | # `full=true` lifts the matrix-fanout throttle so each suite's # max_parallel = size. Conditions: # 1. Scheduled cron run. # 2. run_all_tests run (manual full dispatch / release) -- a full # run should mirror the cron's parallelism, not just its test set. # 3. pull_request event with the `high priority` label. FULL=false if [[ "${{ github.event_name }}" == "schedule" ]]; then FULL=true echo "Scheduled run -> full parallelism" elif [[ "${{ inputs.run_all_tests }}" == "true" ]]; then FULL=true echo "run_all_tests -> full parallelism" elif [[ "${{ github.event_name }}" == "pull_request" && "${{ contains(github.event.pull_request.labels.*.name, 'high priority') }}" == "true" ]]; then FULL=true echo "high priority PR -> full parallelism" fi echo "full=$FULL" >> "$GITHUB_OUTPUT" - name: Resolve sglang-ci-stats SHA id: partition-model-sha env: GH_TOKEN: ${{ github.token }} run: | # Pin all shards to one immutable commit so dispatch and every # runtime LPT use the same model snapshot. Soft fail -> static. SHA=$(gh api repos/sgl-project/sglang-ci-stats/commits/main --jq '.sha' 2>/dev/null || true) if [[ -n "$SHA" ]]; then echo "Pinned sglang-ci-stats@$SHA" echo "sha=$SHA" >> "$GITHUB_OUTPUT" else echo "::warning::Could not resolve sglang-ci-stats SHA; using in-source est_time" echo "sha=" >> "$GITHUB_OUTPUT" fi - name: Fetch live partition model if: steps.partition-model-sha.outputs.sha != '' run: | # SHA resolved -> require fetch (curl --retry). Soft fallback # would risk cross-shard LPT divergence on transient curl flake. rm -f /tmp/partition-model.json URL="https://raw.githubusercontent.com/sgl-project/sglang-ci-stats/${{ steps.partition-model-sha.outputs.sha }}/model.json" curl --fail --silent --show-error --max-time 15 --retry 3 --retry-delay 2 \ "$URL" -o /tmp/partition-model.json echo "Fetched partition-model.json ($(wc -c < /tmp/partition-model.json) bytes)" - name: Compute partitions id: partitions run: | # Emit a single JSON output `partitions` keyed by suite name with # {size, arr, max_parallel} fields per suite. Replaces the prior # full/low max-parallel presets; `--full-parallel` keeps the # `high priority` PR / scheduled cron escape hatch. # See scripts/ci/utils/compute_partitions.py. python3 scripts/ci/utils/compute_partitions.py \ --full-parallel ${{ steps.parallel-mode.outputs.full }} \ --partition-model-file /tmp/partition-model.json \ --pr-test-yml ${{ inputs.pr_test_yml }} \ >> "$GITHUB_OUTPUT" - name: Set B200 runner tag id: set-runner run: | # Use kernel-build runner only when sgl_kernel changes are detected. sgl_kernel="${{ steps.filter.outputs.sgl_kernel }}" if [[ "$sgl_kernel" == "true" ]]; then echo "b200_runner=4-gpu-b200-kernel" >> $GITHUB_OUTPUT else echo "b200_runner=4-gpu-b200" >> $GITHUB_OUTPUT fi - name: Build runs_on_map (resolves $b200_runner sentinel) id: runner-map run: | python3 scripts/ci/runner_configs.py --map \ '${{ steps.set-runner.outputs.b200_runner }}' \ >> "$GITHUB_OUTPUT" - name: Enable retry for CI id: set-retry run: | echo "enable_retry=true" >> $GITHUB_OUTPUT echo "Retry logic enabled for CI" - name: Set continue-on-error for full test runs id: set-continue-on-error run: | if [[ "${{ steps.run-mode.outputs.run_all_tests }}" == "true" || "${{ inputs.force_continue_on_error }}" == "true" ]]; then echo "continue_on_error=true" >> $GITHUB_OUTPUT echo "Full test run or force flag detected, enabling continue-on-error to run all tests" else echo "continue_on_error=false" >> $GITHUB_OUTPUT echo "Filtered run, continue-on-error disabled" fi - name: Show filter results in summary (table) run: | { echo "## Change Detection" echo "" echo "| Component | Changed |" echo "|-------------------|---------|" echo "| main_package | ${{ steps.filter.outputs.main_package || steps.run-mode.outputs.run_all_tests }} |" echo "| sgl_kernel | ${{ steps.filter.outputs.sgl_kernel }} |" echo "| jit_kernel | ${{ steps.filter.outputs.jit_kernel || steps.run-mode.outputs.run_all_tests }} |" echo "| multimodal_gen | ${{ steps.filter.outputs.multimodal_gen || steps.run-mode.outputs.run_all_tests }} |" echo "| b200_runner | ${{ steps.set-runner.outputs.b200_runner }} |" echo "| enable_retry | ${{ steps.set-retry.outputs.enable_retry }} |" echo "| continue_on_error | ${{ steps.set-continue-on-error.outputs.continue_on_error }} |" } >> $GITHUB_STEP_SUMMARY