Skip to content

feat(todomvc-demo): add ?bug=1 reproducible bug for the connector case study #559

feat(todomvc-demo): add ?bug=1 reproducible bug for the connector case study

feat(todomvc-demo): add ?bug=1 reproducible bug for the connector case study #559

Workflow file for this run

name: CI
on:
pull_request:
branches: [main]
push:
branches: [main]
# Workflow-default permissions are minimal — read-only. Individual jobs
# that need more (none in this file at present) must declare their own
# `permissions:` block. The publish workflow lives in release.yml; this
# file is CI only. Hard rule recorded in CONTRIBUTING.md §"Workflow
# security hard rules": every workflow scopes permissions, and no
# workflow in this repo uses `pull_request_target` (the PostHog
# Shai-Hulud 2.0 vector, Nov 24 2025).
permissions:
contents: read
jobs:
ci:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa # v4
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: '24'
cache: pnpm
- run: pnpm install --frozen-lockfile
# Build first so cross-package type declarations (e.g. @cubenest/rrweb-core's
# dist/*.d.ts) exist before downstream packages typecheck against the
# workspace dependency's published `exports` types.
- run: pnpm build
- run: pnpm lint
- run: pnpm typecheck
# `pnpm test` is vitest-only across all packages — it never launches a
# browser, so the main pipeline stays green without Chrome. The browser
# E2E lives in the separate `e2e-wdio` job below.
- run: pnpm test
# Recipe verifier — the status-aware link check is a HARD gate: a
# PUBLISHED recipe that links to a draft/archived recipe (relatedRecipes
# or inline body link) 404s in prod, so it fails the build here. The
# hero images for every published recipe have now landed, so the
# STRICT_RECIPE_ASSETS gate is on: a published recipe missing its
# `/recipes/assets/<slug>.png` hard-fails here. `pnpm build` above has
# already produced @cubenest/docs-shared's dist/ that this imports.
- run: STRICT_RECIPE_ASSETS=1 node packages/docs-shared/scripts/verify-recipes.mjs
# Plugin/marketplace integrity: manifest shape, mcp-block parity vs the
# repo-root .mcp.json, and the bundled skill copy staying byte-identical
# to packages/peek-cli/skills/peek-skill.md. Fails the `ci` gate on drift.
- run: node packages/docs-shared/scripts/check-plugin.mjs
# @tracelane/wdio browser smoke (Task 2.17). Separate, non-blocking job so a
# Chrome/chromedriver hiccup can't fail the required `ci` gate. The smoke spec
# fails on purpose; the run passes when a < 25 MB .html report was written
# (asserted in e2e/wdio.conf.ts onComplete + e2e/run.mjs exit mapping).
e2e-wdio:
runs-on: ubuntu-latest
# Do not fail the overall workflow if the browser E2E is flaky/unavailable.
continue-on-error: true
# Hard cap so a hung WDIO worker (e.g., chromedriver missing) can't sit
# consuming a runner for 6 hours. WDIO 9 has no default connect-phase
# timeout; if Chrome can't start, the worker waits indefinitely. 15 min
# is generous for the single-spec smoke run that completes in ~30s when
# the runtime is healthy.
timeout-minutes: 15
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa # v4
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: '24'
cache: pnpm
# ubuntu-latest ships Chrome; pin it explicitly so the run is reproducible.
# `install-chromedriver: true` is REQUIRED — the action defaults to false.
# Capture both binary paths via `id:` + outputs and pipe them into WDIO via
# CHROME_PATH/CHROMEDRIVER_PATH (consumed by e2e/wdio.conf.ts).
#
# WHY this matters (May 29 2026 root cause): WDIO 9.27's startWebDriver
# calls setupPuppeteerBrowser + setupChromedriver from @wdio/utils, which
# ignore Chrome/chromedriver on PATH and instead download their own copies
# via @puppeteer/browsers into os.tmpdir(). On GH Actions Ubuntu runners
# that download hangs silently (driver-setup logs are at info level; conf
# ran at warn level). Every e2e-wdio run cancelled at the 15-min cap with
# zero output after "Execution of 1 workers started" — workflow conclusion
# = cancelled => red CI badge on a repo where every push-triggered job
# that mattered (the required `ci` gate + e2e-peek) was actually passing.
# Pointing WDIO at the binaries setup-chrome already installed bypasses
# the Puppeteer download entirely.
- uses: browser-actions/setup-chrome@19ae4b339ee18925ab85cf12c1041150ea4a44c8 # v1
id: setup-chrome
with:
chrome-version: stable
install-chromedriver: true
- run: pnpm install --frozen-lockfile
# The recorder bundle + workspace deps must be built before the E2E.
- run: pnpm build
- run: pnpm --filter @tracelane/wdio test:e2e
env:
CHROME_PATH: ${{ steps.setup-chrome.outputs.chrome-path }}
CHROMEDRIVER_PATH: ${{ steps.setup-chrome.outputs.chromedriver-path }}
# peek extension Playwright persistent-context smoke (Task 3.29). Separate,
# non-blocking job — a Playwright/chromium download flake or a Chromium
# extension-loading quirk can't fail the required `ci` gate. The smoke
# asserts the unpacked MV3 extension loads + the native-host stdio loop
# ingests into SQLite (see packages/peek-extension/e2e/smoke.spec.ts).
e2e-peek:
runs-on: ubuntu-latest
continue-on-error: true
# Same hard cap as e2e-wdio for the same reason: Playwright's persistent-
# context launches can hang on missing chromium binary downloads or MV3
# extension load failures. The spec completes in ~30s when healthy.
timeout-minutes: 15
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa # v4
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: '24'
cache: pnpm
- run: pnpm install --frozen-lockfile
# Build extension (writes .output/chrome-mv3) + peek-mcp (writes dist/index.js).
- run: pnpm build
# Install Playwright's bundled chromium (NOT chromium_headless_shell —
# the headless shell doesn't load MV3 extensions; the spec sets
# channel: 'chromium' to use the full build).
- run: pnpm --filter @peekdev/extension exec playwright install --with-deps chromium
- run: pnpm --filter @peekdev/extension test:e2e
# peek Windows runtime validation (2026-06-15 Windows-compat audit). Until
# now every CI job ran on ubuntu-latest, so the peek win32 code paths — the
# `\\.\pipe\peek-host` named-pipe bind, the better-sqlite3 Windows prebuild
# (.node dlopen), the backslash-path bin entry guard (pathToFileURL), and the
# %LOCALAPPDATA%/registry-target resolution — were exercised ONLY by unit
# tests that mock process.platform, never on a real Windows kernel. This job
# runs the peek-mcp + peek-cli unit suites on a real Windows runner so those
# branches are validated for real. Scoped to the two peek packages (and their
# workspace deps) to stay fast and avoid unrelated cross-package Windows noise.
#
# Not yet a required check — branch protection still requires only `ci` + `dco`
# (see CLAUDE.md). Promote `ci-windows` to a required context once it has a few
# green runs. continue-on-error is false so its status reflects reality.
ci-windows:
runs-on: windows-latest
# Hard cap: a hung named-pipe bind or a stuck better-sqlite3 install can't
# sit on a (pricier) Windows runner indefinitely. The unit suites finish in
# ~1 min when healthy.
timeout-minutes: 15
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
# No git credentials are needed after checkout (install/build/test only),
# so don't persist the token in .git/config — reduces token exposure in a
# job that runs repository-controlled code.
with:
persist-credentials: false
- uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa # v4
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
# Node 24 matches the `ci` job and is >= the better-sqlite3 prebuild
# floor (Node 22+); installing here proves the Windows prebuild loads.
node-version: '24'
cache: pnpm
- run: pnpm install --frozen-lockfile
# Build peek-mcp + peek-cli and their workspace deps: peek-cli's tests
# resolve `@peekdev/mcp/db` + `@peekdev/mcp/native-host` via the built
# dist exports, and peek-mcp's stdio smoke test spawns the built bin.
- run: pnpm --filter "@peekdev/mcp..." --filter "@peekdev/cli..." build
- run: pnpm --filter @peekdev/mcp --filter @peekdev/cli typecheck
# The actual point of the job: run on Windows so better-sqlite3's .node
# dlopen, the named-pipe socket-path/host-socket logic, and the
# pathToFileURL entry guard execute on the real platform.
- run: pnpm --filter @peekdev/mcp --filter @peekdev/cli test