Repository navigation
ci: build and qualify ROCm images through Slurm #2
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
| # SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | |
| # SPDX-License-Identifier: Apache-2.0 | |
| # | |
| # Licensed under the Apache License, Version 2.0 (the "License"); | |
| # you may not use this file except in compliance with the License. | |
| # You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, software | |
| # distributed under the License is distributed on an "AS IS" BASIS, | |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| # See the License for the specific language governing permissions and | |
| # limitations under the License. | |
| name: Pre Merge | |
| on: | |
| push: | |
| branches: | |
| - main | |
| - release/*.*.* | |
| pull_request: | |
| # Cancel any previous check runs for the same pull request to avoid redundant workflows. | |
| concurrency: | |
| group: ${{ github.event_name == 'pull_request' && format('{0}-{1}', github.workflow, github.event.pull_request.number) || format('{0}-{1}', github.workflow, github.run_id) }} | |
| cancel-in-progress: ${{ github.event_name == 'pull_request' }} | |
| jobs: | |
| changed-files: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| docs: ${{ steps.changes.outputs.docs }} | |
| examples: ${{ steps.changes.outputs.examples }} | |
| api_docs: ${{ steps.changes.outputs.api_docs }} | |
| fern_components: ${{ steps.changes.outputs.fern_components }} | |
| operator: ${{ steps.changes.outputs.operator }} | |
| rust: ${{ steps.changes.outputs.rust }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| # Do not use fetch-depth: 0 — changed-files now works with shallow clone | |
| - name: Check for changes | |
| id: changes | |
| uses: $/.github/actions/changed-files | |
| with: | |
| gh_token: ${{ github.token }} | |
| # Structural docs rules the Fern CLI does not cover: SPDX headers, frontmatter, body H1, | |
| # link scope, dangling nav paths, and internal references. Read-only, so it reports through | |
| # the job summary rather than a pull request comment. | |
| # | |
| # The step summary lists every finding; that is the surface to point readers at. | |
| # Inline annotations are best-effort on top of it, for two reasons: GitHub caps | |
| # workflow-command annotations at 10 per level per step, so a PR introducing 15 | |
| # errors surfaces only 10 in the diff, and the step scans all of docs/ rather | |
| # than the changed files, so a finding outside the diff has no line to attach to | |
| # and appears only in the run log. | |
| docs-lint: | |
| name: Docs Lint | |
| needs: changed-files | |
| if: needs.changed-files.outputs.docs == 'true' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 | |
| - name: Lint docs structure | |
| run: python3 docs/fern/scripts/docs_lint.py --scan docs --github | |
| pre-merge-status-check: | |
| runs-on: ubuntu-latest | |
| needs: [changed-files, pre-commit, recipe-check, api-docs, fern-check, fern-broken-links, docs-lint, operator, rust-tests, rust-clippy, docs-website-composition] | |
| if: always() | |
| steps: | |
| - name: "Check all dependent jobs" | |
| run: | | |
| echo '${{ toJson(needs) }}' | jq -e 'to_entries | map(.value.result) | all(. as $result | ["success", "skipped"] | any($result == .))' | |
| pre-commit: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 | |
| - uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1 | |
| timeout-minutes: 3 | |
| recipe-check: | |
| name: Recipe Check | |
| needs: changed-files | |
| if: needs.changed-files.outputs.examples == 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 | |
| with: | |
| python-version: '3.13' | |
| - name: Install recipe check dependencies | |
| # These packages provide options and warning types from the repository's | |
| # shared pytest configuration. The recipe tests themselves do not import | |
| # them. | |
| run: | | |
| python3 -m pip install \ | |
| 'pytest>=8.0' \ | |
| 'jinja2==3.1.6' \ | |
| 'jsonschema>=4' \ | |
| 'pyyaml>=6.0' \ | |
| 'pydantic>=2' \ | |
| 'pytest-asyncio>=1.0' \ | |
| 'pytest-benchmark>=4' \ | |
| 'pytest-timeout==2.4.0' | |
| - name: Install qualified Kustomize renderer | |
| run: | | |
| go install sigs.k8s.io/kustomize/kustomize/v5@v5.8.1 | |
| echo "KUSTOMIZE_BIN=$(go env GOPATH)/bin/kustomize" >> "$GITHUB_ENV" | |
| - name: Check generated recipe manifests | |
| run: python3 scripts/kustomize-matrix.py check | |
| - name: Test recipe generators and docs artifacts | |
| run: python3 -m pytest --noconftest tests/test_kustomize_matrix.py tests/test_generate_kustomize_openapi.py docs/tests/ | |
| api-docs: | |
| name: Generated API References | |
| needs: changed-files | |
| if: needs.changed-files.outputs.api_docs == 'true' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 | |
| with: | |
| python-version: '3.13' | |
| - name: Install API docs test dependencies | |
| # pydantic and pytest-benchmark satisfy the module-referencing | |
| # filterwarnings entries in the repository's pyproject.toml so pytest | |
| # can load them under the repository's shared config. fsspec backs the | |
| # storage.py doctest the suite executes. | |
| run: | | |
| python3 -m pip install \ | |
| 'griffe==2.1.0' \ | |
| 'pytest>=8.0' \ | |
| 'pyyaml>=6.0' \ | |
| 'pydantic>=2' \ | |
| 'pytest-asyncio>=1.0' \ | |
| 'pytest-benchmark>=4' \ | |
| 'fsspec' | |
| - name: Test generated API references | |
| # docs/fern/scripts/tests is an explicit path so it opts back into | |
| # collection despite the pyproject's docs/* ignore-glob (which keeps | |
| # the rendered docs site content out of the default suite). | |
| run: | | |
| python3 -m pytest -q \ | |
| docs/fern/scripts/tests/test_gen_python_api.py \ | |
| docs/fern/scripts/tests/test_gen_rust_api.py \ | |
| docs/fern/scripts/tests/test_gen_kubernetes_api.py \ | |
| docs/fern/scripts/tests/test_api_reference_regressions.py \ | |
| docs/fern/scripts/tests/test_api_freshness.py | |
| - name: Generate API references from source | |
| # The Python/Rust references are publish-time artifacts (generated in | |
| # fern-docs.yml against the branch being published), not committed | |
| # files, so there is no freshness to check on a PR. What a code PR CAN | |
| # break is generation itself -- a signature griffe cannot parse, a | |
| # removed module the curated list still names -- so run both | |
| # generators in write mode and fail the job if either errors. The | |
| # output lands in gitignored paths and is discarded with the runner. | |
| run: | | |
| set -euo pipefail | |
| python3 docs/fern/scripts/gen_python_api.py | |
| python3 docs/fern/scripts/gen_rust_api.py | |
| - name: Check generated Kubernetes API reference freshness | |
| # Unlike the Python/Rust pages, the Kubernetes reference regenerates | |
| # from a docs-owned source file and its output IS committed, so the | |
| # freshness gate stays. On a PR, --since scopes the gate to what the | |
| # branch itself changed (an unscoped gate reddens branches for merges | |
| # to main they never made). On push to main there is no base and none | |
| # is wanted: main is where global freshness must hold. | |
| # | |
| # The base commit is fetched explicitly because this job checks out | |
| # shallow. Without it the range cannot resolve, and the helper fails | |
| # closed to the strict gate -- safe, but the flag would do nothing. | |
| env: | |
| BASE_SHA: ${{ github.event.pull_request.base.sha }} | |
| run: | | |
| set -euo pipefail | |
| SINCE=() | |
| if [ -n "${BASE_SHA:-}" ]; then | |
| git fetch --no-tags --depth=1 origin "$BASE_SHA" 2>/dev/null || true | |
| if git cat-file -e "${BASE_SHA}^{commit}" 2>/dev/null; then | |
| SINCE=(--since "$BASE_SHA") | |
| else | |
| echo "::notice::base $BASE_SHA unavailable; using the strict gate" | |
| fi | |
| fi | |
| python3 docs/fern/scripts/gen_kubernetes_api.py --check "${SINCE[@]}" | |
| # Safe Fern docs checks run in pre-merge with read-only permissions. | |
| fern-check: | |
| name: Fern Configuration Check | |
| needs: changed-files | |
| if: needs.changed-files.outputs.docs == 'true' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 | |
| with: | |
| node-version: '22' | |
| - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 | |
| with: | |
| python-version: '3.13' | |
| - name: Generate API reference pages | |
| # index.yml's Reference tab points at the Python/Rust API pages, which | |
| # are publish-time artifacts (gitignored, not committed). fern check | |
| # validates that every nav path exists, so materialize them first. | |
| run: | | |
| python3 -m pip install 'griffe==2.1.0' | |
| python3 docs/fern/scripts/gen_python_api.py | |
| python3 docs/fern/scripts/gen_rust_api.py | |
| - name: Install Fern CLI | |
| run: npm install -g fern-api | |
| - name: Validate Fern configuration | |
| working-directory: docs/fern | |
| run: fern check | |
| - name: Cache the npm store for esbuild | |
| if: needs.changed-files.outputs.fern_components == 'true' | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 | |
| with: | |
| path: ~/.npm | |
| # Keyed on the pinned version, so bumping esbuild misses the cache | |
| # deliberately rather than serving a stale tarball for a new pin. | |
| key: npm-esbuild-0.24.0-${{ runner.os }} | |
| - name: Parse custom MDX components | |
| # Scoped to the narrow fern_components filter rather than the repo-wide | |
| # docs one: this step exercises component sources only, and on the docs | |
| # filter roughly 95% of its runs have no component change to check. | |
| if: needs.changed-files.outputs.fern_components == 'true' | |
| working-directory: docs/fern | |
| # `fern check` validates configuration and navigation, never component | |
| # syntax, so a component that does not compile merges green and only | |
| # surfaces when Fern builds the site. #12330 shipped a LandingStyles.tsx | |
| # whose CSS comment contained raw backticks that closed the enclosing | |
| # template literal; it took #12402 to repair. esbuild transforms each | |
| # file without bundling, which is exactly the syntax gate that was | |
| # missing. Keep the version pinned so a bad esbuild release cannot | |
| # redefine this gate. | |
| run: | | |
| set -euo pipefail | |
| # Installed rather than run through `npx --yes`, which re-fetches | |
| # 4.35 MB from the registry on every run with no integrity check. This | |
| # step is a hard dependency of pre-merge-status-check, so a registry | |
| # 5xx would red a PR that only touched an .mdx page. --no-save keeps | |
| # the tree clean (there is no package.json beside fern/), and the | |
| # npm cache below makes a warm run need no network at all. | |
| npm install --no-save --no-audit --no-fund esbuild@0.24.0 | |
| ESBUILD=./node_modules/.bin/esbuild | |
| # Same four suffixes Fern's bundler scans, and the same set | |
| # docs/fern/scripts/check_component_imports.py covers. Keep them aligned. | |
| find_components() { | |
| find components -type f \ | |
| \( -name '*.tsx' -o -name '*.ts' -o -name '*.jsx' -o -name '*.js' \) "$@" | |
| } | |
| COUNT=$(find_components | wc -l) | |
| if [ "$COUNT" -eq 0 ]; then | |
| echo "::error::No component sources found under docs/fern/components" | |
| exit 1 | |
| fi | |
| echo "Parsing $COUNT component sources" | |
| # Hoisted out of the xargs line: as a word on that command line the | |
| # command substitution's exit status is invisible to set -e, so a | |
| # failing mktemp expanded to --outdir= and esbuild ran anyway. | |
| OUTDIR=$(mktemp -d) | |
| # --outbase=. keeps the input tree structure under OUTDIR. Without it | |
| # every entry point is keyed by basename alone, so a future Foo.ts plus | |
| # Foo.tsx aborts the whole run with esbuild's "Two output files share | |
| # the same path" -- a red gate whose message has nothing to do with | |
| # component syntax. | |
| find_components -print0 \ | |
| | xargs -0 "$ESBUILD" --outbase=. --outdir="$OUTDIR" | |
| docs-website-composition: | |
| name: Docs Website Composition Check | |
| needs: changed-files | |
| if: needs.changed-files.outputs.docs == 'true' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| fetch-depth: 0 | |
| # The sync and release-version composition (rsync scopes, nav path | |
| # transforms, the shared-Reference machinery) only executes on main pushes | |
| # and tag cuts, so fern check pre-merge validates the source tree rather | |
| # than the tree that actually publishes. This replays both jobs against | |
| # docs-website and runs fern check on the composed result. | |
| - name: Fetch docs-website | |
| run: git fetch --no-tags --depth=1 origin docs-website:refs/remotes/origin/docs-website | |
| - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 | |
| with: | |
| node-version: '22' | |
| - name: Install Fern CLI | |
| run: npm install -g fern-api | |
| - name: Install yq | |
| run: | | |
| # Runner-owned bin dir: no sudo, and $GITHUB_PATH puts it ahead of | |
| # any preinstalled yq for the steps that follow. | |
| mkdir -p "$RUNNER_TEMP/bin" | |
| wget -qO "$RUNNER_TEMP/bin/yq" https://github.com/mikefarah/yq/releases/download/v4.52.5/yq_linux_amd64 | |
| chmod +x "$RUNNER_TEMP/bin/yq" | |
| echo "$RUNNER_TEMP/bin" >> "$GITHUB_PATH" | |
| - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 | |
| with: | |
| python-version: '3.13' | |
| - name: Install replay dependencies | |
| # The replay generates the publish-time Python/Rust API pages exactly | |
| # like the real sync job; the script hard-fails without griffe. pyyaml | |
| # must be reinstalled too: setup-python replaces the runner's system | |
| # python3 (which bundles PyYAML) on PATH, and the replay's | |
| # resolve_translation_links.py imports yaml. | |
| run: python3 -m pip install 'griffe==2.1.0' 'pyyaml>=6.0' | |
| - name: Replay the docs-website composition | |
| env: | |
| DOCS_WEBSITE_REF: origin/docs-website | |
| run: bash docs/fern/scripts/simulate_docs_website.sh | |
| fern-broken-links: | |
| name: Fern Broken Links Check | |
| needs: changed-files | |
| if: needs.changed-files.outputs.docs == 'true' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 | |
| with: | |
| node-version: '22' | |
| - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 | |
| with: | |
| python-version: '3.13' | |
| - name: Generate API reference pages | |
| # The committed API landing links relatively to the publish-time | |
| # Python/Rust pages; the broken-links checker resolves those through | |
| # the file graph, so materialize them first. | |
| run: | | |
| python3 -m pip install 'griffe==2.1.0' | |
| python3 docs/fern/scripts/gen_python_api.py | |
| python3 docs/fern/scripts/gen_rust_api.py | |
| - name: Install Fern CLI | |
| run: npm install -g fern-api | |
| - name: Check for broken links | |
| working-directory: docs/fern | |
| run: fern docs broken-links | |
| operator: | |
| needs: changed-files | |
| if: needs.changed-files.outputs.operator == 'true' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| fetch-depth: 0 # clustertest derives its alpha version from v1.3.0 | |
| - uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 | |
| - name: Run operator checks | |
| uses: $/.github/actions/check-deploy-component | |
| with: | |
| component: operator | |
| platform: linux/amd64 | |
| - name: Run operator envtests | |
| working-directory: deploy/operator | |
| run: make envtest | |
| rust-tests: | |
| needs: changed-files | |
| if: needs.changed-files.outputs.rust == 'true' | |
| runs-on: | |
| group: Fastchecker | |
| strategy: | |
| matrix: { dir: ['.', 'lib/bindings/python', 'lib/runtime/examples', 'lib/bindings/kvbm'] } | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| lfs: true | |
| - name: Set up system dependencies | |
| run: | | |
| # Install protoc for Rust build dependencies (NOTE: much faster than apt install) | |
| PB_REL="https://github.com/protocolbuffers/protobuf/releases" | |
| PROTOC_VER="30.2" | |
| PROTOC_ZIP="protoc-${PROTOC_VER}-linux-x86_64.zip" | |
| PROTOC_SHA256="327e9397c6fb3ea2a542513a3221334c6f76f7aa524a7d2561142b67b312a01f" | |
| curl --retry 5 --retry-delay 2 -fsSLO "$PB_REL/download/v${PROTOC_VER}/${PROTOC_ZIP}" | |
| echo "${PROTOC_SHA256} ${PROTOC_ZIP}" | sha256sum -c - | |
| unzip "${PROTOC_ZIP}" -d $HOME/.local | |
| rm "${PROTOC_ZIP}" | |
| export PATH="$PATH:$HOME/.local/bin" | |
| protoc --version | |
| - name: Cache cargo artifacts | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 | |
| with: | |
| path: | | |
| ~/.cargo/bin/ | |
| ~/.cargo/registry | |
| key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} | |
| restore-keys: ${{ runner.os }}-cargo- | |
| - name: Set up Rust Toolchain Components | |
| run: rustup component add rustfmt | |
| - name: Verify Code Formatting | |
| working-directory: ${{ matrix.dir }} | |
| run: cargo fmt -- --check | |
| - name: Install and Run cargo-deny | |
| working-directory: ${{ matrix.dir }} | |
| run: | | |
| cargo-deny --version || cargo install cargo-deny@0.19.0 | |
| cargo-deny -L error --all-features check licenses bans --config ${{ github.workspace }}/deny.toml | |
| # Have an explicit step to build tests first to separate time spent on build vs execution. | |
| - name: Compile Tests | |
| working-directory: ${{ matrix.dir }} | |
| run: cargo test --locked --no-run | |
| - name: Run Doc Tests | |
| working-directory: ${{ matrix.dir }} | |
| run: cargo doc --no-deps && cargo test --locked --doc | |
| - name: Run Unit Tests | |
| working-directory: ${{ matrix.dir }} | |
| # NOTE: --all-targets doesn't run doc tests | |
| run: cargo test --locked --all-targets | |
| - name: Check isolated kv-router feature builds | |
| if: matrix.dir == '.' | |
| working-directory: ${{ matrix.dir }} | |
| # Workspace feature unification hides these; check each on its own. | |
| run: | | |
| cargo check --locked -p dynamo-kv-router --no-default-features --features standalone-slot-tracker | |
| cargo check --locked -p dynamo-kv-router --no-default-features --features standalone-indexer | |
| - name: Run standalone slot-tracker feature tests | |
| if: matrix.dir == '.' | |
| working-directory: ${{ matrix.dir }} | |
| # No workspace member requests standalone-slot-tracker, so it needs an explicit run here. | |
| run: cargo test --locked -p dynamo-kv-router --features standalone-slot-tracker --lib 'services::' | |
| - name: Run canonical replay feature tests | |
| if: matrix.dir == '.' | |
| working-directory: ${{ matrix.dir }} | |
| run: | | |
| cargo test --locked -p dynamo-bench --features replay-bench \ | |
| --bench offline_replay_bench -- \ | |
| testdata/mooncake_trace_tiny.jsonl \ | |
| --iterations 2 \ | |
| --canonical-reports-jsonl "$RUNNER_TEMP/canonical-replay.jsonl" | |
| - name: Run Python bindings AIC feature tests | |
| if: matrix.dir == 'lib/bindings/python' | |
| working-directory: ${{ matrix.dir }} | |
| run: cargo test --locked --features aic-forward-pass -- --nocapture | |
| - name: Compile feature-gated benchmark entrypoints | |
| if: matrix.dir == '.' | |
| working-directory: ${{ matrix.dir }} | |
| run: | | |
| compile_bench() { | |
| feature="$1" | |
| shift | |
| cargo test --locked -p dynamo-bench --no-default-features \ | |
| --features "$feature" "$@" --no-run | |
| } | |
| compile_bench multiturn --bench multiturn_bench | |
| compile_bench satf --bin request_trace_to_satf | |
| compile_bench request-trace-to-mooncake --bin request_trace_to_mooncake | |
| compile_bench weka-to-agentic-mooncake --bin weka_to_agentic_mooncake | |
| compile_bench offline-replay --bench offline_replay_bench | |
| compile_bench mooncake --bench mooncake_bench | |
| compile_bench active-sequences --bench active_sequences_bench | |
| compile_bench dc-ckf-consumer --bin dc_ckf_consumer_bench | |
| compile_bench dc-ckf-relay --bench dc_ckf_relay_bench | |
| cargo test --locked --no-default-features -p dynamo-bench \ | |
| --features request-trace-to-mooncake --test request_trace_to_mooncake | |
| cargo test --locked --no-default-features -p dynamo-bench \ | |
| --features weka-to-agentic-mooncake --test weka_to_agentic_mooncake | |
| cargo test --locked -p dynamo-llm --no-default-features \ | |
| --features kv-router-stress --bench kv_router_bench --no-run | |
| rust-clippy: | |
| needs: changed-files | |
| if: needs.changed-files.outputs.rust == 'true' | |
| runs-on: | |
| group: Fastchecker | |
| strategy: | |
| matrix: { dir: ['.', 'lib/bindings/python', 'lib/runtime/examples', 'lib/bindings/kvbm'] } | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| lfs: true | |
| - name: Verify Cargo lock file is in sync | |
| working-directory: ${{ matrix.dir }} | |
| run: cargo metadata --locked --format-version 1 | |
| - name: Set up system dependencies | |
| run: | | |
| # Install protoc for Rust build dependencies (NOTE: much faster than apt install) | |
| PB_REL="https://github.com/protocolbuffers/protobuf/releases" | |
| PROTOC_VER="30.2" | |
| PROTOC_ZIP="protoc-${PROTOC_VER}-linux-x86_64.zip" | |
| PROTOC_SHA256="327e9397c6fb3ea2a542513a3221334c6f76f7aa524a7d2561142b67b312a01f" | |
| curl --retry 5 --retry-delay 2 -fsSLO "$PB_REL/download/v${PROTOC_VER}/${PROTOC_ZIP}" | |
| echo "${PROTOC_SHA256} ${PROTOC_ZIP}" | sha256sum -c - | |
| unzip "${PROTOC_ZIP}" -d $HOME/.local | |
| rm "${PROTOC_ZIP}" | |
| export PATH="$PATH:$HOME/.local/bin" | |
| protoc --version | |
| - name: Cache cargo artifacts | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 | |
| with: | |
| path: | | |
| ~/.cargo/bin/ | |
| ~/.cargo/registry | |
| key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} | |
| restore-keys: ${{ runner.os }}-cargo- | |
| - name: Set up Rust Toolchain Components | |
| run: rustup component add clippy | |
| - name: Run Clippy Checks | |
| working-directory: ${{ matrix.dir }} | |
| run: cargo clippy --no-deps --all-targets -- -D warnings | |
| - name: Run Python bindings AIC feature clippy | |
| if: matrix.dir == 'lib/bindings/python' | |
| working-directory: ${{ matrix.dir }} | |
| run: cargo clippy --locked --no-deps --features aic-forward-pass --all-targets -- -D warnings | |
| - name: Lint Python bindings worker-selection policy builds | |
| if: matrix.dir == 'lib/bindings/python' | |
| working-directory: ${{ matrix.dir }} | |
| run: | | |
| # custom-policy is on by default; also lint it alongside the standalone selection | |
| # service, and the build that links no worker-selection policies at all. | |
| cargo clippy --locked --no-deps --features custom-policy,select-service --all-targets -- -D warnings | |
| cargo clippy --locked --no-deps --no-default-features --all-targets -- -D warnings | |
| - name: Lint feature-gated benchmark entrypoints | |
| if: matrix.dir == '.' | |
| working-directory: ${{ matrix.dir }} | |
| run: | | |
| lint_bench() { | |
| feature="$1" | |
| shift | |
| cargo clippy --locked --no-deps -p dynamo-bench --no-default-features \ | |
| --features "$feature" "$@" -- -D warnings | |
| } | |
| lint_bench multiturn --bench multiturn_bench | |
| lint_bench satf --bin request_trace_to_satf | |
| lint_bench request-trace-to-mooncake --bin request_trace_to_mooncake | |
| lint_bench weka-to-agentic-mooncake --bin weka_to_agentic_mooncake | |
| lint_bench weka-to-agentic-mooncake --test weka_to_agentic_mooncake | |
| lint_bench offline-replay --bench offline_replay_bench | |
| lint_bench mooncake --bench mooncake_bench | |
| lint_bench active-sequences --bench active_sequences_bench | |
| lint_bench dc-ckf-consumer --bin dc_ckf_consumer_bench | |
| lint_bench dc-ckf-relay --bench dc_ckf_relay_bench | |
| cargo clippy --locked --no-deps -p dynamo-llm --no-default-features \ | |
| --features kv-router-stress --bench kv_router_bench -- -D warnings | |
| - name: Install and Run cargo-machete | |
| working-directory: ${{ matrix.dir }} | |
| run: | | |
| cargo-machete --version || cargo install cargo-machete@0.9.1 | |
| cargo machete |