Skip to content

test(mcp-server): align cucumber assertions and resolve pending step … #7

test(mcp-server): align cucumber assertions and resolve pending step …

test(mcp-server): align cucumber assertions and resolve pending step … #7

Workflow file for this run

---
# CI pipeline for substrate — mirrors local `just ci` targets.
# Branch-protection gate: require job `ci-success` to pass.
#
# All cargo invocations use --locked to ensure Cargo.lock is honoured.
# Toolchain is pinned via rust-toolchain.toml (channel = "1.95.0").
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
env:
CARGO_TERM_COLOR: always
CARGO_INCREMENTAL: "0"
RUST_BACKTRACE: "1"
jobs:
# ---------------------------------------------------------------------------
# fmt — formatting gate (rustfmt)
# ---------------------------------------------------------------------------
fmt:
name: fmt
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Rust toolchain
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
components: rustfmt
- name: Cache cargo registry + git
uses: Swatinem/rust-cache@v2
- name: Check formatting
run: cargo fmt --all -- --check
# ---------------------------------------------------------------------------
# clippy — lint gate (-D warnings)
# ---------------------------------------------------------------------------
clippy:
name: clippy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Rust toolchain
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
components: clippy
- name: Cache cargo registry + git
uses: Swatinem/rust-cache@v2
- name: Clippy
run: cargo clippy --locked --workspace --all-targets -- -D warnings
# ---------------------------------------------------------------------------
# nextest — test suite via cargo-nextest
# ---------------------------------------------------------------------------
nextest:
name: nextest
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Rust toolchain
uses: actions-rust-lang/setup-rust-toolchain@v1
- name: Cache cargo registry + git
uses: Swatinem/rust-cache@v2
- name: Install cargo-nextest
uses: taiki-e/install-action@v2
with:
tool: cargo-nextest
- name: Run tests
run: cargo nextest run --locked --workspace --no-fail-fast
# ---------------------------------------------------------------------------
# deny — dependency license + advisory + source check
# ---------------------------------------------------------------------------
deny:
name: deny
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Rust toolchain
uses: actions-rust-lang/setup-rust-toolchain@v1
- name: Cache cargo registry + git
uses: Swatinem/rust-cache@v2
- name: Install cargo-deny
uses: taiki-e/install-action@v2
with:
tool: cargo-deny
- name: Run cargo deny
run: |
if [ -f deny.toml ]; then
cargo deny --locked check
else
echo "::warning::deny.toml not found — skipping cargo deny"
fi
# ---------------------------------------------------------------------------
# audit — vulnerability advisory scan
# ---------------------------------------------------------------------------
audit:
name: audit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Rust toolchain
uses: actions-rust-lang/setup-rust-toolchain@v1
- name: Cache cargo registry + git
uses: Swatinem/rust-cache@v2
- name: Install cargo-audit
uses: taiki-e/install-action@v2
with:
tool: cargo-audit
- name: Run cargo audit
run: cargo audit --deny warnings
# ---------------------------------------------------------------------------
# semver-checks — public API semver regression detection
# Skips gracefully when no baseline exists (first-ever publish).
# ---------------------------------------------------------------------------
semver-checks:
name: semver-checks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Rust toolchain
uses: actions-rust-lang/setup-rust-toolchain@v1
- name: Cache cargo registry + git
uses: Swatinem/rust-cache@v2
- name: Install cargo-semver-checks
uses: taiki-e/install-action@v2
with:
tool: cargo-semver-checks
- name: Run semver checks
# `|| true` lets the job pass on first-ever run when no baseline exists
# in the registry. A genuine semver violation will still be reported in
# the output and should be investigated manually.
run: cargo semver-checks check-release --locked --workspace || true
# ---------------------------------------------------------------------------
# llvm-cov — code coverage with 80 % line threshold
# ---------------------------------------------------------------------------
llvm-cov:
name: llvm-cov
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Rust toolchain
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
components: llvm-tools-preview
- name: Cache cargo registry + git
uses: Swatinem/rust-cache@v2
- name: Install cargo-llvm-cov
uses: taiki-e/install-action@v2
with:
tool: cargo-llvm-cov
- name: Install cargo-nextest
uses: taiki-e/install-action@v2
with:
tool: cargo-nextest
- name: Collect coverage
run: >
cargo llvm-cov
--locked
--workspace
--fail-under-lines 80
--lcov
--output-path lcov.info
- name: Upload to Codecov
uses: codecov/codecov-action@v4
with:
files: lcov.info
fail_ci_if_error: false
token: ${{ secrets.CODECOV_TOKEN }}
# ---------------------------------------------------------------------------
# bench — compile-only benchmark build (runtime execution is manual)
# ---------------------------------------------------------------------------
bench:
name: bench (compile only)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Rust toolchain
uses: actions-rust-lang/setup-rust-toolchain@v1
- name: Cache cargo registry + git
uses: Swatinem/rust-cache@v2
- name: Compile benchmarks
run: cargo bench --locked --workspace --no-run
# ---------------------------------------------------------------------------
# spec-validate — run spec validate --lane full via the spec CLI.
# Requires the spec-framework to be on PATH. Skips with a warning when the
# tool is not available (e.g., forks or external contributors).
# ---------------------------------------------------------------------------
spec-validate:
name: spec-validate
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Cache mise tooling
uses: actions/cache@v4
with:
path: ~/.local/share/mise
key: mise-${{ runner.os }}-${{ hashFiles('mise.toml') }}
restore-keys: mise-${{ runner.os }}-
- name: Install mise
uses: jdx/mise-action@v2
- name: Install spec framework (best-effort)
run: |
if ! command -v spec >/dev/null 2>&1; then
if [ -n "${SPEC_FRAMEWORK_DIR:-}" ] && [ -d "$SPEC_FRAMEWORK_DIR" ]; then
echo "spec framework already available at $SPEC_FRAMEWORK_DIR"
else
echo "::warning::spec CLI not on PATH and SPEC_FRAMEWORK_DIR not set — skipping spec-validate"
echo "SPEC_SKIP=1" >> "$GITHUB_ENV"
fi
fi
- name: Validate spec
run: |
if [ "${SPEC_SKIP:-0}" = "1" ]; then
echo "Skipping spec-validate (spec CLI not available)"
else
spec validate --lane full
fi
# ---------------------------------------------------------------------------
# mmdc-lint — validate all Mermaid blocks in docs/arch/ markdown files
# ---------------------------------------------------------------------------
mmdc-lint:
name: mmdc-lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
- name: Install mermaid-cli
run: pnpm dlx @mermaid-js/mermaid-cli --version || true
# Install via dlx so no package.json is needed; the check step below
# invokes the script which will run mmdc directly.
- name: Install mermaid-cli (global for PATH)
run: npm install -g @mermaid-js/mermaid-cli
- name: Lint Mermaid diagrams
run: bash scripts/lint-mermaid.sh --keep-going
# ---------------------------------------------------------------------------
# typos — spell-check source code and documentation
# ---------------------------------------------------------------------------
typos:
name: typos
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install typos
uses: taiki-e/install-action@v2
with:
tool: typos
- name: Run typos
run: |
if [ -f typos.toml ]; then
typos --config typos.toml
else
typos
fi
# ---------------------------------------------------------------------------
# cargo-shear — detect unused workspace dependencies
# ---------------------------------------------------------------------------
cargo-shear:
name: cargo-shear
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Rust toolchain
uses: actions-rust-lang/setup-rust-toolchain@v1
- name: Cache cargo registry + git
uses: Swatinem/rust-cache@v2
- name: Install cargo-shear
uses: taiki-e/install-action@v2
with:
tool: cargo-shear
- name: Check for unused dependencies
run: cargo shear
# ---------------------------------------------------------------------------
# ci-success — aggregator job used as the branch-protection gate.
# Depends on every job above. Succeeds when all pass.
# ---------------------------------------------------------------------------
ci-success:
name: ci-success
runs-on: ubuntu-latest
needs:
- fmt
- clippy
- nextest
- deny
- audit
- semver-checks
- llvm-cov
- bench
- spec-validate
- mmdc-lint
- typos
- cargo-shear
if: always()
steps:
- name: Check all jobs passed
run: |
results='${{ toJSON(needs) }}'
failures=$(echo "$results" | python3 -c "
import sys, json
d = json.load(sys.stdin)
failed = [k for k,v in d.items() if v['result'] not in ('success','skipped')]
if failed:
print('FAILED jobs: ' + ', '.join(failed))
sys.exit(1)
print('All jobs passed.')
")