name: PR Test (Arm64) on: push: branches: [ main ] pull_request: branches: [ main ] workflow_dispatch: workflow_call: inputs: ref: description: 'Git ref (branch, tag, or SHA) to test. If not provided, uses the default branch.' required: false type: string default: '' run_all_tests: description: "Run all tests (for releasing or testing purpose)" required: false type: boolean default: false concurrency: group: pr-test-arm64-${{ inputs.ref || github.ref }} cancel-in-progress: false jobs: check-changes: runs-on: ubuntu-latest outputs: main_package: ${{ steps.filter.outputs.main_package || steps.run-mode.outputs.run_all_tests}} steps: - name: Checkout code uses: actions/checkout@v4 with: ref: ${{ inputs.ref || github.ref }} - name: Determine run mode id: run-mode run: | if [[ "${{ inputs.run_all_tests }}" == "true" ]]; then echo "run_all_tests=true" >> $GITHUB_OUTPUT echo "Run mode: ALL TESTS (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: - "python/sglang/!(multimodal_gen)/**/!(*.md)" - "python/pyproject_cpu.toml" - "test/**/!(*.md)" - "sgl-kernel/**/*.!(md|txt)" - ".github/workflows/pr-test-arm64.yml" - "docker/arm64.Dockerfile" pr-gate: needs: check-changes if: needs.check-changes.outputs.main_package == 'true' uses: ./.github/workflows/pr-gate.yml secrets: inherit build-test: needs: [check-changes, pr-gate] if: needs.check-changes.outputs.main_package == 'true' runs-on: ubuntu-24.04-arm steps: - name: Checkout repository uses: actions/checkout@v4 with: ref: ${{ inputs.ref || github.ref }} - name: Build container run: | PR_REPO=${{ github.event.pull_request.head.repo.clone_url }} PR_HEAD_REF=${{ github.head_ref }} docker build \ ${PR_REPO:+--build-arg SGLANG_REPO=$PR_REPO} \ ${PR_HEAD_REF:+--build-arg VER_SGLANG=$PR_HEAD_REF} \ . -f docker/arm64.Dockerfile -t sglang_arm64 --no-cache - name: Run container run: | docker run -dt \ -v ${{ github.workspace }}:/sglang-checkout/ --ipc=host \ --name ci_sglang_arm64 \ sglang_arm64 - name: Arm sanity check timeout-minutes: 5 run: | docker exec -w /sglang-checkout/ ci_sglang_arm64 \ bash -c "source /opt/.venv/bin/activate && python3 -c 'import platform; import torch; import sgl_kernel; from sglang.srt.utils.common import is_host_cpu_arm64; assert platform.machine() in (\"aarch64\", \"arm64\"); assert is_host_cpu_arm64(); assert hasattr(torch.ops.sgl_kernel, \"decode_attention_cpu\"); assert hasattr(torch.ops.sgl_kernel, \"initialize\");'" - name: Run unit tests timeout-minutes: 36 run: | docker exec -w /sglang-checkout/ ci_sglang_arm64 \ bash -c "source /opt/.venv/bin/activate && cd ./test && python3 run_suite.py --hw cpu --suite base-b-test-cpu-arm64 --timeout-per-file 1500" - name: Change permission timeout-minutes: 2 run: | docker exec -u root ci_sglang_arm64 bash -c " rm -rf /tmp/ci-home && chown -R $(id -u):$(id -g) /sglang-checkout/ 2>/dev/null || true " - name: Cleanup container if: always() run: | docker rm -f ci_sglang_arm64 || true