Skip to content

ci: build and qualify ROCm images through Slurm #2

ci: build and qualify ROCm images through Slurm

ci: build and qualify ROCm images through Slurm #2

Workflow file for this run

# 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