Adding precise prefix cache indexer observability metrics #7407
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Matrix jobs (e2e-image-common, e2e-image-router) are each | |
| # followed by a *-status job that aggregates their result, since GitHub | |
| # required status checks cannot reference individual matrix legs. | |
| name: CI - Test | |
| on: | |
| push: | |
| branches: | |
| - main | |
| - 'release-*' | |
| pull_request: | |
| branches: | |
| - main | |
| permissions: | |
| contents: read | |
| actions: read | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| check-changes: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| src: ${{ steps.filter.outputs.src }} | |
| helm: ${{ steps.filter.outputs.helm }} | |
| steps: | |
| - name: Checkout source | |
| uses: actions/checkout@v7 | |
| - uses: dorny/paths-filter@v4 | |
| id: filter | |
| with: | |
| filters: | | |
| src: | |
| - '**/*.go' | |
| - Dockerfile.* | |
| - Makefile* | |
| - go.mod | |
| - go.sum | |
| - scripts/** | |
| - hack/** | |
| - test/** | |
| - .github/actions/docker-build-and-push/action.yml | |
| - .github/actions/e2e-runner-setup/action.yml | |
| - .github/workflows/ci-pr-checks.yaml | |
| - '!Dockerfile.coordinator' | |
| - '!Makefile.coord.mk' | |
| - '!cmd/coordinator/**' | |
| - '!pkg/coordinator/**' | |
| - '!test/coordinator/**' | |
| helm: | |
| - 'config/charts/**' | |
| - 'hack/verify-helm.sh' | |
| - '.github/workflows/ci-pr-checks.yaml' | |
| verify-helm-charts: | |
| needs: check-changes | |
| if: ${{ needs.check-changes.outputs.helm == 'true' && (github.event_name == 'pull_request' || (github.event_name == 'push' && github.ref == 'refs/heads/main')) }} | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout source | |
| uses: actions/checkout@v7 | |
| - name: Set up Go | |
| uses: actions/setup-go@v7 | |
| with: | |
| go-version-file: go.mod | |
| - name: Run make verify-helm-charts | |
| run: make verify-helm-charts | |
| test: | |
| needs: check-changes | |
| if: ${{ needs.check-changes.outputs.src == 'true' }} | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 60 | |
| steps: | |
| - name: Checkout source | |
| uses: actions/checkout@v7 | |
| - name: Create Go cache dirs | |
| id: go-cache | |
| run: | | |
| mkdir -p "$HOME/.cache/llm-d-gomodcache" "$HOME/.cache/llm-d-gobuildcache" | |
| echo "mod=$HOME/.cache/llm-d-gomodcache" >> "$GITHUB_OUTPUT" | |
| echo "build=$HOME/.cache/llm-d-gobuildcache" >> "$GITHUB_OUTPUT" | |
| - name: Cache Go modules and build cache | |
| uses: actions/cache@v6 | |
| with: | |
| path: | | |
| ${{ steps.go-cache.outputs.mod }} | |
| ${{ steps.go-cache.outputs.build }} | |
| key: go-cache-${{ runner.os }}-${{ hashFiles('go.sum') }} | |
| restore-keys: | | |
| go-cache-${{ runner.os }}- | |
| # Missing cache is not an error; compare-coverage.sh reports all | |
| # components as new and exits 0. | |
| - name: Restore main branch coverage baseline | |
| if: github.event_name == 'pull_request' | |
| uses: actions/cache/restore@v6 | |
| with: | |
| path: coverage/baseline | |
| key: coverage-main | |
| - name: Run unit tests | |
| shell: bash | |
| env: | |
| GO_MOD_CACHE_VOL: ${{ steps.go-cache.outputs.mod }} | |
| GO_BUILD_CACHE_VOL: ${{ steps.go-cache.outputs.build }} | |
| run: make test-unit | |
| # Anti-rot: execute the benchmark bodies once so runtime breakage (panics, | |
| # deadlocks) is caught. `go test` only compiles benchmarks; it never runs | |
| # them without -bench. | |
| - name: Run benchmark smoke | |
| shell: bash | |
| env: | |
| GO_MOD_CACHE_VOL: ${{ steps.go-cache.outputs.mod }} | |
| GO_BUILD_CACHE_VOL: ${{ steps.go-cache.outputs.build }} | |
| run: make bench-smoke | |
| - name: Run hermetic integration tests | |
| shell: bash | |
| env: | |
| GO_MOD_CACHE_VOL: ${{ steps.go-cache.outputs.mod }} | |
| GO_BUILD_CACHE_VOL: ${{ steps.go-cache.outputs.build }} | |
| run: make test-integration-hermetic | |
| - name: Compare coverage against main baseline | |
| id: coverage-gate | |
| if: github.event_name == 'pull_request' | |
| continue-on-error: true | |
| shell: bash | |
| run: make coverage-compare BASELINE_DIR=coverage/baseline | |
| - name: Find latest release branch | |
| if: github.event_name == 'pull_request' | |
| id: find-releases | |
| shell: bash | |
| run: | | |
| gh api "repos/${{ github.repository }}/branches" \ | |
| --paginate \ | |
| --jq '[.[] | select(.name | test("^release-[0-9]")) | .name][]' \ | |
| | sort -V | tail -1 > /tmp/release_branches.txt | |
| echo "Release branches found:" | |
| cat /tmp/release_branches.txt | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| - name: Download and compare release coverage baselines | |
| if: github.event_name == 'pull_request' | |
| shell: bash | |
| run: | | |
| if [[ ! -s /tmp/release_branches.txt ]]; then | |
| echo "No release branches found, skipping." | |
| exit 0 | |
| fi | |
| while IFS= read -r branch; do | |
| [[ -z "$branch" ]] && continue | |
| echo "Looking up latest successful run for branch: $branch" | |
| run_id=$(gh run list \ | |
| --repo "${{ github.repository }}" \ | |
| --branch "$branch" \ | |
| --workflow "ci-pr-checks.yaml" \ | |
| --status success \ | |
| --limit 1 \ | |
| --json databaseId \ | |
| --jq '.[0].databaseId // empty') | |
| if [[ -z "$run_id" ]]; then | |
| echo "No successful run found for $branch, skipping." | |
| continue | |
| fi | |
| dest="coverage/release-baselines/$branch" | |
| mkdir -p "$dest" | |
| if gh run download "$run_id" \ | |
| --repo "${{ github.repository }}" \ | |
| --name "coverage-baseline-$branch" \ | |
| --dir "$dest"; then | |
| make coverage-compare BASELINE_DIR="$dest" COVERAGE_LABEL="$branch" | |
| else | |
| echo "No coverage artifact for $branch in run $run_id, skipping." | |
| fi | |
| done < /tmp/release_branches.txt | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| - name: Stage coverage baseline for caching | |
| if: github.ref == 'refs/heads/main' && github.event_name == 'push' | |
| shell: bash | |
| run: | | |
| mkdir -p coverage/baseline | |
| cp coverage/*.out coverage/baseline/ | |
| - name: Save coverage baseline (main branch only) | |
| if: github.ref == 'refs/heads/main' && github.event_name == 'push' | |
| uses: actions/cache/save@v6 | |
| with: | |
| path: coverage/baseline | |
| key: coverage-main | |
| - name: Upload coverage artifact (release branches) | |
| if: >- | |
| github.event_name == 'push' && | |
| startsWith(github.ref, 'refs/heads/release-') | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: coverage-baseline-${{ github.ref_name }} | |
| path: coverage/*.out | |
| retention-days: 400 | |
| overwrite: true | |
| - name: Enforce coverage gate | |
| if: github.event_name == 'pull_request' && steps.coverage-gate.outcome == 'failure' | |
| run: | | |
| echo "::error::Coverage regression detected -- see the coverage report in the job summary above." | |
| exit 1 | |
| e2e-image-common: | |
| needs: check-changes | |
| if: ${{ needs.check-changes.outputs.src == 'true' }} | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| image: | |
| - name: builder | |
| source: build | |
| docker-file: Dockerfile.builder | |
| image-name: llm-d-builder | |
| archive: llm-d-builder | |
| - name: epp | |
| source: build | |
| docker-file: Dockerfile.epp | |
| image-name: llm-d-router-endpoint-picker | |
| archive: llm-d-router-endpoint-picker | |
| - name: simulator | |
| source: pull | |
| image: ghcr.io/llm-d/llm-d-inference-sim:v0.10.2 | |
| archive: llm-d-inference-sim | |
| name: e2e-image-common (${{ matrix.image.name }}) | |
| steps: | |
| - name: Checkout source | |
| if: ${{ matrix.image.source == 'build' }} | |
| uses: actions/checkout@v7 | |
| - name: Build ${{ matrix.image.name }} image | |
| if: ${{ matrix.image.source == 'build' }} | |
| uses: ./.github/actions/docker-build-and-push | |
| with: | |
| docker-file: ${{ matrix.image.docker-file }} | |
| image-name: ${{ matrix.image.image-name }} | |
| tag: dev | |
| registry: ghcr.io/llm-d | |
| push: 'false' | |
| buildx-outputs: type=docker,dest=${{ runner.temp }}/${{ matrix.image.archive }}.tar | |
| commit-sha: ${{ github.sha }} | |
| - name: Pull ${{ matrix.image.name }} image | |
| if: ${{ matrix.image.source == 'pull' }} | |
| run: | | |
| docker pull --platform linux/amd64 "${{ matrix.image.image }}" | |
| docker save "${{ matrix.image.image }}" -o "${{ runner.temp }}/${{ matrix.image.archive }}.tar" | |
| - name: Upload ${{ matrix.image.name }} image | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: e2e-image-${{ matrix.image.name }} | |
| path: ${{ runner.temp }}/${{ matrix.image.archive }}.tar | |
| retention-days: 1 | |
| compression-level: 0 | |
| e2e-image-common-status: | |
| needs: e2e-image-common | |
| if: always() | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check e2e-image-common result | |
| run: | | |
| result="${{ needs.e2e-image-common.result }}" | |
| if [[ "$result" != "success" && "$result" != "skipped" ]]; then | |
| echo "::error::e2e-image-common failed for at least one matrix image" | |
| exit 1 | |
| fi | |
| e2e-image-router: | |
| needs: check-changes | |
| if: ${{ needs.check-changes.outputs.src == 'true' }} | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| image: | |
| - name: sidecar | |
| source: build | |
| docker-file: Dockerfile.sidecar | |
| image-name: llm-d-router-disagg-sidecar | |
| archive: llm-d-router-disagg-sidecar | |
| - name: renderer | |
| source: pull | |
| image: vllm/vllm-openai-cpu:v0.21.0 | |
| archive: vllm-openai-cpu | |
| name: e2e-image-router (${{ matrix.image.name }}) | |
| steps: | |
| - name: Checkout source | |
| if: ${{ matrix.image.source == 'build' }} | |
| uses: actions/checkout@v7 | |
| - name: Build ${{ matrix.image.name }} image | |
| if: ${{ matrix.image.source == 'build' }} | |
| uses: ./.github/actions/docker-build-and-push | |
| with: | |
| docker-file: ${{ matrix.image.docker-file }} | |
| image-name: ${{ matrix.image.image-name }} | |
| tag: dev | |
| registry: ghcr.io/llm-d | |
| push: 'false' | |
| buildx-outputs: type=docker,dest=${{ runner.temp }}/${{ matrix.image.archive }}.tar | |
| commit-sha: ${{ github.sha }} | |
| - name: Pull ${{ matrix.image.name }} image | |
| if: ${{ matrix.image.source == 'pull' }} | |
| run: | | |
| docker pull --platform linux/amd64 "${{ matrix.image.image }}" | |
| docker save "${{ matrix.image.image }}" -o "${{ runner.temp }}/${{ matrix.image.archive }}.tar" | |
| - name: Upload ${{ matrix.image.name }} image | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: e2e-image-${{ matrix.image.name }} | |
| path: ${{ runner.temp }}/${{ matrix.image.archive }}.tar | |
| retention-days: 1 | |
| compression-level: 0 | |
| e2e-image-router-status: | |
| needs: e2e-image-router | |
| if: always() | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check e2e-image-router result | |
| run: | | |
| result="${{ needs.e2e-image-router.result }}" | |
| if [[ "$result" != "success" && "$result" != "skipped" ]]; then | |
| echo "::error::e2e-image-router failed for at least one matrix image" | |
| exit 1 | |
| fi | |
| e2e-router: | |
| needs: | |
| - check-changes | |
| - e2e-image-common | |
| - e2e-image-router | |
| if: ${{ needs.check-changes.outputs.src == 'true' }} | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 45 | |
| steps: | |
| - name: Checkout source | |
| uses: actions/checkout@v7 | |
| - name: Set up e2e runner | |
| id: e2e-setup | |
| uses: ./.github/actions/e2e-runner-setup | |
| - name: Download builder image | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: e2e-image-builder | |
| path: ${{ runner.temp }}/e2e-images | |
| - name: Download EPP image | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: e2e-image-epp | |
| path: ${{ runner.temp }}/e2e-images | |
| - name: Download sidecar image | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: e2e-image-sidecar | |
| path: ${{ runner.temp }}/e2e-images | |
| - name: Download simulator image | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: e2e-image-simulator | |
| path: ${{ runner.temp }}/e2e-images | |
| - name: Download renderer image | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: e2e-image-renderer | |
| path: ${{ runner.temp }}/e2e-images | |
| - name: Load e2e images | |
| shell: bash | |
| run: | | |
| for image in "${RUNNER_TEMP}"/e2e-images/*.tar; do | |
| docker load --input "$image" | |
| done | |
| - name: Run e2e-router | |
| shell: bash | |
| env: | |
| GO_MOD_CACHE_VOL: ${{ steps.e2e-setup.outputs.go-mod-cache }} | |
| GO_BUILD_CACHE_VOL: ${{ steps.e2e-setup.outputs.go-build-cache }} | |
| PULL_VLLM_RENDER_IMAGE: "false" | |
| HF_TOKEN: ${{ secrets.HF_TOKEN }} | |
| run: make test-e2e-run |