Update build-and-test.yml (#1311) #1434
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: Build & Test | |
| on: | |
| push: | |
| branches: | |
| - main | |
| - 3.x | |
| - 2.x | |
| # Skip on docs-only / metadata-only pushes. Keep this list in SYNC with | |
| # build-and-test-skip.yml - that companion workflow reports success for | |
| # the same required-check names when this one is skipped, otherwise PRs | |
| # that only touch docs would hang forever on "Waiting for status to be | |
| # reported" (GitHub's well-known paths-filter + required-check gotcha). | |
| paths-ignore: | |
| - '**/*.md' | |
| - 'demos/**' | |
| - 'website/**' | |
| - 'LICENSE' | |
| - '.gitattributes' | |
| - '.editorconfig' | |
| - '.prettierignore' | |
| - '.prettierrc' | |
| - '.nvmrc' | |
| - '.gitignore' | |
| - '.husky/**' | |
| - '.pre-commit-config.yaml' | |
| - 'osv-scanner.toml' | |
| - '.github/ISSUE_TEMPLATE.md' | |
| - '.github/PULL_REQUEST_TEMPLATE.md' | |
| - '.github/FUNDING.yml' | |
| - '.github/dependabot.yml' | |
| - '.github/workflows/codeql-analysis.yml' | |
| - '.github/workflows/dependency-review.yml' | |
| - '.github/workflows/fuzz.yml' | |
| - '.github/workflows/scorecard.yml' | |
| - '.github/workflows/sign-release.yml' | |
| - '.github/workflows/slsa-provenance.yml' | |
| pull_request: | |
| paths-ignore: | |
| - '**/*.md' | |
| - 'demos/**' | |
| - 'website/**' | |
| - 'LICENSE' | |
| - '.gitattributes' | |
| - '.editorconfig' | |
| - '.prettierignore' | |
| - '.prettierrc' | |
| - '.nvmrc' | |
| - '.gitignore' | |
| - '.husky/**' | |
| - '.pre-commit-config.yaml' | |
| - 'osv-scanner.toml' | |
| - '.github/ISSUE_TEMPLATE.md' | |
| - '.github/PULL_REQUEST_TEMPLATE.md' | |
| - '.github/FUNDING.yml' | |
| - '.github/dependabot.yml' | |
| - '.github/workflows/codeql-analysis.yml' | |
| - '.github/workflows/dependency-review.yml' | |
| - '.github/workflows/fuzz.yml' | |
| - '.github/workflows/scorecard.yml' | |
| - '.github/workflows/sign-release.yml' | |
| - '.github/workflows/slsa-provenance.yml' | |
| permissions: | |
| contents: read | |
| # Cancel superseded runs on the same PR to save minutes on rapid pushes. | |
| # Pushes to protected branches are NOT cancelled - we want full CI history | |
| # for every merged commit. | |
| concurrency: | |
| group: build-test-${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: ${{ github.event_name == 'pull_request' }} | |
| jobs: | |
| # Fast feedback: lint, jsdom, chromium-only browser test across Node versions. | |
| # Runs on every push and every PR. | |
| install: | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| node-version: [20.x, 22.x, 24.x, 25.x] | |
| steps: | |
| - name: Harden the runner (Audit all outbound calls) | |
| uses: step-security/harden-runner@6c3c2f2c1c457b00c10c4848d6f5491db3b629df # v2.18.0 | |
| with: | |
| egress-policy: audit | |
| - name: Checkout | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| persist-credentials: false | |
| - name: Setup Node.js ${{ matrix.node-version }} | |
| uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 | |
| with: | |
| node-version: ${{ matrix.node-version }} | |
| cache: npm | |
| - name: Install Dependencies | |
| run: npm ci | |
| # All three engines - test:ci runs the full browser matrix (no | |
| # --project flag, unlike local `npm test`). DOMPurify's security | |
| # posture depends on per-engine HTML parser behaviour being exercised, | |
| # so this coverage is kept on every PR despite the download cost. | |
| - name: Install Playwright Browsers | |
| run: ./node_modules/.bin/playwright install --with-deps chromium firefox webkit | |
| - name: Build | |
| run: npm run build | |
| - name: Verify dist/ matches src/ | |
| run: | | |
| if ! git diff --quiet dist/; then | |
| echo "::error::dist/ is out of sync with src/. The husky pre-commit hook should have rebuilt dist/ before commit. Did you commit without running 'npm install' first (which wires up the hook), or bypass hooks with --no-verify?" | |
| echo "--- dist/ diff ---" | |
| git diff --stat dist/ | |
| git diff dist/ | head -100 | |
| exit 1 | |
| fi | |
| echo "dist/ matches src/ ✓" | |
| - name: Lint | |
| run: npm run lint | |
| - name: Test | |
| run: npm run test:ci | |
| - name: Upload Playwright report | |
| if: failure() | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: playwright-report-node-${{ matrix.node-version }} | |
| path: playwright-report/ | |
| retention-days: 7 | |
| - name: Verify TypeScript | |
| run: npm run verify-typescript | |
| # Browser diversity: chromium + firefox + webkit across Ubuntu, macOS, and | |
| # Windows. Catches OS-specific rendering quirks (e.g. macOS WebKit ≈ real | |
| # Safari engine, Windows font shaping, Linux-specific parser paths). | |
| # | |
| # Only runs on release branches (main, 2.x, 3.x) to conserve runner minutes. | |
| # PRs get chromium-only coverage from the "install" job above, which is | |
| # sufficient for catching regressions. | |
| browser-matrix: | |
| if: github.event_name == 'push' | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest, windows-latest] | |
| steps: | |
| - name: Harden the runner (Audit all outbound calls) | |
| uses: step-security/harden-runner@6c3c2f2c1c457b00c10c4848d6f5491db3b629df # v2.18.0 | |
| with: | |
| egress-policy: audit | |
| - name: Checkout | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| persist-credentials: false | |
| - name: Setup Node.js 25.x | |
| uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 | |
| with: | |
| node-version: 25.x | |
| cache: npm | |
| - name: Install Dependencies | |
| run: npm ci | |
| - name: Install Playwright Browsers (Linux) | |
| if: runner.os == 'Linux' | |
| run: ./node_modules/.bin/playwright install --with-deps chromium firefox webkit | |
| - name: Install Playwright Browsers (macOS / Windows) | |
| if: runner.os != 'Linux' | |
| run: ./node_modules/.bin/playwright install chromium firefox webkit | |
| - name: Build | |
| run: npm run build | |
| - name: Run browser tests (all engines) | |
| run: npm run test:browser | |
| - name: Upload Playwright report | |
| if: failure() | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: playwright-report-${{ matrix.os }} | |
| path: playwright-report/ | |
| retention-days: 7 |