fix(deps): update dependency prosemirror-history to v1.5.1 #5271
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: CI | |
| on: | |
| push: | |
| branches: ["main"] | |
| pull_request: | |
| branches: ["main"] | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| # =========================================== | |
| # Lint - Check code formatting | |
| # =========================================== | |
| lint: | |
| name: Lint | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - name: Setup Bun | |
| uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 | |
| with: | |
| bun-version-file: package.json | |
| - name: Cache Bun dependencies | |
| uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 | |
| with: | |
| path: ~/.bun/install/cache | |
| key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-bun- | |
| - name: Install dependencies | |
| run: bun install --frozen-lockfile | |
| - name: Check code formatting | |
| run: bun run lint | |
| # =========================================== | |
| # Unit Tests - Shared Packages (Vitest) | |
| # =========================================== | |
| test-packages: | |
| name: Unit Tests (Shared Packages) | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - name: Setup Bun | |
| uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 | |
| with: | |
| bun-version-file: package.json | |
| - name: Cache Bun dependencies | |
| uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 | |
| with: | |
| path: ~/.bun/install/cache | |
| key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-bun- | |
| - name: Install dependencies | |
| run: bun install --frozen-lockfile | |
| - name: Run shared package tests with coverage | |
| run: cd packages/inkweld-prosemirror && bun run test:coverage | |
| - name: Run inkweld-presence tests with coverage | |
| run: cd packages/inkweld-presence && bun run test:coverage | |
| - name: Upload packages coverage | |
| if: ${{ !cancelled() }} | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: packages-coverage | |
| path: packages/inkweld-prosemirror/coverage/lcov.info | |
| retention-days: 1 | |
| - name: Upload presence package coverage | |
| if: ${{ !cancelled() }} | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: presence-coverage | |
| path: packages/inkweld-presence/coverage/lcov.info | |
| retention-days: 1 | |
| # =========================================== | |
| # Unit Tests - Frontend (Vitest) - Sharded across parallel runners | |
| # =========================================== | |
| # `ng test` has no --shard flag, so frontend/scripts/test-shard.mjs deals | |
| # the spec files round-robin across the matrix and passes each shard's list | |
| # via --include. Unsharded this was the longest job in the workflow (~18m); | |
| # 2 shards (~9m each) bring it in line with the e2e jobs; 3 ran ~5-6m, | |
| # shorter than the e2e shards, so the extra runner bought no wall-clock. Each shard emits an lcov.info | |
| # covering the whole tree, so per-shard thresholds are disabled (the `shard` | |
| # configuration in angular.json) and enforced on the merged report in the | |
| # frontend-coverage job below. | |
| test-frontend: | |
| name: Unit Tests (Frontend) - Shard ${{ matrix.shardIndex }}/${{ matrix.shardTotal }} | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| shardIndex: [1, 2] | |
| shardTotal: [2] | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7 | |
| with: | |
| node-version: "24" | |
| - name: Setup Bun | |
| uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 | |
| with: | |
| bun-version-file: package.json | |
| - name: Cache Bun dependencies | |
| uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 | |
| with: | |
| path: ~/.bun/install/cache | |
| key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-bun- | |
| - name: Install dependencies | |
| run: bun install --frozen-lockfile | |
| - name: Show Node.js version | |
| run: node --version && bun --version | |
| - name: Run frontend tests (shard ${{ matrix.shardIndex }}/${{ matrix.shardTotal }}) | |
| run: cd frontend && NODE_OPTIONS="--max-old-space-size=8192" npm run test:shard -- ${{ matrix.shardIndex }}/${{ matrix.shardTotal }} | |
| - name: Upload frontend coverage shard | |
| if: ${{ !cancelled() }} | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: frontend-coverage-shard-${{ matrix.shardIndex }} | |
| path: frontend/coverage/inkweld-frontend/lcov.info | |
| retention-days: 1 | |
| # =========================================== | |
| # Frontend Coverage - merge shards + enforce thresholds | |
| # =========================================== | |
| frontend-coverage: | |
| name: Unit Tests (Frontend) - Coverage | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| needs: [test-frontend] | |
| # Merge whatever shards produced coverage even if a shard's tests failed, | |
| # so SonarCloud still gets a report; skip only on cancellation. | |
| if: ${{ !cancelled() }} | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7 | |
| with: | |
| node-version: "24" | |
| - name: Download coverage shards | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| pattern: frontend-coverage-shard-* | |
| path: frontend/coverage/shards | |
| - name: Merge coverage and check thresholds | |
| run: cd frontend && node scripts/merge-lcov.mjs --out coverage/inkweld-frontend/lcov.info coverage/shards/*/lcov.info | |
| - name: Upload frontend coverage | |
| if: ${{ !cancelled() }} | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: frontend-coverage | |
| path: frontend/coverage/inkweld-frontend/lcov.info | |
| retention-days: 1 | |
| # =========================================== | |
| # Unit Tests - Backend (Bun) | |
| # =========================================== | |
| test-backend: | |
| name: Unit Tests (Backend) | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - name: Setup Bun | |
| uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 | |
| with: | |
| bun-version-file: package.json | |
| - name: Cache Bun dependencies | |
| uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 | |
| with: | |
| path: ~/.bun/install/cache | |
| key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-bun- | |
| - name: Install dependencies | |
| run: bun install --frozen-lockfile | |
| - name: Run backend tests | |
| run: cd backend && DB_DATABASE=":memory:" USER_APPROVAL_REQUIRED="false" bun run test:coverage | |
| - name: Upload backend coverage | |
| if: ${{ !cancelled() }} | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: backend-coverage | |
| path: backend/coverage/lcov.info | |
| retention-days: 1 | |
| # =========================================== | |
| # SonarCloud Analysis | |
| # =========================================== | |
| sonarcloud: | |
| name: SonarCloud Code Analysis | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| needs: [frontend-coverage, test-backend, test-packages] | |
| # Run even when the test jobs fail (partial coverage is still worth | |
| # scanning), but NOT when the run is cancelled - `always()` would also | |
| # match cancellations, and a superseded run's coverage artifacts never | |
| # get uploaded, so the scan would report 0% coverage on new code and post | |
| # a false quality gate failure to the PR. | |
| # Also skip SonarCloud analysis for Renovate dependency PRs (machine-generated). | |
| if: ${{ !cancelled() && !startsWith(github.head_ref, 'renovate/') }} | |
| # Configure the 15-minute wait timer on the sonarcloud-analysis environment. | |
| environment: | |
| name: sonarcloud-analysis | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| with: | |
| fetch-depth: 0 | |
| - name: Download frontend coverage | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| name: frontend-coverage | |
| path: frontend/coverage/inkweld-frontend | |
| continue-on-error: true | |
| - name: Download backend coverage | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| name: backend-coverage | |
| path: backend/coverage | |
| continue-on-error: true | |
| - name: Download packages coverage | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| name: packages-coverage | |
| path: packages/inkweld-prosemirror/coverage | |
| continue-on-error: true | |
| - name: Download presence package coverage | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| name: presence-coverage | |
| path: packages/inkweld-presence/coverage | |
| continue-on-error: true | |
| - name: SonarCloud Scan | |
| uses: SonarSource/sonarqube-scan-action@ba9859eae8dd6bd29e412f25ddbbef3d032000f4 # v8 | |
| env: | |
| SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| # =========================================== | |
| # E2E Tests - Sharded across parallel runners | |
| # =========================================== | |
| # The heavier e2e jobs are split with Playwright's --shard=N/T flag using a | |
| # GitHub Actions matrix so test files are evenly distributed across runners. | |
| # Wall-clock time drops roughly 1/N at the cost of N runners' worth of | |
| # compute (each shard re-runs setup). | |
| # | |
| # Shard counts were tuned against historical job durations: Docker ~15m, | |
| # Wrangler ~13m at 2 shards (now 3), Online ~11m. Local (~8m) and | |
| # Screenshots (~9m) are left unsharded - Local because the savings don't | |
| # justify the extra runner, and | |
| # Screenshots because it is driven by the docs build rather than | |
| # `playwright test` directly and must run sequentially for visual | |
| # consistency. | |
| # Local E2E Tests (24 spec files - unsharded; ~8m on the runner) | |
| e2e-local: | |
| name: E2E Tests (Local) | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7 | |
| with: | |
| node-version: "24" | |
| - name: Setup Bun | |
| uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 | |
| with: | |
| bun-version-file: package.json | |
| - name: Cache Bun dependencies | |
| uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 | |
| with: | |
| path: ~/.bun/install/cache | |
| key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-bun- | |
| - name: Install dependencies | |
| run: bun install --frozen-lockfile | |
| - name: Get installed Playwright version | |
| id: playwright-version | |
| run: echo "version=$(node -p "require('@playwright/test/package.json').version")" >> $GITHUB_OUTPUT | |
| working-directory: frontend | |
| - name: Cache Playwright browsers | |
| id: playwright-cache | |
| uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 | |
| with: | |
| path: ~/.cache/ms-playwright | |
| key: ${{ runner.os }}-playwright-${{ steps.playwright-version.outputs.version }} | |
| - name: Install Playwright browsers | |
| if: steps.playwright-cache.outputs.cache-hit != 'true' | |
| run: cd frontend && ./node_modules/.bin/playwright install --with-deps chromium | |
| - name: Install Playwright system deps | |
| if: steps.playwright-cache.outputs.cache-hit == 'true' | |
| run: cd frontend && ./node_modules/.bin/playwright install-deps chromium | |
| - name: Build frontend | |
| run: cd frontend && npm run build | |
| - name: Run local e2e tests | |
| run: cd frontend && npm run e2e:local:ci | |
| env: | |
| E2E_MODE: prod | |
| - name: Upload Playwright reports | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| if: failure() | |
| with: | |
| name: playwright-report-local | |
| path: frontend/playwright-report/ | |
| retention-days: 7 | |
| - name: Upload Playwright test results (traces, screenshots, videos) | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| # `always()` rather than `failure()`: a test that failed once and passed | |
| # on retry leaves the job green, but its first-attempt trace/screenshot | |
| # (trace: 'retain-on-first-failure') is what we need to debug the flake. | |
| # On a clean run the directory is empty and nothing is uploaded. | |
| if: always() | |
| with: | |
| name: playwright-test-results-local | |
| path: frontend/test-results/ | |
| retention-days: 7 | |
| if-no-files-found: ignore | |
| # Online E2E Tests (22 spec files - 2 shards) | |
| e2e-online: | |
| name: E2E Tests (Online) - Shard ${{ matrix.shardIndex }}/${{ matrix.shardTotal }} | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| shardIndex: [1, 2] | |
| shardTotal: [2] | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7 | |
| with: | |
| node-version: "24" | |
| - name: Setup Bun | |
| uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 | |
| with: | |
| bun-version-file: package.json | |
| - name: Cache Bun dependencies | |
| uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 | |
| with: | |
| path: ~/.bun/install/cache | |
| key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-bun- | |
| - name: Install dependencies | |
| run: bun install --frozen-lockfile | |
| - name: Get installed Playwright version | |
| id: playwright-version | |
| run: echo "version=$(node -p "require('@playwright/test/package.json').version")" >> $GITHUB_OUTPUT | |
| working-directory: frontend | |
| - name: Cache Playwright browsers | |
| id: playwright-cache | |
| uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 | |
| with: | |
| path: ~/.cache/ms-playwright | |
| key: ${{ runner.os }}-playwright-${{ steps.playwright-version.outputs.version }} | |
| - name: Install Playwright browsers | |
| if: steps.playwright-cache.outputs.cache-hit != 'true' | |
| run: cd frontend && ./node_modules/.bin/playwright install --with-deps chromium | |
| - name: Install Playwright system deps | |
| if: steps.playwright-cache.outputs.cache-hit == 'true' | |
| run: cd frontend && ./node_modules/.bin/playwright install-deps chromium | |
| - name: Build frontend | |
| run: cd frontend && npm run build | |
| - name: Run online e2e tests (shard ${{ matrix.shardIndex }}/${{ matrix.shardTotal }}) | |
| run: cd frontend && npm run e2e:online:ci -- --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }} | |
| env: | |
| E2E_MODE: prod | |
| - name: Upload Playwright reports | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| if: failure() | |
| with: | |
| name: playwright-report-online-shard-${{ matrix.shardIndex }} | |
| path: frontend/playwright-report/ | |
| retention-days: 7 | |
| - name: Upload Playwright test results (traces, screenshots, videos) | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| # `always()` rather than `failure()`: a test that failed once and passed | |
| # on retry leaves the job green, but its first-attempt trace/screenshot | |
| # (trace: 'retain-on-first-failure') is what we need to debug the flake. | |
| # On a clean run the directory is empty and nothing is uploaded. | |
| if: always() | |
| with: | |
| name: playwright-test-results-online-shard-${{ matrix.shardIndex }} | |
| path: frontend/test-results/ | |
| retention-days: 7 | |
| if-no-files-found: ignore | |
| # Wrangler E2E Tests (22 spec files - 3 shards; the slowest e2e job at 2) | |
| e2e-wrangler: | |
| name: E2E Tests (Wrangler) - Shard ${{ matrix.shardIndex }}/${{ matrix.shardTotal }} | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| shardIndex: [1, 2, 3] | |
| shardTotal: [3] | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7 | |
| with: | |
| node-version: "24" | |
| - name: Setup Bun | |
| uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 | |
| with: | |
| bun-version-file: package.json | |
| - name: Cache Bun dependencies | |
| uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 | |
| with: | |
| path: ~/.bun/install/cache | |
| key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-bun- | |
| - name: Install dependencies | |
| run: bun install --frozen-lockfile | |
| - name: Get installed Playwright version | |
| id: playwright-version | |
| run: echo "version=$(node -p "require('@playwright/test/package.json').version")" >> $GITHUB_OUTPUT | |
| working-directory: frontend | |
| - name: Cache Playwright browsers | |
| id: playwright-cache | |
| uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 | |
| with: | |
| path: ~/.cache/ms-playwright | |
| key: ${{ runner.os }}-playwright-${{ steps.playwright-version.outputs.version }} | |
| - name: Install Playwright browsers | |
| if: steps.playwright-cache.outputs.cache-hit != 'true' | |
| run: cd frontend && ./node_modules/.bin/playwright install --with-deps chromium | |
| - name: Install Playwright system deps | |
| if: steps.playwright-cache.outputs.cache-hit == 'true' | |
| run: cd frontend && ./node_modules/.bin/playwright install-deps chromium | |
| - name: Copy wrangler.toml for CI | |
| run: cp backend/wrangler.toml.example backend/wrangler.toml | |
| - name: Initialize local D1 database | |
| run: cd backend && bun run init:d1-local | |
| - name: Build frontend | |
| run: cd frontend && npm run build | |
| - name: Run wrangler e2e tests (shard ${{ matrix.shardIndex }}/${{ matrix.shardTotal }}) | |
| # Retries once in CI like the other e2e jobs (see the `retries` note in | |
| # playwright.wrangler.config.ts). A backend crash still fails the shard: | |
| # every test after it fails on the retry too. A one-off flake passes on | |
| # retry and leaves its first-attempt trace in the test-results artifact. | |
| run: cd frontend && npm run e2e:wrangler:ci -- --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }} | |
| env: | |
| E2E_MODE: prod | |
| # Where the wrangler backend's stdout/stderr is tee'd (see | |
| # playwright.wrangler.config.ts). Uploaded as an artifact on failure | |
| # so a native workerd crash stack is preserved for investigation. | |
| # Note: the webServer runs with cwd ../backend, so this must be | |
| # absolute to land in a stable, project-owned location. | |
| WRANGLER_LOG_FILE: ${{ github.workspace }}/wrangler-backend.log | |
| # wrangler's own diagnostic log records what the console's empty | |
| # "[ERROR]" line hides. When a transient ProxyWorker disconnect | |
| # ("Network connection lost.") kills `wrangler dev` mid-run — see | |
| # cloudflare/workers-sdk#15317 — the real cause only shows up at | |
| # debug level in this file. Redirected into the workspace so it can | |
| # be uploaded as an artifact instead of staying in the runner home. | |
| WRANGLER_LOG: debug | |
| WRANGLER_LOG_PATH: ${{ github.workspace }}/wrangler-debug-logs | |
| - name: Upload Playwright reports | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| if: failure() | |
| with: | |
| name: playwright-report-wrangler-shard-${{ matrix.shardIndex }} | |
| path: frontend/playwright-report/ | |
| retention-days: 7 | |
| - name: Upload Playwright test results (traces, screenshots, videos) | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| # `always()` rather than `failure()`: a test that failed once and passed | |
| # on retry leaves the job green, but its first-attempt trace/screenshot | |
| # (trace: 'retain-on-first-failure') is what we need to debug the flake. | |
| # On a clean run the directory is empty and nothing is uploaded. | |
| if: always() | |
| with: | |
| name: playwright-test-results-wrangler-shard-${{ matrix.shardIndex }} | |
| path: frontend/test-results/ | |
| retention-days: 7 | |
| if-no-files-found: ignore | |
| - name: Upload wrangler backend log | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| if: failure() | |
| with: | |
| name: wrangler-backend-log-shard-${{ matrix.shardIndex }} | |
| path: wrangler-backend.log | |
| retention-days: 7 | |
| - name: Upload wrangler diagnostic log | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| if: failure() | |
| with: | |
| name: wrangler-diag-log-shard-${{ matrix.shardIndex }} | |
| path: wrangler-debug-logs/ | |
| retention-days: 7 | |
| if-no-files-found: warn | |
| # Docker E2E Tests (22 spec files - 2 shards) | |
| # Note: each shard rebuilds the Docker image in globalSetup, so the per-job | |
| # cost is high. We deliberately keep this at 2 shards to avoid blowing up | |
| # compute usage. | |
| e2e-docker: | |
| name: E2E Tests (Docker) - Shard ${{ matrix.shardIndex }}/${{ matrix.shardTotal }} | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| shardIndex: [1, 2] | |
| shardTotal: [2] | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7 | |
| with: | |
| node-version: "24" | |
| - name: Setup Bun | |
| uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 | |
| with: | |
| bun-version-file: package.json | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4 | |
| - name: Cache Bun dependencies | |
| uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 | |
| with: | |
| path: ~/.bun/install/cache | |
| key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-bun- | |
| - name: Install dependencies | |
| run: bun install --frozen-lockfile | |
| - name: Get installed Playwright version | |
| id: playwright-version | |
| run: echo "version=$(node -p "require('@playwright/test/package.json').version")" >> $GITHUB_OUTPUT | |
| working-directory: frontend | |
| - name: Cache Playwright browsers | |
| id: playwright-cache | |
| uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 | |
| with: | |
| path: ~/.cache/ms-playwright | |
| key: ${{ runner.os }}-playwright-${{ steps.playwright-version.outputs.version }} | |
| - name: Install Playwright browsers | |
| if: steps.playwright-cache.outputs.cache-hit != 'true' | |
| run: cd frontend && ./node_modules/.bin/playwright install --with-deps chromium | |
| - name: Install Playwright system deps | |
| if: steps.playwright-cache.outputs.cache-hit == 'true' | |
| run: cd frontend && ./node_modules/.bin/playwright install-deps chromium | |
| - name: Run Docker e2e tests (shard ${{ matrix.shardIndex }}/${{ matrix.shardTotal }}) | |
| run: cd frontend && npm run e2e:docker:ci -- --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }} | |
| - name: Upload Playwright reports | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| if: failure() | |
| with: | |
| name: playwright-report-docker-shard-${{ matrix.shardIndex }} | |
| path: frontend/playwright-report/ | |
| retention-days: 7 | |
| - name: Upload Playwright test results (traces, screenshots, videos) | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| # `always()` rather than `failure()`: a test that failed once and passed | |
| # on retry leaves the job green, but its first-attempt trace/screenshot | |
| # (trace: 'retain-on-first-failure') is what we need to debug the flake. | |
| # On a clean run the directory is empty and nothing is uploaded. | |
| if: always() | |
| with: | |
| name: playwright-test-results-docker-shard-${{ matrix.shardIndex }} | |
| path: frontend/test-results/ | |
| retention-days: 7 | |
| if-no-files-found: ignore | |
| # =========================================== | |
| # E2E Tests - Screenshots (via docs build) | |
| # =========================================== | |
| # Not sharded: this job builds the docs site, which runs the screenshot | |
| # tests as a side effect. The tests must run sequentially to produce | |
| # consistent visual output. | |
| e2e-screenshots: | |
| name: E2E Tests (Screenshots) | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7 | |
| with: | |
| node-version: "24" | |
| - name: Setup Bun | |
| uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 | |
| with: | |
| bun-version-file: package.json | |
| - name: Cache Bun dependencies | |
| uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 | |
| with: | |
| path: ~/.bun/install/cache | |
| key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-bun- | |
| - name: Install dependencies | |
| run: bun install --frozen-lockfile | |
| - name: Get installed Playwright version | |
| id: playwright-version | |
| run: echo "version=$(node -p "require('@playwright/test/package.json').version")" >> $GITHUB_OUTPUT | |
| working-directory: frontend | |
| - name: Cache Playwright browsers | |
| id: playwright-cache | |
| uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 | |
| with: | |
| path: ~/.cache/ms-playwright | |
| key: ${{ runner.os }}-playwright-${{ steps.playwright-version.outputs.version }} | |
| - name: Install Playwright browsers | |
| if: steps.playwright-cache.outputs.cache-hit != 'true' | |
| run: cd frontend && ./node_modules/.bin/playwright install --with-deps chromium | |
| - name: Install Playwright system deps | |
| if: steps.playwright-cache.outputs.cache-hit == 'true' | |
| run: cd frontend && ./node_modules/.bin/playwright install-deps chromium | |
| - name: Build docs (runs screenshot e2e tests) | |
| run: cd docs/site && bun run build | |
| - name: Upload Playwright reports | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| if: failure() | |
| with: | |
| name: playwright-report-screenshots | |
| path: frontend/playwright-report/ | |
| retention-days: 7 | |
| # =========================================== | |
| # Build and Push Dev Docker Image (Multi-arch) | |
| # =========================================== | |
| # Pre-build frontend on AMD64 (output is platform-agnostic) | |
| docker-frontend-build: | |
| name: Build Frontend for Docker | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| needs: | |
| [ | |
| lint, | |
| test-frontend, | |
| frontend-coverage, | |
| test-backend, | |
| test-packages, | |
| e2e-local, | |
| e2e-online, | |
| e2e-wrangler, | |
| e2e-docker, | |
| e2e-screenshots, | |
| ] | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - name: Setup Bun | |
| uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 | |
| with: | |
| bun-version-file: package.json | |
| - name: Install dependencies | |
| # Workspace-root install so the @inkweld/prosemirror peer deps | |
| # (prosemirror-model, yjs) are available for the shared package | |
| # consumed by the frontend build. | |
| run: bun install --frozen-lockfile | |
| - name: Build frontend | |
| run: cd frontend && bun run build | |
| - name: Compress WASM files | |
| run: cd frontend && node scripts/compress-wasm.js | |
| - name: Upload frontend dist | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: frontend-dist | |
| path: frontend/dist | |
| retention-days: 1 | |
| # Build AMD64 image | |
| docker-dev-amd64: | |
| name: Build Docker (amd64) | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| packages: write | |
| needs: [docker-frontend-build] | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - name: Download frontend dist | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| name: frontend-dist | |
| path: frontend/dist | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4 | |
| - name: Log in to GitHub Container Registry | |
| uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Build and push Docker image (amd64) | |
| uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7 | |
| with: | |
| context: . | |
| file: Dockerfile | |
| push: true | |
| platforms: linux/amd64 | |
| tags: ghcr.io/${{ github.repository_owner }}/inkweld:dev-amd64 | |
| build-args: FRONTEND_PREBUILT=true | |
| cache-from: type=gha,scope=amd64 | |
| cache-to: type=gha,mode=max,scope=amd64 | |
| provenance: false | |
| # Build ARM64 image on native ARM runner | |
| docker-dev-arm64: | |
| name: Build Docker (arm64) | |
| runs-on: ubuntu-26.04-arm | |
| permissions: | |
| contents: read | |
| packages: write | |
| needs: [docker-frontend-build] | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - name: Download frontend dist | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| name: frontend-dist | |
| path: frontend/dist | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4 | |
| - name: Log in to GitHub Container Registry | |
| uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Build and push Docker image (arm64) | |
| uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7 | |
| with: | |
| context: . | |
| file: Dockerfile | |
| push: true | |
| platforms: linux/arm64 | |
| tags: ghcr.io/${{ github.repository_owner }}/inkweld:dev-arm64 | |
| build-args: FRONTEND_PREBUILT=true | |
| cache-from: type=gha,scope=arm64 | |
| cache-to: type=gha,mode=max,scope=arm64 | |
| provenance: false | |
| # Create multi-arch manifest | |
| docker-dev-manifest: | |
| name: Create Docker Manifest | |
| runs-on: ubuntu-latest | |
| permissions: | |
| packages: write | |
| needs: [docker-dev-amd64, docker-dev-arm64] | |
| steps: | |
| - name: Log in to GitHub Container Registry | |
| uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Create and push multi-arch manifest | |
| run: | | |
| docker manifest create ghcr.io/${{ github.repository_owner }}/inkweld:dev \ | |
| ghcr.io/${{ github.repository_owner }}/inkweld:dev-amd64 \ | |
| ghcr.io/${{ github.repository_owner }}/inkweld:dev-arm64 | |
| docker manifest push ghcr.io/${{ github.repository_owner }}/inkweld:dev |