chore(deps): bump dompurify from 3.4.3 to 3.4.13 in /dashboard #7753
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 | |
| - develop | |
| push: | |
| branches: | |
| - main | |
| - develop | |
| tags: | |
| - 'v*' | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ci-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| lint-pr-title: | |
| if: github.event_name == 'pull_request' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: amannn/action-semantic-pull-request@v6 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| with: | |
| types: 'feat | |
| fix | |
| docs | |
| style | |
| refactor | |
| perf | |
| test | |
| build | |
| ci | |
| chore | |
| revert | |
| ' | |
| requireScope: false | |
| lint: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: actions/setup-node@v6 | |
| with: | |
| node-version: '22' | |
| cache: npm | |
| - name: Install dependencies | |
| run: npm ci --ignore-scripts | |
| - name: Run hygiene check | |
| run: npm run hygiene-check | |
| - name: 'Security check - prevent shell: true' | |
| run: npm run security-check | |
| - name: Run linter | |
| run: npm run lint | |
| feat-minor-bump-gate: | |
| if: github.event_name == 'pull_request' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Enforce approved minor bump label for feat PRs | |
| uses: actions/github-script@v9 | |
| with: | |
| script: | | |
| const pr = context.payload.pull_request; | |
| if (!pr) { | |
| core.info('Not a pull request event; skipping gate.'); | |
| return; | |
| } | |
| // Fetch live PR data from the API instead of using the frozen payload. | |
| // This ensures re-runs pick up title changes and labels added after the initial push. | |
| const { data: livePr } = await github.rest.pulls.get({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| pull_number: pr.number, | |
| }); | |
| const title = livePr.title || ''; | |
| const isFeat = /^feat(\(.+\))?!?:\s/i.test(title); | |
| if (!isFeat) { | |
| core.info(`PR title is not feat:* (${title}); gate passed.`); | |
| return; | |
| } | |
| const labels = (livePr.labels || []).map(label => label.name); | |
| if (labels.includes('approved-minor-bump')) { | |
| core.info('approved-minor-bump label present; feat gate passed.'); | |
| return; | |
| } | |
| core.setFailed('feat: PRs require the approved-minor-bump label before CI can pass.'); | |
| sdk-drift: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: dorny/paths-filter@v4 | |
| id: filter | |
| with: | |
| filters: | | |
| sdk-related: | |
| - 'openapi.yaml' | |
| - 'src/routes/**' | |
| - 'src/schemas/**' | |
| - 'packages/client/**' | |
| - 'packages/python-client/**' | |
| - '.github/workflows/ci.yml' | |
| - uses: actions/setup-node@v6 | |
| if: github.event_name == 'push' || steps.filter.outputs.sdk-related == 'true' | |
| with: | |
| node-version: '22' | |
| cache: npm | |
| - uses: actions/setup-python@v6 | |
| if: github.event_name == 'push' || steps.filter.outputs.sdk-related == 'true' | |
| with: | |
| python-version: '3.12' | |
| cache: pip | |
| cache-dependency-path: packages/python-client/pyproject.toml | |
| - name: Install dependencies | |
| if: github.event_name == 'push' || steps.filter.outputs.sdk-related == 'true' | |
| run: npm ci | |
| - name: Check generated OpenAPI contract | |
| if: github.event_name == 'push' || steps.filter.outputs.sdk-related == 'true' | |
| run: npm run openapi:check | |
| - name: Check generated TypeScript SDK | |
| if: github.event_name == 'push' || steps.filter.outputs.sdk-related == 'true' | |
| run: npm run sdk:ts:check | |
| - name: Check generated Python SDK | |
| if: github.event_name == 'push' || steps.filter.outputs.sdk-related == 'true' | |
| run: npm run sdk:py:check | |
| test: | |
| if: ${{ !startsWith(github.ref, 'refs/tags/') }} | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: | |
| - ubuntu-latest | |
| node-version: | |
| - '20' | |
| - '22' | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Setup Node.js ${{ matrix.node-version }} | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: ${{ matrix.node-version }} | |
| cache: npm | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Security audit | |
| run: npm audit --audit-level=high | |
| - name: Lockfile lint | |
| run: npx lockfile-lint --type npm --path package-lock.json --validate-https | |
| - name: TypeScript check | |
| run: npx tsc --noEmit | |
| - name: Build | |
| run: npm run build | |
| - name: Run server smoke UAT | |
| run: npm run test:smoke | |
| - name: Start Aegis | |
| shell: bash | |
| run: | | |
| node dist/cli.js --port 9100 > aegis.log 2>&1 & | |
| echo "AEGIS_PID=$!" >> "$GITHUB_ENV" | |
| - name: Smoke test health endpoint | |
| run: node scripts/ci-smoke-health.mjs | |
| - name: Stop Aegis | |
| if: always() | |
| shell: bash | |
| run: | | |
| if [ -n "${AEGIS_PID:-}" ]; then | |
| kill "$AEGIS_PID" || true | |
| fi | |
| - name: Check bundle size | |
| run: "THRESHOLD_KB=2080\nSERVER_SIZE=$(find dist/ -name \"*.js\" ! -path \"\ | |
| */__tests__/*\" ! -path \"*/dashboard/*\" -exec du -ck {} + | tail -1 | awk '{print $1}')\nSERVER_SIZE_KB=$((SERVER_SIZE))\n\ | |
| echo \"## Bundle Size Report\" >> \"$GITHUB_STEP_SUMMARY\"\necho \"\" >> \"\ | |
| $GITHUB_STEP_SUMMARY\"\necho \"| Scope | Size (KB) | Threshold (KB) | Status\ | |
| \ |\" >> \"$GITHUB_STEP_SUMMARY\"\necho \"|-------|-----------|----------------|--------|\"\ | |
| \ >> \"$GITHUB_STEP_SUMMARY\"\nif [ \"$SERVER_SIZE_KB\" -gt \"$THRESHOLD_KB\"\ | |
| \ ]; then\n echo \"| Server (excl. tests) | ${SERVER_SIZE_KB} | ${THRESHOLD_KB}\ | |
| \ | \u274C Exceeds threshold |\" >> \"$GITHUB_STEP_SUMMARY\"\n echo \"::error::Server\ | |
| \ bundle size ${SERVER_SIZE_KB}KB exceeds ${THRESHOLD_KB}KB threshold\"\n\ | |
| \ exit 1\nelse\n echo \"| Server (excl. tests) | ${SERVER_SIZE_KB} | ${THRESHOLD_KB}\ | |
| \ | \u2705 Within budget |\" >> \"$GITHUB_STEP_SUMMARY\"\n echo \"Server\ | |
| \ bundle size: ${SERVER_SIZE_KB}KB (threshold: ${THRESHOLD_KB}KB)\"\nfi\n" | |
| - name: Build dashboard | |
| run: cd dashboard && npm ci && npm run build | |
| - name: Run dashboard E2E tests (PR gate) | |
| if: matrix.os == 'ubuntu-latest' && matrix.node-version == '20' | |
| run: cd dashboard && npx vitest run | |
| - name: Run tests with coverage | |
| run: npm test -- --coverage | |
| - name: Enforce coverage thresholds | |
| if: matrix.os == 'ubuntu-latest' && matrix.node-version == '20' | |
| run: | | |
| echo "## Coverage Threshold Enforcement" >> "$GITHUB_STEP_SUMMARY" | |
| echo "" >> "$GITHUB_STEP_SUMMARY" | |
| echo "| Metric | Threshold | Enforced |" >> "$GITHUB_STEP_SUMMARY" | |
| echo "|--------|-----------|----------|" >> "$GITHUB_STEP_SUMMARY" | |
| echo "| Lines | 65% | ✅ |" >> "$GITHUB_STEP_SUMMARY" | |
| echo "| Branches | 65% | ✅ |" >> "$GITHUB_STEP_SUMMARY" | |
| echo "| Functions | 65% | ✅ |" >> "$GITHUB_STEP_SUMMARY" | |
| echo "" >> "$GITHUB_STEP_SUMMARY" | |
| echo "> Thresholds are enforced by vitest config (vitest.config.ts)." >> "$GITHUB_STEP_SUMMARY" | |
| echo "> If this step runs, all coverage thresholds passed." >> "$GITHUB_STEP_SUMMARY" | |
| - name: Upload coverage reports | |
| uses: actions/upload-artifact@v4 | |
| if: matrix.os == 'ubuntu-latest' && matrix.node-version == '20' | |
| with: | |
| name: coverage-report | |
| path: coverage/ | |
| retention-days: 7 | |
| - name: Audit tracked files | |
| run: "FOUND=$(git ls-files | grep -E '(^should$|results\\.tsv|^state/|\\.tsbuildinfo$|\\\ | |
| .env$|\\.log$|\\.tmp$|\\.bak$|\\.swp$)' || true)\nif [ -n \"$FOUND\" ]; then\n\ | |
| \ echo \"::error::Blacklisted files found in git tracking\"\n echo \"$FOUND\"\ | |
| \n exit 1\nfi\necho \"Audit passed - no blacklisted files found\"\n" | |
| platform-smoke: | |
| if: ${{ (github.event_name == 'pull_request' && github.base_ref == 'develop') || (github.event_name == 'push' && github.ref == 'refs/heads/develop') }} | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: | |
| - windows-latest | |
| - macos-latest | |
| node-version: | |
| - '22' | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Setup Node.js ${{ matrix.node-version }} | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: ${{ matrix.node-version }} | |
| cache: npm | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Build | |
| run: npm run build | |
| - name: Run server smoke UAT | |
| run: npm run test:smoke | |
| - name: Run platform smoke subset | |
| run: > | |
| npx vitest run | |
| src/__tests__/platform-shell.test.ts | |
| src/__tests__/path-utils-909.test.ts | |
| src/__tests__/hook-paths-909.test.ts | |
| src/__tests__/startup.test.ts | |
| src/__tests__/config.test.ts | |
| - name: Run config watcher smoke | |
| run: npx vitest run src/__tests__/config-hot-reload-1753.test.ts | |
| test-matrix: | |
| if: ${{ startsWith(github.ref, 'refs/tags/') }} | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: | |
| - ubuntu-latest | |
| - windows-latest | |
| - macos-latest | |
| node-version: | |
| - '20' | |
| - '22' | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Setup Node.js ${{ matrix.node-version }} | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: ${{ matrix.node-version }} | |
| cache: npm | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Security audit | |
| run: npm audit --audit-level=high | |
| - name: Lockfile lint | |
| run: npx lockfile-lint --type npm --path package-lock.json --validate-https | |
| - name: TypeScript check | |
| run: npx tsc --noEmit | |
| - name: Build | |
| run: npm run build | |
| - name: Run server smoke UAT | |
| run: npm run test:smoke | |
| - name: Start Aegis (Linux/macOS) | |
| if: runner.os != 'Windows' | |
| shell: bash | |
| run: | | |
| node dist/cli.js --port 9100 > aegis.log 2>&1 & | |
| echo "AEGIS_PID=$!" >> "$GITHUB_ENV" | |
| - name: Start Aegis (Windows) | |
| if: runner.os == 'Windows' | |
| shell: pwsh | |
| run: | | |
| $proc = Start-Process -FilePath node -ArgumentList 'dist/cli.js', '--port', '9100' -PassThru -WindowStyle Hidden | |
| "AEGIS_PID=$($proc.Id)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append | |
| - name: Smoke test health endpoint (Linux/macOS) | |
| if: runner.os != 'Windows' | |
| shell: bash | |
| run: node scripts/ci-smoke-health.mjs | |
| - name: Smoke test health endpoint (Windows) | |
| if: runner.os == 'Windows' | |
| shell: pwsh | |
| run: node scripts/ci-smoke-health.mjs | |
| - name: Stop Aegis (Linux/macOS) | |
| if: always() && runner.os != 'Windows' | |
| shell: bash | |
| run: | | |
| if [ -n "${AEGIS_PID:-}" ]; then | |
| kill "$AEGIS_PID" || true | |
| fi | |
| - name: Stop Aegis (Windows) | |
| if: always() && runner.os == 'Windows' | |
| shell: pwsh | |
| run: | | |
| if ($env:AEGIS_PID) { | |
| Stop-Process -Id ([int]$env:AEGIS_PID) -Force -ErrorAction SilentlyContinue | |
| } | |
| - name: Check bundle size | |
| if: runner.os != 'Windows' | |
| run: "THRESHOLD_KB=2080\nSERVER_SIZE=$(find dist/ -name \"*.js\" ! -path \"\ | |
| */__tests__/*\" ! -path \"*/dashboard/*\" -exec du -ck {} + | tail -1 | awk '{print $1}')\nSERVER_SIZE_KB=$((SERVER_SIZE))\n\ | |
| echo \"## Bundle Size Report\" >> \"$GITHUB_STEP_SUMMARY\"\necho \"\" >> \"\ | |
| $GITHUB_STEP_SUMMARY\"\necho \"| Scope | Size (KB) | Threshold (KB) | Status\ | |
| \ |\" >> \"$GITHUB_STEP_SUMMARY\"\necho \"|-------|-----------|----------------|--------|\"\ | |
| \ >> \"$GITHUB_STEP_SUMMARY\"\nif [ \"$SERVER_SIZE_KB\" -gt \"$THRESHOLD_KB\"\ | |
| \ ]; then\n echo \"| Server (excl. tests) | ${SERVER_SIZE_KB} | ${THRESHOLD_KB}\ | |
| \ | ❌ Exceeds threshold |\" >> \"$GITHUB_STEP_SUMMARY\"\n echo \"::error::Server\ | |
| \ bundle size ${SERVER_SIZE_KB}KB exceeds ${THRESHOLD_KB}KB threshold\"\n\ | |
| \ exit 1\nelse\n echo \"| Server (excl. tests) | ${SERVER_SIZE_KB} | ${THRESHOLD_KB}\ | |
| \ | ✅ Within budget |\" >> \"$GITHUB_STEP_SUMMARY\"\n echo \"Server bundle\ | |
| \ size: ${SERVER_SIZE_KB}KB (threshold: ${THRESHOLD_KB}KB)\"\nfi\n" | |
| - name: Build dashboard | |
| run: cd dashboard && npm ci && npm run build | |
| - name: Run dashboard E2E tests (PR gate) | |
| if: matrix.os == 'ubuntu-latest' && matrix.node-version == '20' | |
| run: cd dashboard && npx vitest run | |
| - name: Run tests with coverage | |
| run: npm test -- --coverage | |
| - name: Upload coverage reports | |
| uses: actions/upload-artifact@v4 | |
| if: matrix.os == 'ubuntu-latest' && matrix.node-version == '20' | |
| with: | |
| name: coverage-report | |
| path: coverage/ | |
| retention-days: 7 | |
| - name: Audit tracked files | |
| if: runner.os != 'Windows' | |
| run: "FOUND=$(git ls-files | grep -E '(^should$|results\\.tsv|^state/|\\.tsbuildinfo$|\\\ | |
| .env$|\\.log$|\\.tmp$|\\.bak$|\\.swp$)' || true)\nif [ -n \"$FOUND\" ]; then\n\ | |
| \ echo \"::error::Blacklisted files found in git tracking\"\n echo \"$FOUND\"\ | |
| \n exit 1\nfi\necho \"Audit passed - no blacklisted files found\"\n" | |
| dashboard-e2e: | |
| if: github.event_name == 'pull_request' && github.base_ref == 'develop' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: '22' | |
| cache: npm | |
| - name: Install dashboard dependencies | |
| run: cd dashboard && npm ci | |
| - name: Install Playwright Chromium | |
| run: cd dashboard && npx playwright install --with-deps chromium | |
| - name: Run dashboard E2E (required specs) | |
| run: cd dashboard && npx playwright test e2e/login.spec.ts e2e/session-list.spec.ts e2e/audit.spec.ts --project=chromium | |
| - name: Upload Playwright report | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: dashboard-playwright-report | |
| path: dashboard/playwright-report/ | |
| retention-days: 7 | |
| - name: Upload Playwright test results | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: dashboard-playwright-test-results | |
| path: dashboard/test-results/ | |
| retention-days: 7 | |
| auto-label-test: | |
| runs-on: ubuntu-latest | |
| if: "github.event_name == 'push' ||\n(github.event_name == 'pull_request' && (\n\ | |
| \ contains(github.event.pull_request.changed_files, '.github/actions/auto-label/')\ | |
| \ ||\n contains(github.event.pull_request.changed_files, '.github/workflows/auto-label.yml')\n\ | |
| ))\n" | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: '22' | |
| - name: Install action dependencies | |
| working-directory: .github/actions/auto-label | |
| run: npm ci | |
| - name: Run auto-label tests | |
| working-directory: .github/actions/auto-label | |
| run: npx vitest run --reporter=verbose |