fix(socketio-shim): NonNullable<> on harness setTimer type to fix tsgo #45
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: ci-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| test: | |
| name: typecheck + test + coverage gate | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: latest | |
| - name: Install dependencies | |
| run: bun install --frozen-lockfile | |
| - name: Typecheck (all packages) | |
| run: | | |
| bun run --cwd packages/shared typecheck | |
| bun run --cwd packages/socialcalc-headless typecheck | |
| bun run --cwd packages/worker typecheck | |
| bun run --cwd packages/client typecheck | |
| bun run --cwd packages/client-multi typecheck | |
| bun run --cwd packages/oracle-harness typecheck | |
| bun run --cwd packages/cli typecheck | |
| bun run --cwd packages/socketio-shim typecheck | |
| bun run --cwd packages/migrate typecheck | |
| bun run --cwd packages/e2e typecheck | |
| - name: shared — tests + 100% coverage gate | |
| run: bun run --cwd packages/shared test:coverage | |
| - name: worker — Node tests + 100% coverage gate | |
| run: bun run --cwd packages/worker test:coverage | |
| - name: client — Vite build (needed for assets/static/player.js) | |
| run: bun run --cwd packages/client build | |
| - name: client-multi — Vite build (needed for assets/multi/) | |
| run: bun run --cwd packages/client-multi build | |
| - name: Build curated assets/ dir (scripts/build-assets.sh) | |
| # Phase 4.1/11: regenerates `assets/` at repo root from the | |
| # client/client-multi dist output plus the legacy static files. | |
| # Must run BEFORE worker integration tests (miniflare reads | |
| # wrangler.toml `[assets]` at startup) and `wrangler deploy | |
| # --dry-run` (validates the directory exists). | |
| run: ./scripts/build-assets.sh | |
| - name: Validate worker D1 migrations | |
| # Phase 5.1: smoke-check each SQL file in packages/worker/migrations/ | |
| # by replaying it into a fresh in-memory SQLite DB. Catches syntax | |
| # errors before they blow up at miniflare startup or on a real | |
| # `wrangler d1 migrations apply` in prod. ubuntu-latest ships with | |
| # sqlite3 preinstalled. | |
| run: | | |
| for f in packages/worker/migrations/*.sql; do | |
| echo "applying $f" | |
| sqlite3 :memory: < "$f" | |
| done | |
| - name: worker — integration tests (workerd via miniflare) | |
| run: bun run --cwd packages/worker test:workers | |
| - name: worker — wrangler dry-run build | |
| run: bun run --cwd packages/worker build:dry | |
| - name: socialcalc-headless — smoke tests (workerd) | |
| run: bun run --cwd packages/socialcalc-headless test | |
| - name: client — tests + 100% coverage gate | |
| run: bun run --cwd packages/client test:coverage | |
| - name: client-multi — tests + 100% coverage gate | |
| run: bun run --cwd packages/client-multi test:coverage | |
| - name: oracle-harness — tests + 100% coverage gate | |
| run: bun run --cwd packages/oracle-harness test:coverage | |
| - name: cli — tests + 100% coverage gate | |
| run: bun run --cwd packages/cli test:coverage | |
| - name: socketio-shim — tests + 100% coverage gate | |
| run: bun run --cwd packages/socketio-shim test:coverage | |
| - name: migrate — tests + 100% coverage gate | |
| run: bun run --cwd packages/migrate test:coverage | |
| - name: Upload coverage artifacts | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: coverage-lcov | |
| path: | | |
| packages/shared/coverage/ | |
| packages/worker/coverage/ | |
| packages/client/coverage/ | |
| packages/client-multi/coverage/ | |
| packages/oracle-harness/coverage/ | |
| packages/cli/coverage/ | |
| packages/socketio-shim/coverage/ | |
| packages/migrate/coverage/ | |
| retention-days: 7 | |
| if-no-files-found: ignore | |
| build-selfhost: | |
| name: build:selfhost — docker image + smoke | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| needs: test | |
| # Mirrors CLAUDE.md §11.1 item 10. Uses the Dockerfile + docker-compose | |
| # at the repo root and hits /_health via scripts/smoke-selfhost.sh. | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Smoke — build image, compose up, curl /_health, compose down | |
| run: ./scripts/smoke-selfhost.sh | |
| e2e: | |
| name: e2e — Playwright against wrangler dev | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| needs: test | |
| # Mirrors CLAUDE.md §11.1 item 8. Boots wrangler + the client-multi | |
| # Vite dev server via per-worker fixtures in packages/e2e and exercises | |
| # the HTTP surface + SPA mount. Uploads the HTML report on failure so | |
| # traces/screenshots are recoverable. | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: latest | |
| - name: Install dependencies | |
| run: bun install --frozen-lockfile | |
| - name: Install Playwright browsers (chromium + system deps) | |
| run: bunx playwright install --with-deps chromium | |
| working-directory: packages/e2e | |
| # Wrangler 4 reads `[assets] directory = "../../assets"` from | |
| # wrangler.toml; if the dir is missing (or empty, which it is on | |
| # this fresh runner) wrangler hangs on asset-manifest resolution | |
| # — silently, with no stderr — and every fixture setup times out. | |
| # The `test` job builds these before its own suite; `e2e` runs on | |
| # a separate runner with a clean workspace, so rebuild here. | |
| - name: client — Vite build (for assets/static/player.js) | |
| run: bun run --cwd packages/client build | |
| - name: client-multi — Vite build (for assets/multi/) | |
| run: bun run --cwd packages/client-multi build | |
| - name: Build curated assets/ dir | |
| run: ./scripts/build-assets.sh | |
| - name: Run Playwright suite | |
| run: bun run --cwd packages/e2e test | |
| env: | |
| CI: 'true' | |
| - name: Upload Playwright HTML report | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: playwright-report | |
| path: packages/e2e/playwright-report/ | |
| retention-days: 7 | |
| if-no-files-found: ignore | |
| - name: Upload trace + screenshots on failure | |
| if: failure() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: playwright-test-results | |
| path: packages/e2e/test-results/ | |
| retention-days: 7 | |
| if-no-files-found: ignore | |
| mutation-gate: | |
| name: mutation-gate — changed packages only | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| needs: test | |
| # Fast PR-gate mutation check. Runs Stryker only on packages whose | |
| # `src/` changed in the PR, so docs/test/config-only PRs skip it and | |
| # single-package PRs stay under ~2 minutes. The full matrix lives in | |
| # nightly.yml; see CLAUDE.md §5.3 + docs/MUTATION_REPORT.md for the | |
| # ratchet workflow. | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: latest | |
| - name: Install dependencies | |
| run: bun install --frozen-lockfile | |
| - name: Detect changed packages | |
| id: changed | |
| # Override GH Actions' default `bash -eo pipefail` because grep | |
| # exits non-zero when the pattern matches nothing, which is the | |
| # expected case for docs/test/config-only PRs. | |
| shell: bash {0} | |
| run: | | |
| # Compare the PR head against the merge-base with origin/main. | |
| # On a push to main the base still resolves (merge-base with self | |
| # is HEAD) — the diff is empty, so the Stryker step is skipped. | |
| git fetch origin main --depth=1 || true | |
| if git merge-base origin/main HEAD >/dev/null 2>&1; then | |
| BASE=$(git merge-base origin/main HEAD) | |
| else | |
| BASE=HEAD~1 | |
| fi | |
| changed=$(git diff --name-only "$BASE" HEAD \ | |
| | grep -oE '^packages/[^/]+/src/' \ | |
| | sort -u \ | |
| | sed 's|packages/||;s|/src/||' \ | |
| | tr '\n' ' ') | |
| echo "packages=$changed" >> "$GITHUB_OUTPUT" | |
| echo "Changed packages: ${changed:-<none>}" | |
| - name: Run Stryker on changed packages | |
| if: steps.changed.outputs.packages != '' | |
| run: | | |
| for pkg in ${{ steps.changed.outputs.packages }}; do | |
| if [ -f "packages/$pkg/stryker.conf.json" ]; then | |
| echo "::group::mutation test — $pkg" | |
| bun run --cwd "packages/$pkg" mutation | |
| echo "::endgroup::" | |
| else | |
| echo "skip: packages/$pkg has no stryker.conf.json" | |
| fi | |
| done | |
| - name: Upload mutation reports on failure | |
| if: failure() && steps.changed.outputs.packages != '' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: mutation-gate-reports | |
| path: packages/*/reports/mutation/ | |
| retention-days: 7 | |
| if-no-files-found: ignore |