[CI] Speed up dependency install: dual-ABI Rust ext cache and prevalidation pruning (#33619)

This commit is contained in:
Liangsheng Yin
2026-08-04 20:33:48 -07:00
committed by GitHub
parent 6c05aaae7e
commit 1033cae8d5
11 changed files with 155 additions and 1371 deletions
+52 -23
View File
@@ -36,9 +36,9 @@ on:
type: string
default: rust-ext-x86_64
cache_key_prefix:
description: 'Cache key prefix. Callers share it on purpose to reuse each other''s build; it encodes the arch, since the modules are not portable across architectures.'
description: 'Cache key prefix. Callers share it on purpose to reuse each other''s build; it encodes the arch and the interpreter ABI set, since the modules are portable across neither.'
type: string
default: rust-ext-x86_64
default: rust-ext-x86_64-cp310-cp312
max_glibc:
description: 'Highest GLIBC symbol version the built .so files may require. Set by the oldest test runner image, jammy at glibc 2.35 - the pools are not all on one image.'
type: string
@@ -102,6 +102,26 @@ jobs:
path: python/sglang/srt/*/_core*.so
key: ${{ inputs.cache_key_prefix }}-${{ hashFiles('rust/**', 'python/setup.py') }}
# On a miss: different hash = rust/setup.py moved; no entries = evicted.
- name: Report cache lookup
env:
GH_TOKEN: ${{ github.token }}
PRIMARY_KEY: ${{ steps.cache.outputs.cache-primary-key }}
MATCHED_KEY: ${{ steps.cache.outputs.cache-matched-key }}
KEY_PREFIX: ${{ inputs.cache_key_prefix }}
run: |
if [ -n "${MATCHED_KEY}" ]; then
echo "hit: ${MATCHED_KEY}"
ls -l python/sglang/srt/*/_core*.so
else
echo "miss: ${PRIMARY_KEY}"
echo "entries under ${KEY_PREFIX}- (created / ref / size / key):"
gh cache list --repo "${GITHUB_REPOSITORY}" --key "${KEY_PREFIX}-" \
--limit 15 --json createdAt,ref,sizeInBytes,key \
--jq '.[] | [.createdAt, .ref, ((.sizeInBytes / 1048576 | floor | tostring) + " MiB"), .key] | @tsv' \
|| echo "(gh cache list unavailable: token lacks actions:read)"
fi
# No MAX_GLIBC: these are the bytes the compile job already checked before
# saving them under this key. The module count is still worth re-checking,
# so a truncated entry fails here rather than as a test import error.
@@ -139,15 +159,20 @@ jobs:
- uses: ./.github/actions/check-maintenance
# No crate sets abi3, so the ABI tag is minor-version specific and only the
# pools on this version can use the result - h20 ships 3.12 and falls back to
# compiling during install. Pinned rather than left to the image so the tag is
# at least predictable.
# No crate sets abi3, so build one module set per interpreter the pools
# run (h100 ships 3.10, h20 ships 3.12); EXT_SUFFIX keeps them apart.
- name: Set up Python 3.10
id: py310
uses: actions/setup-python@v5
with:
python-version: '3.10'
- name: Set up Python 3.12
id: py312
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install protoc and Rust toolchain
run: bash scripts/ci/utils/install_rust_protoc.sh
@@ -155,32 +180,36 @@ jobs:
run: |
set -euxo pipefail
export PATH="${CARGO_HOME:-$HOME/.cargo}/bin:${PATH}"
# Same path ci_install_dependency.sh uses, so a runner that also runs test
# stages keeps one warm cache. Its guard is repeated here because nothing
# prunes the tree on a runner that only ever builds.
export CARGO_TARGET_DIR="${HOME}/.cache/sglang-cargo-target"
mkdir -p "${CARGO_TARGET_DIR}"
used="$(df --output=pcent "${CARGO_TARGET_DIR}" 2>/dev/null | tr -dc '0-9')"
# Per-interpreter subdirs (set in the loop): PyO3's fingerprint tracks
# the interpreter, so a shared dir rebuilds on every ABI switch.
cargo_target_root="${HOME}/.cache/sglang-cargo-target"
mkdir -p "${cargo_target_root}"
used="$(df --output=pcent "${cargo_target_root}" 2>/dev/null | tr -dc '0-9')"
if [ "${used:-0}" -ge 85 ]; then
echo "cargo target dir filesystem at ${used}%; dropping ${CARGO_TARGET_DIR}"
rm -rf "${CARGO_TARGET_DIR}"
mkdir -p "${CARGO_TARGET_DIR}"
echo "cargo target dir filesystem at ${used}%; dropping ${cargo_target_root}"
rm -rf "${cargo_target_root}"
mkdir -p "${cargo_target_root}"
fi
python3 -m pip install --upgrade pip
command -v uv >/dev/null 2>&1 || pip install uv
# build_rust needs only the build backend, not sglang's ~294 runtime deps.
# Per-job path: these runners are persistent and shared, so a fixed one
# both inherits the previous job's venv and races a concurrent build.
venv="${RUNNER_TEMP:-/tmp}/sglang-ci-rust-ext-${GITHUB_RUN_ID:-norun}-$$"
venv_root="${RUNNER_TEMP:-/tmp}/sglang-ci-rust-ext-${GITHUB_RUN_ID:-norun}-$$"
# Best-effort, like ci_cleanup_venv.sh: under set -e a failing EXIT trap
# would fail the step, and nothing here is worth keeping for a postmortem.
trap 'rm -rf "${venv}" || true' EXIT
uv venv "${venv}" --python python3.10 --seed
# shellcheck disable=SC1091
source "${venv}/bin/activate"
uv pip install "setuptools>=61.0" "setuptools-rust>=1.10" "setuptools-scm>=8.0" wheel
cd python
SGLANG_BUILD_RUST_EXTS=all python setup.py build_rust --inplace
trap 'rm -rf "${venv_root}" || true' EXIT
for python_bin in "${{ steps.py310.outputs.python-path }}" "${{ steps.py312.outputs.python-path }}"; do
minor="$("${python_bin}" -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")')"
export CARGO_TARGET_DIR="${cargo_target_root}/py${minor}"
venv="${venv_root}/py${minor}"
uv venv "${venv}" --python "${python_bin}" --seed
# shellcheck disable=SC1091
source "${venv}/bin/activate"
uv pip install "setuptools>=61.0" "setuptools-rust>=1.10" "setuptools-scm>=8.0" wheel
(cd python && SGLANG_BUILD_RUST_EXTS=all python setup.py build_rust --inplace)
deactivate
done
- name: Verify modules and stage for upload
env:
+5 -2
View File
@@ -10,6 +10,8 @@ on:
paths:
- 'rust/**'
- 'python/setup.py'
# The key's prefix lives in this file, so a bump there also moves the key.
- '.github/workflows/_pr-test-rust-ext-build.yml'
workflow_dispatch:
# Only the newest merge needs to seed; earlier ones are already stale.
@@ -17,9 +19,10 @@ concurrency:
group: seed-rust-ext-cache
cancel-in-progress: true
# Declaring permissions at all drops everything not listed, and check-maintenance
# needs issues: read to reach the maintenance issue.
# Declaring permissions at all drops everything not listed. issues: read for
# check-maintenance; actions: read for the restore job's gh cache list.
permissions:
actions: read
contents: read
issues: read