1# The enforcement job.2#3# Deliberately separate from release.yml, which links a native webview and so4# needs GTK and WebKitGTK headers on Linux, a macOS runner for the .app, and5# the seam built first. This one judges correctness on every push and pull6# request, and it holds one rule above all others: a gate that did not judge7# may not say PASS. `go test` is run through tools/testgate, which fails the8# run if any test skipped; there are no optional prerequisites, because every9# input a required test reads is committed to this repository or generated by10# the job itself.11#12# It runs on all three platforms. The tests compare bytes for a living —13# generated artifacts against committed ones — so a platform that rewrote a14# line ending or built a path with the wrong separator is caught here rather15# than by a user. `/.gitattributes` is the other half of that: LF in every16# working tree, corpus files never transformed at all.1718name: CI1920on:21 push:22 branches:23 - main24 pull_request:2526permissions:27 contents: read2829concurrency:30 group: ci-${{ github.ref }}31 cancel-in-progress: true3233env:34 GOFLAGS: -buildvcs=false3536jobs:37 test:38 name: test (${{ matrix.os }})39 runs-on: ${{ matrix.os }}40 strategy:41 # One platform's failure is a finding about that platform, not a reason42 # to stop learning what the other two think.43 fail-fast: false44 matrix:45 os: [ubuntu-24.04, macos-15, windows-2022]46 steps:47 - uses: actions/checkout@v548 - uses: actions/setup-go@v549 with:50 go-version-file: go.mod51 - uses: actions/setup-node@v452 with:53 # Type stripping is on by default here, which is what lets the lanes54 # run their TypeScript tests with no build step.55 node-version: "24"56 cache: npm57 cache-dependency-path: package-lock.json5859 # The TypeScript lanes install at the repository root as npm workspaces.60 # `--ignore-scripts` because nothing here has a postinstall worth running.61 - name: Install the TypeScript lanes' dependencies62 run: npm ci --ignore-scripts6364 # A checkout that rewrote line endings would fail the byte comparisons65 # below with an unreadable diff. Say so here instead, in one line.66 - name: Confirm the working tree came through unmodified67 run: git diff --exit-code6869 - name: Vet70 run: go vet ./...7172 # Every Go test in the module, through the gate that refuses skips.73 # The race detector needs cgo and a C toolchain, so it runs where that74 # is free rather than nowhere.75 - name: Go tests76 run: go run ./tools/testgate ${{ matrix.os == 'ubuntu-24.04' && '-race' || '' }} ./...7778 # Each lane's own gate: boundary rules, tsc at its strictest, and the79 # lane's test suite.80 - name: Analysis lane81 run: npm run --silent lane8283 - name: Render lane84 run: npm run --silent seam-lane8586 # The guardrails: the lane import matrix, hostenv purity, network87 # confinement, semconv discipline.88 - name: Depcheck89 run: go run ./tools/depcheck9091 e2e:92 name: e2e (${{ matrix.os }})93 runs-on: ${{ matrix.os }}94 strategy:95 fail-fast: false96 matrix:97 os: [ubuntu-24.04]98 steps:99 - uses: actions/checkout@v5100 - uses: actions/setup-go@v5101 with:102 go-version-file: go.mod103 - uses: actions/setup-node@v4104 with:105 node-version: "24"106 cache: npm107 cache-dependency-path: package-lock.json108109 - name: Install the TypeScript lanes' dependencies110 run: npm ci --ignore-scripts111112 - name: Install a browser113 run: npx playwright install --with-deps chromium114115 # Builds the seam, packs the test registry from the committed corpus,116 # starts the real application over it and walks it in a real browser.117 # Every prerequisite is built right here, in this job: there is no118 # "not judged" outcome, only red and green.119 - name: End-to-end120 run: make test-e2e