feat: monorepo modernization — pnpm 11 + Node 24, Docusaurus docs, React <Apollon> API, VS Code rewrite
#10
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: PR Health Checks | |
| on: | |
| pull_request: | |
| types: [opened, synchronize, reopened] | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| pull-requests: read | |
| jobs: | |
| detect-changes: | |
| name: Detect changes | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| outputs: | |
| code: ${{ steps.filter.outputs.code }} | |
| library: ${{ steps.filter.outputs.library }} | |
| should-skip: ${{ steps.skip-check.outputs.should_skip }} | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| - id: skip-check | |
| uses: fkirc/skip-duplicate-actions@f75f66ce1886f00957d99748a42c724f4330bdcf # v5 | |
| with: | |
| do_not_skip: '["workflow_dispatch"]' | |
| - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3 | |
| id: filter | |
| if: steps.skip-check.outputs.should_skip != 'true' | |
| with: | |
| filters: | | |
| code: | |
| - 'library/**' | |
| - 'standalone/**' | |
| - 'vscode-extension/**' | |
| - 'package.json' | |
| - 'pnpm-lock.yaml' | |
| - 'pnpm-workspace.yaml' | |
| - '.npmrc' | |
| - '.nvmrc' | |
| - 'tsconfig*.json' | |
| - '.github/workflows/pr-health-checks.yml' | |
| library: | |
| - 'library/**' | |
| - 'pnpm-lock.yaml' | |
| - 'pnpm-workspace.yaml' | |
| - '.github/workflows/pr-health-checks.yml' | |
| lint-and-format-check: | |
| needs: [detect-changes] | |
| if: needs.detect-changes.outputs.should-skip != 'true' && needs.detect-changes.outputs.code == 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| - name: Install pnpm | |
| uses: pnpm/action-setup@ac6db6d3c1f721f886538a378a2d73e85697340a # v6.0.8 | |
| - name: Set up Node | |
| uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6 | |
| with: | |
| node-version-file: ".nvmrc" | |
| cache: "pnpm" | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Run Lint | |
| run: pnpm run lint | |
| - name: Check format | |
| run: pnpm run format:check | |
| - name: Check build | |
| run: pnpm run build | |
| - name: Run unit tests | |
| run: pnpm run test | |
| e2e-tests: | |
| needs: [detect-changes] | |
| if: needs.detect-changes.outputs.should-skip != 'true' && needs.detect-changes.outputs.code == 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| - name: Install pnpm | |
| uses: pnpm/action-setup@ac6db6d3c1f721f886538a378a2d73e85697340a # v6.0.8 | |
| - name: Set up Node | |
| uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6 | |
| with: | |
| node-version-file: ".nvmrc" | |
| cache: "pnpm" | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Build | |
| run: pnpm run build:lib | |
| - name: Cache Playwright browsers | |
| uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 | |
| id: playwright-cache | |
| with: | |
| path: ~/.cache/ms-playwright | |
| key: playwright-${{ runner.os }}-v1.59.1-${{ hashFiles('standalone/webapp/package.json') }} | |
| - name: Install Playwright browsers | |
| if: steps.playwright-cache.outputs.cache-hit != 'true' | |
| run: pnpm --filter @tumaet/webapp exec playwright install chromium | |
| - name: Install Playwright system deps | |
| run: pnpm --filter @tumaet/webapp exec playwright install-deps chromium | |
| - name: Run E2E tests | |
| run: pnpm --filter @tumaet/webapp exec playwright test tests/e2e/ | |
| - name: Upload Playwright report | |
| if: ${{ failure() }} | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: playwright-report-e2e | |
| path: standalone/webapp/playwright-report/ | |
| retention-days: 14 | |
| - name: Upload Playwright test results | |
| if: ${{ failure() }} | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: playwright-test-results-e2e | |
| path: standalone/webapp/test-results/ | |
| retention-days: 14 | |
| # Library has `engines.node: ">=22"` for its published consumers — back the | |
| # promise with a build+test on Node 22 LTS so a Node-24-only feature can't | |
| # silently land in the npm tarball. | |
| library-node22-compat: | |
| needs: [detect-changes] | |
| if: needs.detect-changes.outputs.should-skip != 'true' && needs.detect-changes.outputs.library == 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| - name: Install pnpm | |
| uses: pnpm/action-setup@ac6db6d3c1f721f886538a378a2d73e85697340a # v6.0.8 | |
| - name: Set up Node 22 LTS | |
| uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6 | |
| with: | |
| node-version: "22" | |
| cache: "pnpm" | |
| - name: Install dependencies | |
| # `engine-strict=true` rejects Node 22 against the root `>=24.15.0` | |
| # gate; library workspace is `>=22`, so install with the flag off. | |
| run: pnpm install --frozen-lockfile --config.engine-strict=false | |
| - name: Build library | |
| run: pnpm --filter @tumaet/apollon run build | |
| - name: Run library unit tests | |
| run: pnpm --filter @tumaet/apollon run test | |
| - name: Verify ESM exports-map resolution | |
| # The library is ESM-only. `import.meta.resolve` (sync, no side | |
| # effects) validates every subpath in the exports map — actually | |
| # evaluating the module would require jsdom. | |
| working-directory: standalone/server | |
| run: | | |
| node --input-type=module -e ' | |
| const root = import.meta.resolve("@tumaet/apollon"); | |
| const internals = import.meta.resolve("@tumaet/apollon/internals"); | |
| const css = import.meta.resolve("@tumaet/apollon/style.css"); | |
| console.log({ root, internals, css }); | |
| ' | |
| # Baseline regeneration: see docs/development/visual-tests.md. | |
| visual-regression-tests: | |
| needs: [detect-changes] | |
| if: needs.detect-changes.outputs.should-skip != 'true' && needs.detect-changes.outputs.code == 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| container: | |
| image: mcr.microsoft.com/playwright:v1.59.1-noble | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| - name: Install Node 24 | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| curl -fsSL https://deb.nodesource.com/setup_24.x | bash - | |
| apt-get install -y nodejs | |
| node --version | |
| - name: Install pnpm | |
| uses: pnpm/action-setup@ac6db6d3c1f721f886538a378a2d73e85697340a # v6.0.8 | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Build | |
| run: pnpm run build:lib | |
| - name: Run visual regression tests | |
| run: pnpm --filter @tumaet/webapp exec playwright test tests/visual/ | |
| - name: Upload Playwright report | |
| if: ${{ failure() }} | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: playwright-report-visual | |
| path: standalone/webapp/playwright-report/ | |
| retention-days: 14 | |
| - name: Upload Playwright test results | |
| if: ${{ failure() }} | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: playwright-test-results-visual | |
| path: standalone/webapp/test-results/ | |
| retention-days: 14 | |
| # Gate job — set this as the required status check in branch protection. | |
| # Correctly handles skipped jobs (docs-only, duplicate runs). | |
| pr-health-gate: | |
| name: PR Health Gate | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 2 | |
| needs: | |
| [ | |
| detect-changes, | |
| lint-and-format-check, | |
| library-node22-compat, | |
| e2e-tests, | |
| visual-regression-tests, | |
| ] | |
| if: always() | |
| steps: | |
| - name: Evaluate results | |
| run: | | |
| if [[ "${{ contains(needs.*.result, 'failure') }}" == "true" ]]; then | |
| echo "One or more checks failed" | |
| exit 1 | |
| fi | |
| if [[ "${{ contains(needs.*.result, 'cancelled') }}" == "true" ]]; then | |
| echo "One or more checks were cancelled" | |
| exit 1 | |
| fi | |
| echo "All checks passed or were skipped" |