Repository navigation
docs(feature-map): keep the page's sources in the repo; npm run docs:feature-map #1519
Workflow file for this run
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: Dependency Security | |
| # Runs on every PR and every push to main. | |
| # Hard-blocks on Critical npm vulnerabilities. | |
| # Warns on High npm vulnerabilities (non-blocking — devDep false positives are common). | |
| on: | |
| pull_request: | |
| push: | |
| branches: [main] | |
| permissions: | |
| contents: read | |
| jobs: | |
| # ── npm audit ────────────────────────────────────────────────────────────── | |
| npm-audit: | |
| # A version-bump commit changes four package.json version fields and | |
| # nothing else, so there is nothing here for it to check. It used to carry | |
| # `[skip ci]` for this, but that marker also suppresses the *tag* push that | |
| # rides on the same commit, which silently disabled every release — see | |
| # version-bump.yml. Skipping by message keeps the saving without that cost. | |
| # Guarded on event_name so pull_request runs are never skipped. | |
| if: "${{ github.event_name != 'push' || !startsWith(github.event.head_commit.message, 'chore: bump version') }}" | |
| name: npm audit | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v5 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v5 | |
| with: | |
| node-version: 22 | |
| # npm 10 (what Node 22 ships) cannot resolve this workspace graph | |
| # without a lockfile — arborist dies in #loadPeerSet on vitest with | |
| # "Cannot read properties of null (reading 'edgesOut')". npm 11 does | |
| # it fine. Verified on a clean clone at Node 22.23.1. | |
| - run: npm i -g npm@11 | |
| # Generate lockfile on the fly so npm audit has a full dependency graph. | |
| # Consider committing package-lock.json for faster, deterministic CI. | |
| - name: Generate lockfile | |
| run: npm ci --ignore-scripts | |
| # Hard block — Critical vulns in production dependencies. | |
| # Verifies every package in the lockfile against the registry's own | |
| # signatures. `npm audit` answers "is this version known to be | |
| # vulnerable"; this answers "is this tarball the one the registry | |
| # published", which is what catches a tampered or re-published package. | |
| # | |
| # `npm audit signatures` calls the attestations API, which intermittently | |
| # 404s for otherwise-valid packages (e.g. whatwg-url@14.2.0). Treat that | |
| # registry gap as a warning so Critical audit below remains the hard gate. | |
| - name: Verify registry signatures | |
| continue-on-error: true | |
| run: npm audit signatures | |
| - name: Fail on Critical vulnerabilities | |
| run: npm audit --audit-level=critical --omit=dev | |
| # Soft check — High vulns across all deps (informational; common in devDeps). | |
| - name: Warn on High vulnerabilities | |
| run: npm audit --audit-level=high || echo "⚠️ High-severity advisories found — review npm-audit-full.json" | |
| # Upload full JSON report as a build artifact for manual review. | |
| - name: Save full audit report | |
| if: always() | |
| run: npm audit --json > npm-audit-full.json || true | |
| - name: Upload audit report | |
| if: always() | |
| uses: actions/upload-artifact@v5 | |
| with: | |
| name: npm-audit-report | |
| path: npm-audit-full.json | |
| retention-days: 30 | |
| # ── ESLint security rules ────────────────────────────────────────────────── | |
| eslint-security: | |
| # A version-bump commit changes four package.json version fields and | |
| # nothing else, so there is nothing here for it to check. It used to carry | |
| # `[skip ci]` for this, but that marker also suppresses the *tag* push that | |
| # rides on the same commit, which silently disabled every release — see | |
| # version-bump.yml. Skipping by message keeps the saving without that cost. | |
| # Guarded on event_name so pull_request runs are never skipped. | |
| if: "${{ github.event_name != 'push' || !startsWith(github.event.head_commit.message, 'chore: bump version') }}" | |
| name: ESLint security | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v5 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v5 | |
| with: | |
| node-version: 22 | |
| # npm 10 (what Node 22 ships) cannot resolve this workspace graph | |
| # without a lockfile — arborist dies in #loadPeerSet on vitest with | |
| # "Cannot read properties of null (reading 'edgesOut')". npm 11 does | |
| # it fine. Verified on a clean clone at Node 22.23.1. | |
| - run: npm i -g npm@11 | |
| - name: Install dependencies | |
| run: npm ci --ignore-scripts | |
| # Errors (inject/eval/ReDoS) cause non-zero exit and block the PR. | |
| # Warnings (detect-non-literal-fs-filename) are informational — legitimate | |
| # server/CLI filesystem operations use variable paths by design. | |
| - name: Run ESLint security rules | |
| run: npx eslint . | |
| # ── node_modules backdoor / unexpected port scan ─────────────────────────── | |
| # Dedicated deep scan also lives in deps-backdoor-scan.yml (scheduled weekly). | |
| deps-backdoor-scan: | |
| # A version-bump commit changes four package.json version fields and | |
| # nothing else, so there is nothing here for it to check. It used to carry | |
| # `[skip ci]` for this, but that marker also suppresses the *tag* push that | |
| # rides on the same commit, which silently disabled every release — see | |
| # version-bump.yml. Skipping by message keeps the saving without that cost. | |
| # Guarded on event_name so pull_request runs are never skipped. | |
| if: "${{ github.event_name != 'push' || !startsWith(github.event.head_commit.message, 'chore: bump version') }}" | |
| name: Deps backdoor / port scan | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v5 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v5 | |
| with: | |
| node-version: 22 | |
| # npm 10 (what Node 22 ships) cannot resolve this workspace graph | |
| # without a lockfile — arborist dies in #loadPeerSet on vitest with | |
| # "Cannot read properties of null (reading 'edgesOut')". npm 11 does | |
| # it fine. Verified on a clean clone at Node 22.23.1. | |
| - run: npm i -g npm@11 | |
| - name: Install dependencies (ignore-scripts) | |
| run: npm ci --ignore-scripts | |
| - name: Scan node_modules | |
| run: npm run scan:deps-security -- --report deps-backdoor-report.json | |
| - name: Upload scan report | |
| if: always() | |
| uses: actions/upload-artifact@v5 | |
| with: | |
| name: deps-backdoor-report | |
| path: deps-backdoor-report.json | |
| retention-days: 30 |