Skip to content

Update changelog and features #70

Update changelog and features

Update changelog and features #70

Workflow file for this run

name: CI
# Merge gate for three.ws. Real money rides on this code, so every PR and every
# push to main must clear the checks below before it can land. Jobs run in
# parallel; the slowest (unit tests) gates the rest.
on:
pull_request:
push:
branches: [main]
# A newer push to the same branch/PR cancels the in-flight run — no point
# spending CI minutes on a commit that's already superseded.
concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 24
cache: npm
- run: npm ci
# eslint exits non-zero on any error. Pre-existing warnings are allowed
# for now; the bar is "no new errors". Tighten with --max-warnings once
# the warning backlog is burned down.
- run: npx eslint .
test:
name: Unit tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 24
cache: npm
- run: npm ci
- run: npx vitest run
guards:
name: Source guards
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 24
cache: npm
- run: npm ci
# Fail if `npx vercel build` ever clobbered an api/*.js source file with
# an esbuild bundle (a documented footgun in this repo).
- run: node scripts/check-api-not-bundled.mjs
# Every JS-rendered <img> must declare loading= so off-fold feed/grid
# images defer their fetch+decode. Keeps scroll perf from regressing as
# new components ship. Bulk-fix: node scripts/codemod-lazy-images.mjs
- run: npm run check:images
# Regenerates and validates the public changelog/page index; the script
# fails the build on a malformed changelog entry. Run as a validation
# gate only — the generated changelog.json is not byte-deterministic, so
# a committed-artifact diff check would be flaky and is intentionally
# omitted until the generator emits stable output.
- run: npm run build:pages
typecheck:
name: Typecheck
runs-on: ubuntu-latest
# `npm run typecheck` (tsc over jsconfig.json) is clean as of 2026-06-21, so
# this is now a hard merge gate: a new type error blocks the PR. The JSDoc
# backlog it used to wait on has been burned down — keep it clean by fixing
# the types, not by restoring continue-on-error.
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 24
cache: npm
- run: npm ci
- run: npm run typecheck
pages:
name: Page health
runs-on: ubuntu-latest
# scripts/test-pages.mjs spawns its own vite server and drives Chromium over
# every public route, failing on thrown errors, real console errors, dead
# requests, or broken hero images before they ship (npm run test:pages).
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 24
cache: npm
- run: npm ci
- name: Cache Playwright browsers
uses: actions/cache@v4
with:
path: ~/.cache/ms-playwright
key: playwright-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
restore-keys: playwright-${{ runner.os }}-
- run: npx playwright install --with-deps chromium
- run: npm run test:pages
e2e:
name: E2E (Playwright)
runs-on: ubuntu-latest
# The browser-driven specs (playwright.config.js boots `npm run dev` as its
# webServer). retries:1 in the config absorbs a single transient blip; a
# spec that fails twice is a real regression and blocks the PR.
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 24
cache: npm
- run: npm ci
- name: Cache Playwright browsers
uses: actions/cache@v4
with:
path: ~/.cache/ms-playwright
key: playwright-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
restore-keys: playwright-${{ runner.os }}-
- run: npx playwright install --with-deps chromium
- run: npx playwright test