Skip to content

chore: unexport three in-file-only types flagged by newer knip #1030

chore: unexport three in-file-only types flagged by newer knip

chore: unexport three in-file-only types flagged by newer knip #1030

Workflow file for this run

name: CI
on:
pull_request:
branches: [main]
push:
branches: [main]
permissions:
contents: read
concurrency:
group: ci-${{ github.ref }}
# Never cancel main-branch runs: a release tag can point at a commit whose
# CI was cancelled by a faster push, shipping unverified code (audit
# 20260612, observed for v0.8.4). PRs still cancel superseded runs.
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
jobs:
# Frontend checks: lint, tests, build — platform-independent (jsdom + vite)
frontend-run:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v7
with:
# Fetch enough history for the new-deps slopsquatting gate to diff
# against origin/main.
fetch-depth: 0
- uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6
with:
version: 10
- uses: actions/setup-node@v6
with:
node-version: 22
cache: pnpm
- run: pnpm install --frozen-lockfile
- name: Security audit
# pnpm 10 audit broken: npm retired legacy endpoint (410), bulk API lands in pnpm 11
# Track: https://github.com/pnpm/pnpm/issues/11265
continue-on-error: true
run: pnpm audit --audit-level=critical
- name: Slopsquatting gate (new-dep review)
# Flags newly-added packages that look hallucinated or freshly-published.
# Background: USENIX Sec 2025 — LLM package hallucination 5-22%, with
# active "slopsquat" supply-chain attacks. See scripts/check-new-deps.sh.
run: bash scripts/check-new-deps.sh
- run: pnpm check:all
# Gate job: required by branch protection (exact name "frontend")
frontend:
if: always()
needs: [frontend-run]
runs-on: ubuntu-latest
steps:
- name: Check result
env:
RESULT: ${{ needs.frontend-run.result }}
run: |
if [ "$RESULT" != "success" ]; then
echo "frontend-run: $RESULT"
exit 1
fi
# Perf bench: on every run, src/bench/*.bench.ts must execute without error
# so the suite can't silently rot. On PRs, additionally benches the base ref
# in a worktree ON THE SAME RUNNER and compares means (same machine, same
# noise conditions — committed cross-machine baselines are meaningless).
# The comparison is a NON-BLOCKING signal (continue-on-error): shared-runner
# variance makes a hard gate cry wolf; the step summary carries the verdict.
# Threshold and semantics: scripts/compare-bench.mjs (2.5x mean, 1 ms floor).
bench:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v7
- uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6
with:
version: 10
- uses: actions/setup-node@v6
with:
node-version: 22
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm bench --outputJson /tmp/bench-current.json
- name: Bench base ref (same-runner reference)
id: bench-base
if: github.event_name == 'pull_request'
continue-on-error: true
run: |
git fetch --depth=1 origin "$BASE_REF"
git worktree add /tmp/bench-base FETCH_HEAD
cd /tmp/bench-base
pnpm install --frozen-lockfile
pnpm bench --outputJson /tmp/bench-base.json
env:
BASE_REF: ${{ github.base_ref }}
- name: Compare against base (non-blocking signal)
if: github.event_name == 'pull_request' && steps.bench-base.outcome == 'success'
continue-on-error: true
run: node scripts/compare-bench.mjs /tmp/bench-base.json /tmp/bench-current.json
# Detect if Rust code changed — skip rust-test for frontend-only PRs
changes:
runs-on: ubuntu-latest
outputs:
rust: ${{ steps.filter.outputs.rust }}
steps:
- uses: actions/checkout@v7
- uses: dorny/paths-filter@7b450fff21473bca461d4b92ce414b9d0420d706 # v4
id: filter
with:
filters: |
rust:
- 'src-tauri/**'
- 'Cargo.lock'
rust-test:
needs: [changes]
if: needs.changes.outputs.rust == 'true' || github.event_name == 'push'
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
os: [macos-latest, ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v7
- uses: ./.github/actions/setup-tauri-deps
- uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable branch
with:
toolchain: stable
components: clippy, rustfmt
- uses: actions/cache@v6
with:
path: |
~/.cargo/registry
~/.cargo/git
key: rust-${{ runner.os }}-${{ hashFiles('src-tauri/Cargo.lock') }}
restore-keys: rust-${{ runner.os }}-
- name: Create sidecar stub for Tauri build script
shell: bash
run: |
if [[ "$RUNNER_OS" == "Windows" ]]; then
triple="x86_64-pc-windows-msvc"
ext=".exe"
elif [[ "$RUNNER_OS" == "Linux" ]]; then
triple="x86_64-unknown-linux-gnu"
ext=""
else
triple="aarch64-apple-darwin"
ext=""
fi
touch "src-tauri/binaries/vmark-mcp-server-${triple}${ext}"
# rustfmt is textual and platform-independent — one OS leg is enough.
- name: Format check (rustfmt)
if: runner.os == 'Linux'
run: cargo fmt --manifest-path src-tauri/Cargo.toml --check
# Clippy runs per-OS because cfg-gated platform code (Windows/Linux
# branches) never compiles on the macOS leg. Runs before tests to fail
# fast; shares the same build cache.
- name: Lint (clippy, warnings are errors)
run: cargo clippy --manifest-path src-tauri/Cargo.toml --all-targets -- -D warnings
- run: cargo test --manifest-path src-tauri/Cargo.toml
# Gate job: required by branch protection (exact name "rust").
# Passes when rust-test succeeded OR was skipped (frontend-only PR);
# fails on any real rust-test failure so Rust-touching PRs cannot
# auto-merge with red Rust CI (audit 20260612 H26).
rust:
if: always()
needs: [changes, rust-test]
runs-on: ubuntu-latest
steps:
- name: Check result
env:
RESULT: ${{ needs.rust-test.result }}
run: |
if [ "$RESULT" != "success" ] && [ "$RESULT" != "skipped" ]; then
echo "rust-test: $RESULT"
exit 1
fi
# cargo-audit is a lockfile-only, platform-independent check — one ubuntu
# job instead of compiling cargo-audit from source on all 3 OSes
# (audit 20260612: ~11 runner-minutes per CI run saved).
rust-audit:
needs: [changes]
if: needs.changes.outputs.rust == 'true' || github.event_name == 'push'
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v7
- name: Install cargo-audit
uses: taiki-e/install-action@c93ccc03e00cd0e08e494f5fd058a6c55a6a1907 # v2.82.8
with:
tool: cargo-audit
- name: Security audit (Rust)
# RUSTSEC-2026-0194/0195: DoS advisories in `quick-xml`, pulled in only
# transitively and unfixable from here — `plist 1.9.0` (via `tauri 2.11.3`)
# pins `quick-xml ^0.39.2` and `tauri-winrt-notification` pins `^0.37`,
# while the fix is >=0.41.0. Neither is reachable without an upstream
# Tauri/plist release. quick-xml is used only for plist parsing (macOS
# bundle metadata) and Windows notifications, never for untrusted external
# XML in VMark. Remove these ignores once a Tauri bump pulls quick-xml >=0.41.
run: cargo audit --file src-tauri/Cargo.lock --ignore RUSTSEC-2026-0194 --ignore RUSTSEC-2026-0195