name: Backend Tests # Runs on backend and extension changes. Tests are co-located with the # code (src/backend/**/*.test.ts, extensions/**/*.test.ts), so test-only # changes match the same globs. puter.js SDK changes are covered by # puterjs-tests.yaml instead. on: pull_request: types: [opened, synchronize, reopened] paths: - 'src/backend/**' - 'extensions/**' - 'tools/**' - 'package.json' - 'package-lock.json' # The type-check job below reads these. - 'tsconfig.json' - 'tsconfig.build.json' - '.github/workflows/backend-tests.yaml' permissions: contents: read pull-requests: write jobs: # `tsconfig.build.json` builds with `noCheck: true`, so nothing else in CI # runs the type checker and a missing export compiles to `undefined`, # surfacing only when the call is finally reached at runtime. This diffs # against tools/typecheck-baseline.json and fails only on *new* errors. # # The consuming repo runs an equivalent gate, but only once someone bumps the # submodule pointer — too late to keep the error off this repo's default # branch. Hence a gate here, on this repo's own pull requests. # # Its own job rather than a step in `test`: that one runs a base/PR matrix for # coverage comparison, and the check only needs the PR ref, once. typecheck: runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 - name: Set up Node.js uses: actions/setup-node@v4 with: node-version: '24' cache: 'npm' - name: Install dependencies run: npm ci - name: Type check (new errors only) run: npm run typecheck test: runs-on: ubuntu-latest strategy: fail-fast: false matrix: include: - ref: ${{ github.base_ref }} artifact: base - ref: ${{ github.head_ref }} artifact: pr steps: - name: Checkout ${{ matrix.ref }} uses: actions/checkout@v4 with: ref: ${{ matrix.ref }} repository: ${{ github.event.pull_request.head.repo.full_name }} - name: Set up Node.js uses: actions/setup-node@v4 with: node-version: '24' cache: 'npm' - name: Install dependencies run: npm ci - name: Run backend tests with coverage run: npm run test:backend -- --coverage env: CI: 'true' - name: Upload coverage artifact if: always() uses: actions/upload-artifact@v4 with: name: backend-coverage-${{ matrix.artifact }} path: src/backend/coverage/ retention-days: 14 report-coverage: needs: test if: always() runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 - name: Download PR coverage uses: actions/download-artifact@v4 with: name: backend-coverage-pr path: src/backend/coverage - name: Download base coverage uses: actions/download-artifact@v4 with: name: backend-coverage-base path: coverage-base - name: Report coverage on PR uses: davelosert/vitest-coverage-report-action@v2 with: json-summary-path: src/backend/coverage/coverage-summary.json json-final-path: src/backend/coverage/coverage-final.json json-summary-compare-path: coverage-base/coverage-summary.json