From 0ec621cac206a7939c9c3750d7fef015259f9e57 Mon Sep 17 00:00:00 2001 From: dev-milos <271274416+dev-milos@users.noreply.github.com> Date: Wed, 22 Jul 2026 11:09:31 +0200 Subject: [PATCH] Add PR gate workflow (build, type-check, unit) First CI gate for the repo. Runs on every PR to master: npm ci -> build -> check -> test:unit. Scope is the fast tier only. Deliberately excluded: - test:browser: budgeted at 3600 s wall, and playwright-v2.config.ts reserves workers from scripts/testing-v2/ledger.mjs, which exists to share one 24-core dev box between concurrent agent sessions. On a single-tenant runner that machinery is inert and misleading. - test:e2e: needs Docker and real worktrees. Both need to be made runner-shaped before they belong in a PR gate. Verified from a clean detached worktree at origin/master (macOS, 24 core): npm ci 14s, build 12s, check 30s, test:unit 78s. That run also surfaced three pre-existing unit-gate failures (14 files / 56 tests), which is the reason this gate is worth having: 1. macOS TMPDIR symlink (6 files). os.tmpdir() is /var/folders/... but its realpath is /private/var/folders/... Tests such as tests2/integration/project-ui-api.test.ts:55 compare a server- canonicalized path against the raw one by strict equality. Linux has no such indirection, so these pass in CI and fail only on macOS. 2. Node below engines (7 files). engines.node is >=22.19.0; native .ts loading arrived in 22.18. On 22.17 the extension-host suites die with 'Unknown file extension ".ts"'. npm ci already warns EBADENGINE -- the warning is load-bearing, not cosmetic. This workflow pins 22.19.0. 3. A genuinely broken test (1 file). tests2/core/file-mentions- resolve.test.ts:698 calls execFileSync("mkfifo"), which this repo's own tier-1 spawn guard blocks. Introduced by #1030 and merged red because nothing ran it. (1) and (2) are laptop-specific and disappear on a Linux runner. (3) is real and will make this gate red on arrival. That is intended: it is fixed separately so this PR stays reviewable on its own, and the gate should stay non-required until it has been observed on a few PRs. --- .github/workflows/build-unit-gate.yml | 43 +++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 .github/workflows/build-unit-gate.yml diff --git a/.github/workflows/build-unit-gate.yml b/.github/workflows/build-unit-gate.yml new file mode 100644 index 000000000..8e5d4e788 --- /dev/null +++ b/.github/workflows/build-unit-gate.yml @@ -0,0 +1,43 @@ +name: Build & Unit Gate + +on: + pull_request: + branches: [master] + push: + branches: [master] + +permissions: + contents: read + +concurrency: + group: pr-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + verify: + name: Build, type-check, unit + runs-on: ubuntu-latest + timeout-minutes: 20 + steps: + - name: Checkout + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 + with: + persist-credentials: false + + - name: Set up Node + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + node-version: '22.19.0' + cache: npm + + - name: Install + run: npm ci + + - name: Build + run: npm run build + + - name: Type-check + run: npm run check + + - name: Unit gate + run: npm run test:unit