chore: unexport three in-file-only types flagged by newer knip #1030
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
| 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 |