Skip to content

chore(repo): untrack .claude/ harness artifacts #242

chore(repo): untrack .claude/ harness artifacts

chore(repo): untrack .claude/ harness artifacts #242

Workflow file for this run

name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
check:
# Matrix across Linux / macOS / Windows so cross-platform regressions
# (case-sensitivity, path separators, native ABI mismatches) surface
# daily instead of waiting for the release tag. The launch-readiness
# audit (2026-05-10) flagged that the keytar arch-mismatch class of
# bug was invisible to the prior ubuntu-only check job. `fail-fast:
# false` lets each OS finish so we see ALL the failures, not just
# the first.
name: Lint · Typecheck · Test (${{ matrix.os }})
runs-on: ${{ matrix.os }}
timeout-minutes: 25
strategy:
fail-fast: false
matrix:
os:
- ubuntu-latest
- macos-latest
- windows-latest
steps:
- uses: actions/checkout@v4
# pnpm version is read from root package.json `packageManager`
# field (single source of truth). Pinned to pnpm@9.15.9 — see
# package.json comment for the rationale.
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'pnpm'
# keytar's load-time dynamic-linker resolves libsecret-1.so.0 on
# Linux. The .deb installer declares this as a runtime dep
# (electron-builder.yml linux.deb.depends), but the GitHub-hosted
# ubuntu-latest CI runner does not pre-install it. Without this,
# `pnpm test` fails when loading apps/desktop/src/main/services/
# provider-factory.test.ts with "libsecret-1.so.0: cannot open
# shared object file". macOS and Windows both ship keychain APIs
# natively so keytar loads with no extra deps there.
- name: Install keytar Linux runtime (libsecret)
if: matrix.os == 'ubuntu-latest'
run: sudo apt-get update && sudo apt-get install -y libsecret-1-0
- name: Install dependencies
run: pnpm install --frozen-lockfile
# Build the workspace packages' dist outputs before typecheck.
# apps/desktop's tsconfig declares each package as a composite
# project reference, so its `tsc --noEmit` step expects the
# referenced project's `dist/index.d.ts` to exist on disk.
# Local dev gets these dist files implicitly (via prior builds);
# CI starts from a clean checkout with no dist (gitignored), so
# we materialize them explicitly. tsc --build resolves the
# reference graph and builds in dep order automatically.
- name: Build workspace packages (composite refs)
run: pnpm exec tsc --build packages/shared-types packages/role-schema packages/provider-router packages/telemetry-core packages/intelligence
- name: Lint
run: pnpm lint
- name: Typecheck
run: pnpm typecheck
- name: Test
run: pnpm test
e2e:
name: E2E smoke (Electron)
runs-on: ubuntu-latest
needs: check
timeout-minutes: 20
steps:
- uses: actions/checkout@v4
# pnpm version is read from root package.json `packageManager`
# field (single source of truth). Pinned to pnpm@9.15.9 — see
# package.json comment for the rationale.
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'pnpm'
# Electron needs a GTK/X11 stack plus libxkb + libasound at runtime
# even in headless mode; xvfb provides the display. ubuntu-latest
# ships most of these, but libasound2t64 + libgbm1 are sometimes
# missing on minimal runners — install explicitly to keep the
# job deterministic.
#
# `libsecret-1-0` is keytar's libsecret runtime dep on Linux. The
# `check` job above installs it for the same reason (see the
# Install keytar Linux runtime step there). The E2E job ALSO
# loads the main process which loads keytar — so it needs the
# same .so available, otherwise keytar's dlopen on import either
# throws or hangs and Electron never paints a window.
- name: Install Electron runtime libraries
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
xvfb \
libnss3 \
libatk1.0-0 \
libatk-bridge2.0-0 \
libcups2 \
libdrm2 \
libxkbcommon0 \
libxcomposite1 \
libxdamage1 \
libxfixes3 \
libxrandr2 \
libgbm1 \
libpango-1.0-0 \
libcairo2 \
libasound2t64 \
libgtk-3-0 \
libsecret-1-0
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build desktop (main + preload + renderer)
run: pnpm -F @team-x/desktop build
# `xvfb-run` wraps the Playwright invocation so Electron has a
# virtual display. `--auto-servernum` picks a free :N so parallel
# jobs on the same runner never collide on :99.
- name: Run Playwright E2E smoke
run: xvfb-run --auto-servernum pnpm -F @team-x/desktop test:e2e:run
# `test-results/` is where Playwright writes traces, screenshots, and
# videos per the `outputDir` in `apps/desktop/playwright.config.ts`.
# The HTML reporter is intentionally disabled in CI (we only run
# `list` + `github` reporters), so there is no `playwright-report/`
# directory to upload — but the trace zips under `test-results/`
# are what we actually need to diagnose a failure: open the trace
# in `npx playwright show-trace <zip>` to see exactly what the
# renderer rendered (or didn't) at the moment of timeout.
- name: Upload Playwright traces on failure
if: failure()
uses: actions/upload-artifact@v4
with:
name: playwright-traces
path: apps/desktop/test-results
retention-days: 7
if-no-files-found: ignore