mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-11 13:46:32 +03:00
* Add DeepSeek Harness as a supported skills provider npx impeccable install now detects ~/.dsh (or $DSH_HOME when it sits under home) and installs into ~/.dsh/skills, the user-level skill root DeepSeek Harness scans, with project-level .dsh/skills on the same layout as other providers. Aliases: dsh, deepseek, deepseek-harness. Engine: PROVIDER_DIRS / aliases / display / input order / global hint, $DSH_HOME-aware user skills dir, provider id resolution from the skill dir, pin harness dirs, bundle path normalization for hashing. Build: dsh transformer target emitting the frontmatter DeepSeek Harness reads (user-invocable, license, compatibility, metadata; unknown keys are ignored there) with no emitHooks (DSH hooks are in-process plugins, not on-disk manifests) and no agentFormat (no documented on-disk subagent format); placeholders (AGENTS.md config file, ask_user_question tool, / command prefix), provider block tags, universal README entry. Docs: HARNESSES.md row and frontmatter column, CLI-CONTRACT constants, README/DEVELOP/AGENTS provider lists. Validation: cargo test --workspace; node scripts/run-tests.mjs core (138 pass); bun run build (19 providers, dist/dsh artifact verified); engine smoke against a fake HOME with a local bundle: install --providers=dsh --scope=global, auto-detected install, and update all resolve the .dsh provider. Generated provider output intentionally omitted per repo policy; the sync workflow regenerates tracked .dsh/skills after merge. Prepared with AI assistance (DeepSeek Harness coding agent). * Address review: DSH_HOME-only detection, generated-output pathspecs - Detect DeepSeek Harness through the resolved $DSH_HOME (fallback ~/.dsh) instead of gating on a fixed ~/.dsh path, so a DSH_HOME-only setup is offered by a provider-less install; generalize the two env-relocated config-dir hints (OpenCode, DSH) into one shared probe. - Add .dsh to the sync workflow's GENERATED_PATHS and CI's generated drift check so the tracked .dsh/skills payload is committed and validated. - Cover both behaviors: new install_detection_tests (DSH_HOME-only, default ~/.dsh, refused outside-home override) and a CLI-CONTRACT note on the resolved detection path. Validation: cargo test --workspace; node scripts/run-tests.mjs core (138 pass); engine smoke: DSH_HOME-only fake HOME installs globally into the resolved skills dir. Prepared with AI assistance (DeepSeek Harness coding agent). * Fix DeepSeek Harness home paths on Windows Use native relative-path containment, cover case and drive boundaries, and verify relocated global install/update without changing project skills. Add DSH output coverage and correct the install documentation. AI assistance: Codex, under pbakaus maintainer direction. * Document the CLI limit on external DSH homes Clarify that outside-home manual copies are not detected or updated by the CLI. AI assistance: Codex, under pbakaus maintainer direction. --------- Co-authored-by: Paul Bakaus <paul.bakaus@gmail.com>
663 lines
23 KiB
YAML
663 lines
23 KiB
YAML
name: CI
|
|
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
pull_request:
|
|
branches: [main]
|
|
workflow_dispatch:
|
|
# Nightly full live-e2e matrix. The smoke groups already gate every PR; the
|
|
# full sweep is too slow for that, so it runs once a day against main.
|
|
schedule:
|
|
- cron: '0 7 * * *'
|
|
|
|
concurrency:
|
|
# Scheduled runs get their own group: the 07:00 UTC nightly and a push to
|
|
# main share github.ref, and cancel-in-progress would let them kill each
|
|
# other mid-run.
|
|
group: ${{ github.workflow }}-${{ github.event_name == 'schedule' && 'nightly' || github.event.pull_request.number || github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
changes:
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
core: ${{ steps.plan.outputs.core }}
|
|
rust: ${{ steps.plan.outputs.rust }}
|
|
detector: ${{ steps.plan.outputs.detector }}
|
|
live: ${{ steps.plan.outputs.live }}
|
|
framework: ${{ steps.plan.outputs.framework }}
|
|
cli_remote_e2e: ${{ steps.plan.outputs.cli_remote_e2e }}
|
|
live_e2e: ${{ steps.plan.outputs.live_e2e }}
|
|
live_e2e_accept_cleanup: ${{ steps.plan.outputs.live_e2e_accept_cleanup }}
|
|
skill_behavior: ${{ steps.plan.outputs.skill_behavior }}
|
|
live_svelte_adapter_deepseek: ${{ steps.plan.outputs.live_svelte_adapter_deepseek }}
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v7
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Setup Node
|
|
uses: actions/setup-node@v7
|
|
with:
|
|
node-version: 24
|
|
|
|
- name: Detect test plan
|
|
id: plan
|
|
env:
|
|
GITHUB_EVENT_BEFORE: ${{ github.event.before }}
|
|
run: node scripts/ci-test-plan.mjs
|
|
|
|
test-matrix:
|
|
name: test (Node ${{ matrix.node-version }})
|
|
runs-on: ubuntu-latest
|
|
needs: changes
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
node-version: [22.18.0, 24]
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v7
|
|
|
|
- name: Setup Node
|
|
uses: actions/setup-node@v7
|
|
with:
|
|
node-version: ${{ matrix.node-version }}
|
|
|
|
- name: Setup Bun
|
|
uses: oven-sh/setup-bun@v2
|
|
with:
|
|
bun-version: latest
|
|
|
|
- name: Install dependencies
|
|
run: bun install
|
|
|
|
- name: Run core tests
|
|
run: bun run test:core
|
|
|
|
- name: Install Puppeteer browser
|
|
if: needs.changes.outputs.detector == 'true'
|
|
run: bunx puppeteer browsers install chrome
|
|
|
|
- name: Run detector tests
|
|
if: needs.changes.outputs.detector == 'true'
|
|
run: bun run test:detector
|
|
|
|
- name: Run live unit tests
|
|
if: needs.changes.outputs.live == 'true'
|
|
run: bun run test:live
|
|
|
|
- name: Run framework fixture tests
|
|
if: needs.changes.outputs.framework == 'true'
|
|
run: bun run test:framework
|
|
|
|
- name: Build
|
|
run: bun run build
|
|
|
|
# `bun run build:extension` runs `cargo xtask bundle`: the rule core
|
|
# compiled to wasm plus the page JS in browser-bundle/.
|
|
- name: Install the pinned toolchain
|
|
if: needs.changes.outputs.detector == 'true'
|
|
run: rustup show && rustup target add wasm32-unknown-unknown
|
|
|
|
- uses: Swatinem/rust-cache@v2
|
|
if: needs.changes.outputs.detector == 'true'
|
|
|
|
- name: Install wasm-pack
|
|
if: needs.changes.outputs.detector == 'true'
|
|
run: cargo install wasm-pack --locked
|
|
|
|
- name: Build extension
|
|
if: needs.changes.outputs.detector == 'true'
|
|
run: bun run build:extension
|
|
|
|
- name: Lint Firefox extension (web-ext)
|
|
if: needs.changes.outputs.detector == 'true'
|
|
# Pinned for reproducible CI. Fails on AMO errors; innerHTML style
|
|
# warnings in the panel renderer are non-blocking and not promoted to
|
|
# errors here.
|
|
run: npx --yes web-ext@10 lint --source-dir dist/extension-firefox
|
|
|
|
# Only meaningful right after the bundle was rebuilt, so it carries the
|
|
# same condition as that step rather than running unconditionally and
|
|
# comparing a committed artifact against an untouched tree. Every input
|
|
# `cargo xtask bundle` reads is in the detector trigger
|
|
# (scripts/test-suites.mjs), so a change to the registry rows or to how
|
|
# they are serialized lands here. The in-page bundle beside it is
|
|
# deliberately not checked: its bytes carry a wasm module built by
|
|
# whatever wasm-pack and wasm-opt the runner installed, so diffing it
|
|
# would fail on toolchain drift rather than on a real change.
|
|
- name: Verify the tracked rule registry is current
|
|
if: needs.changes.outputs.detector == 'true'
|
|
run: git diff --exit-code -- crates/live/assets/antipatterns.json
|
|
|
|
- name: Verify generated tracked outputs
|
|
# What `bun run build` writes, which runs on every PR.
|
|
# extension/detector/ is gitignored (built by `cargo xtask bundle`);
|
|
# it stays listed so a stray tracked copy shows up here.
|
|
run: git diff --exit-code -- .agents .claude .cursor .dsh .gemini .github/skills plugin extension/detector
|
|
|
|
- name: Upload build artifacts
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: impeccable-build-node-${{ matrix.node-version }}
|
|
# Ship the packaged zips, not the unpacked Firefox staging tree.
|
|
path: |
|
|
dist/
|
|
!dist/extension-firefox/
|
|
retention-days: 7
|
|
|
|
# The Rust workspace: the engine binary, the rule core, and every crate
|
|
# behind them. Everything builds from source with no downloads.
|
|
rust:
|
|
runs-on: ubuntu-latest
|
|
needs: changes
|
|
if: needs.changes.outputs.rust == 'true'
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v7
|
|
|
|
# rust-toolchain.toml names the channel; `rustup show` installs it.
|
|
# Never override the toolchain here.
|
|
- name: Install the pinned toolchain
|
|
run: rustup show
|
|
|
|
- uses: Swatinem/rust-cache@v2
|
|
|
|
- name: Build
|
|
run: cargo build --workspace --all-targets
|
|
|
|
- name: Test
|
|
run: cargo test --workspace
|
|
|
|
# The engine ships a windows-x64 binary (release-engine.yml), so the
|
|
# workspace has to build and pass its own tests there. Tests that need a
|
|
# browser or the oracle skip when those are absent.
|
|
rust-windows:
|
|
runs-on: windows-latest
|
|
needs: changes
|
|
if: needs.changes.outputs.rust == 'true'
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v7
|
|
- name: Install the pinned toolchain
|
|
run: rustup show
|
|
- uses: Swatinem/rust-cache@v2
|
|
- run: cargo build --workspace --all-targets
|
|
- run: cargo test --workspace --no-fail-fast
|
|
|
|
launcher-windows:
|
|
runs-on: windows-latest
|
|
needs: changes
|
|
if: needs.changes.outputs.core == 'true'
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v7
|
|
- name: Setup Node
|
|
uses: actions/setup-node@v7
|
|
with:
|
|
node-version: 24
|
|
- name: Exercise Windows launcher downloads and verification
|
|
run: node --test tests/launcher-download.test.mjs
|
|
|
|
# Behavior gate: replays the tests/oracle/ goldens against a release build
|
|
# of the engine from THIS checkout (so a PR is judged on its own source,
|
|
# not on the last published binary). Without this job the oracle only ever
|
|
# runs on developer laptops: tests/oracle.test.mjs skips cleanly when no
|
|
# binary is present, so the default suite is silent about it on CI.
|
|
oracle:
|
|
runs-on: ubuntu-latest
|
|
needs: changes
|
|
if: needs.changes.outputs.oracle == 'true' || needs.changes.outputs.rust == 'true'
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v7
|
|
|
|
- name: Setup Node
|
|
uses: actions/setup-node@v7
|
|
with:
|
|
node-version: 24
|
|
|
|
- name: Setup Bun
|
|
uses: oven-sh/setup-bun@v2
|
|
with:
|
|
bun-version: latest
|
|
|
|
- name: Install dependencies
|
|
run: bun install
|
|
|
|
- name: Install the pinned toolchain
|
|
run: rustup show
|
|
|
|
- uses: Swatinem/rust-cache@v2
|
|
|
|
- name: Build the engine from source
|
|
run: cargo build --release -p impeccable
|
|
|
|
- name: Replay oracle goldens
|
|
env:
|
|
IMPECCABLE_BIN: ${{ github.workspace }}/target/release/impeccable
|
|
run: node tests/oracle/run.mjs
|
|
|
|
# Release-order guard (triage decision D4). Verifies that the engine release for
|
|
# the pinned ENGINE_VERSION is fully published — the five dist binaries + .sha256
|
|
# AND the five @impeccable/cli-<os>-<arch> npm platform packages — before a skill
|
|
# release/merge that depends on them. The launcher, npm shim, and
|
|
# `impeccable install` all dead-end without those assets.
|
|
#
|
|
# A hard gate since engine-v0.1.0 shipped: the assets for the pinned
|
|
# ENGINE_VERSION must exist before a skill/CLI release or a merge that bumps the
|
|
# pin, or the launcher, the npm shim and `impeccable install` dead-end.
|
|
# release.mjs hard-fails `release:skill`/`release:cli` on the same check.
|
|
engine-release-ready:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v7
|
|
|
|
- name: Setup Node
|
|
uses: actions/setup-node@v7
|
|
with:
|
|
node-version: 24
|
|
|
|
- name: Check engine release assets for pinned ENGINE_VERSION
|
|
id: check
|
|
run: node scripts/check-engine-release.mjs
|
|
|
|
- name: Annotate missing engine release
|
|
# Only when the check itself failed, so a checkout or setup failure keeps its own error.
|
|
if: failure() && steps.check.outcome == 'failure'
|
|
run: |
|
|
echo "::error title=Engine release not ready::The engine release for v$(cat ENGINE_VERSION) is not fully published (engine-v$(cat ENGINE_VERSION) release assets and/or the @impeccable/cli-<os>-<arch> npm platform packages). Publish the engine (bun run release:engine) and the platform packages (bun run release:platform-packages) before bumping ENGINE_VERSION on main or releasing the skill/CLI."
|
|
|
|
test:
|
|
runs-on: ubuntu-latest
|
|
needs: test-matrix
|
|
if: always()
|
|
steps:
|
|
- name: Verify Node test matrix
|
|
run: |
|
|
if [ "${{ needs.test-matrix.result }}" != "success" ]; then
|
|
echo "test-matrix result: ${{ needs.test-matrix.result }}"
|
|
exit 1
|
|
fi
|
|
echo "test matrix passed"
|
|
|
|
cli-remote-e2e:
|
|
runs-on: ubuntu-latest
|
|
needs: changes
|
|
if: needs.changes.outputs.cli_remote_e2e == 'true'
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v7
|
|
|
|
- name: Setup Node
|
|
uses: actions/setup-node@v7
|
|
with:
|
|
node-version: 24
|
|
|
|
- name: Setup Bun
|
|
uses: oven-sh/setup-bun@v2
|
|
with:
|
|
bun-version: latest
|
|
|
|
- name: Install dependencies
|
|
run: bun install
|
|
|
|
# The live verbs are the engine binary; build it from this checkout so the
|
|
# suite tests the branch, not the last published release.
|
|
- name: Install the pinned toolchain
|
|
run: rustup show
|
|
|
|
- uses: Swatinem/rust-cache@v2
|
|
|
|
- name: Build the engine
|
|
run: cargo build --release -p impeccable
|
|
|
|
- name: Run remote CLI E2E smoke
|
|
run: bun run test:cli-remote-e2e
|
|
|
|
live-e2e-smoke:
|
|
name: live-e2e smoke (${{ matrix.group }})
|
|
runs-on: ubuntu-latest
|
|
needs: changes
|
|
if: needs.changes.outputs.live_e2e == 'true' && github.event_name != 'workflow_dispatch' && github.event_name != 'schedule'
|
|
timeout-minutes: 15
|
|
strategy:
|
|
fail-fast: true
|
|
matrix:
|
|
include:
|
|
- group: platform
|
|
fixtures: astro-vite7,monorepo-nested-vite,nextjs-app-router,vite8-sveltekit
|
|
- group: svelte
|
|
fixtures: vite8-sveltekit-stateful
|
|
- group: react
|
|
fixtures: vite8-react-css-modules,vite8-react-insert,vite8-react-plain
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v7
|
|
|
|
- name: Setup Node
|
|
uses: actions/setup-node@v7
|
|
with:
|
|
node-version: 24
|
|
|
|
- name: Setup Bun
|
|
uses: oven-sh/setup-bun@v2
|
|
with:
|
|
bun-version: latest
|
|
|
|
- name: Cache fixture npm downloads
|
|
uses: actions/cache@v6
|
|
with:
|
|
path: ~/.npm
|
|
key: ${{ runner.os }}-fixture-npm-${{ hashFiles('tests/framework-fixtures/**/files/package.json') }}
|
|
restore-keys: |
|
|
${{ runner.os }}-fixture-npm-
|
|
|
|
- name: Cache Playwright Chromium
|
|
uses: actions/cache@v6
|
|
with:
|
|
path: ~/.cache/ms-playwright
|
|
key: ${{ runner.os }}-playwright-chromium-${{ hashFiles('package.json', 'bun.lock') }}
|
|
restore-keys: |
|
|
${{ runner.os }}-playwright-chromium-
|
|
|
|
- name: Install dependencies
|
|
run: bun install
|
|
|
|
- name: Install Playwright Chromium
|
|
run: npx playwright install chromium
|
|
|
|
# The live verbs are the engine binary; build it from this checkout so the
|
|
# suite tests the branch, not the last published release.
|
|
- name: Install the pinned toolchain
|
|
run: rustup show
|
|
|
|
- uses: Swatinem/rust-cache@v2
|
|
|
|
- name: Build the engine
|
|
run: cargo build --release -p impeccable
|
|
|
|
- name: Run live E2E tests
|
|
run: bun run test:live-e2e
|
|
env:
|
|
IMPECCABLE_E2E_ONLY: ${{ matrix.fixtures }}
|
|
IMPECCABLE_E2E_SCENARIOS: core
|
|
IMPECCABLE_E2E_TEST_TIMEOUT_MS: 180000
|
|
IMPECCABLE_E2E_INSTALL_TIMEOUT_MS: 120000
|
|
IMPECCABLE_E2E_DEV_READY_TIMEOUT_MS: 60000
|
|
IMPECCABLE_E2E_ARTIFACT_DIR: test-results/live-e2e/${{ matrix.group }}
|
|
|
|
- name: Upload live E2E failure artifacts
|
|
if: failure()
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: live-e2e-smoke-${{ matrix.group }}-artifacts
|
|
path: test-results/live-e2e
|
|
if-no-files-found: ignore
|
|
|
|
live-e2e-full:
|
|
name: live-e2e full (${{ matrix.group }})
|
|
runs-on: ubuntu-latest
|
|
needs: changes
|
|
if: needs.changes.outputs.live_e2e == 'true' && (github.event_name == 'workflow_dispatch' || github.event_name == 'schedule')
|
|
timeout-minutes: 25
|
|
strategy:
|
|
fail-fast: true
|
|
matrix:
|
|
include:
|
|
- group: platform
|
|
fixtures: astro-vite7,monorepo-nested-vite,nextjs-app-router
|
|
- group: svelte
|
|
fixtures: vite8-sveltekit,vite8-sveltekit-stateful
|
|
- group: react-a
|
|
fixtures: vite8-https,vite8-react-base-path,vite8-react-csp-meta,vite8-react-css-modules,vite8-react-emotion
|
|
- group: react-b
|
|
fixtures: vite8-react-insert,vite8-react-mapped-list,vite8-react-modal,vite8-react-plain
|
|
- group: stateful
|
|
fixtures: vite8-react-radix-dialog,vite8-react-router-spa,vite8-react-styled-components,vite8-react-tabs
|
|
- group: styling
|
|
fixtures: vite8-react-tailwindv3,vite8-react-tailwindv4,vite8-react-ts,vite8-react-tsx-repeated-aside,vite8-react-unocss,vite8-react-vanilla-extract
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v7
|
|
|
|
- name: Setup Node
|
|
uses: actions/setup-node@v7
|
|
with:
|
|
node-version: 24
|
|
|
|
- name: Setup Bun
|
|
uses: oven-sh/setup-bun@v2
|
|
with:
|
|
bun-version: latest
|
|
|
|
- name: Cache fixture npm downloads
|
|
uses: actions/cache@v6
|
|
with:
|
|
path: ~/.npm
|
|
key: ${{ runner.os }}-fixture-npm-${{ hashFiles('tests/framework-fixtures/**/files/package.json') }}
|
|
restore-keys: |
|
|
${{ runner.os }}-fixture-npm-
|
|
|
|
- name: Cache Playwright Chromium
|
|
uses: actions/cache@v6
|
|
with:
|
|
path: ~/.cache/ms-playwright
|
|
key: ${{ runner.os }}-playwright-chromium-${{ hashFiles('package.json', 'bun.lock') }}
|
|
restore-keys: |
|
|
${{ runner.os }}-playwright-chromium-
|
|
|
|
- name: Install dependencies
|
|
run: bun install
|
|
|
|
- name: Install Playwright Chromium
|
|
run: npx playwright install chromium
|
|
|
|
# The live verbs are the engine binary; build it from this checkout so the
|
|
# suite tests the branch, not the last published release.
|
|
- name: Install the pinned toolchain
|
|
run: rustup show
|
|
|
|
- uses: Swatinem/rust-cache@v2
|
|
|
|
- name: Build the engine
|
|
run: cargo build --release -p impeccable
|
|
|
|
- name: Run live E2E tests
|
|
run: bun run test:live-e2e
|
|
env:
|
|
IMPECCABLE_E2E_ONLY: ${{ matrix.fixtures }}
|
|
IMPECCABLE_E2E_TEST_TIMEOUT_MS: 300000
|
|
IMPECCABLE_E2E_INSTALL_TIMEOUT_MS: 180000
|
|
IMPECCABLE_E2E_DEV_READY_TIMEOUT_MS: 120000
|
|
IMPECCABLE_E2E_ARTIFACT_DIR: test-results/live-e2e/${{ matrix.group }}
|
|
|
|
- name: Upload live E2E failure artifacts
|
|
if: failure()
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: live-e2e-full-${{ matrix.group }}-artifacts
|
|
path: test-results/live-e2e
|
|
if-no-files-found: ignore
|
|
|
|
live-e2e-accept-cleanup:
|
|
runs-on: ubuntu-latest
|
|
needs: changes
|
|
if: needs.changes.outputs.live_e2e_accept_cleanup == 'true'
|
|
timeout-minutes: 15
|
|
env:
|
|
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}
|
|
steps:
|
|
- name: Skip without provider key
|
|
if: ${{ env.ANTHROPIC_API_KEY == '' && env.DEEPSEEK_API_KEY == '' }}
|
|
run: echo "Skipping provider-backed accept-cleanup regression because no provider API key is configured."
|
|
|
|
- name: Checkout repository
|
|
if: ${{ env.ANTHROPIC_API_KEY != '' || env.DEEPSEEK_API_KEY != '' }}
|
|
uses: actions/checkout@v7
|
|
|
|
- name: Setup Node
|
|
if: ${{ env.ANTHROPIC_API_KEY != '' || env.DEEPSEEK_API_KEY != '' }}
|
|
uses: actions/setup-node@v7
|
|
with:
|
|
node-version: 24
|
|
|
|
- name: Setup Bun
|
|
if: ${{ env.ANTHROPIC_API_KEY != '' || env.DEEPSEEK_API_KEY != '' }}
|
|
uses: oven-sh/setup-bun@v2
|
|
with:
|
|
bun-version: latest
|
|
|
|
- name: Cache fixture npm downloads
|
|
if: ${{ env.ANTHROPIC_API_KEY != '' || env.DEEPSEEK_API_KEY != '' }}
|
|
uses: actions/cache@v6
|
|
with:
|
|
path: ~/.npm
|
|
key: ${{ runner.os }}-fixture-npm-${{ hashFiles('tests/framework-fixtures/**/files/package.json') }}
|
|
restore-keys: |
|
|
${{ runner.os }}-fixture-npm-
|
|
|
|
- name: Cache Playwright Chromium
|
|
if: ${{ env.ANTHROPIC_API_KEY != '' || env.DEEPSEEK_API_KEY != '' }}
|
|
uses: actions/cache@v6
|
|
with:
|
|
path: ~/.cache/ms-playwright
|
|
key: ${{ runner.os }}-playwright-chromium-${{ hashFiles('package.json', 'bun.lock') }}
|
|
restore-keys: |
|
|
${{ runner.os }}-playwright-chromium-
|
|
|
|
- name: Install dependencies
|
|
if: ${{ env.ANTHROPIC_API_KEY != '' || env.DEEPSEEK_API_KEY != '' }}
|
|
run: bun install
|
|
|
|
- name: Install Playwright Chromium
|
|
if: ${{ env.ANTHROPIC_API_KEY != '' || env.DEEPSEEK_API_KEY != '' }}
|
|
run: npx playwright install chromium
|
|
|
|
# The live verbs are the engine binary; build it from this checkout so the
|
|
# suite tests the branch, not the last published release.
|
|
- name: Install the pinned toolchain
|
|
if: ${{ env.ANTHROPIC_API_KEY != '' || env.DEEPSEEK_API_KEY != '' }}
|
|
run: rustup show
|
|
|
|
- uses: Swatinem/rust-cache@v2
|
|
if: ${{ env.ANTHROPIC_API_KEY != '' || env.DEEPSEEK_API_KEY != '' }}
|
|
|
|
- name: Build the engine
|
|
if: ${{ env.ANTHROPIC_API_KEY != '' || env.DEEPSEEK_API_KEY != '' }}
|
|
run: cargo build --release -p impeccable
|
|
|
|
- name: Run accept cleanup regression
|
|
if: ${{ env.ANTHROPIC_API_KEY != '' || env.DEEPSEEK_API_KEY != '' }}
|
|
run: |
|
|
if [ -n "$DEEPSEEK_API_KEY" ]; then
|
|
export IMPECCABLE_E2E_LLM_PROVIDER=deepseek
|
|
else
|
|
export IMPECCABLE_E2E_LLM_PROVIDER=anthropic
|
|
fi
|
|
bun run test:live-e2e-accept-cleanup
|
|
|
|
live-svelte-adapter-deepseek:
|
|
runs-on: ubuntu-latest
|
|
needs: changes
|
|
if: needs.changes.outputs.live_svelte_adapter_deepseek == 'true'
|
|
timeout-minutes: 25
|
|
env:
|
|
DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}
|
|
steps:
|
|
- name: Skip without DeepSeek key
|
|
if: ${{ env.DEEPSEEK_API_KEY == '' }}
|
|
run: echo "Skipping Svelte adapter DeepSeek sweep because DEEPSEEK_API_KEY is not configured."
|
|
|
|
- name: Checkout repository
|
|
if: ${{ env.DEEPSEEK_API_KEY != '' }}
|
|
uses: actions/checkout@v7
|
|
|
|
- name: Setup Node
|
|
if: ${{ env.DEEPSEEK_API_KEY != '' }}
|
|
uses: actions/setup-node@v7
|
|
with:
|
|
node-version: 24
|
|
|
|
- name: Setup Bun
|
|
if: ${{ env.DEEPSEEK_API_KEY != '' }}
|
|
uses: oven-sh/setup-bun@v2
|
|
with:
|
|
bun-version: latest
|
|
|
|
- name: Cache fixture npm downloads
|
|
if: ${{ env.DEEPSEEK_API_KEY != '' }}
|
|
uses: actions/cache@v6
|
|
with:
|
|
path: ~/.npm
|
|
key: ${{ runner.os }}-fixture-npm-${{ hashFiles('tests/framework-fixtures/**/files/package.json') }}
|
|
restore-keys: |
|
|
${{ runner.os }}-fixture-npm-
|
|
|
|
- name: Cache Playwright Chromium
|
|
if: ${{ env.DEEPSEEK_API_KEY != '' }}
|
|
uses: actions/cache@v6
|
|
with:
|
|
path: ~/.cache/ms-playwright
|
|
key: ${{ runner.os }}-playwright-chromium-${{ hashFiles('package.json', 'bun.lock') }}
|
|
restore-keys: |
|
|
${{ runner.os }}-playwright-chromium-
|
|
|
|
- name: Install dependencies
|
|
if: ${{ env.DEEPSEEK_API_KEY != '' }}
|
|
run: bun install
|
|
|
|
- name: Install Playwright Chromium
|
|
if: ${{ env.DEEPSEEK_API_KEY != '' }}
|
|
run: npx playwright install chromium
|
|
|
|
# The live verbs are the engine binary; build it from this checkout so the
|
|
# suite tests the branch, not the last published release.
|
|
- name: Install the pinned toolchain
|
|
if: ${{ env.DEEPSEEK_API_KEY != '' }}
|
|
run: rustup show
|
|
|
|
- uses: Swatinem/rust-cache@v2
|
|
if: ${{ env.DEEPSEEK_API_KEY != '' }}
|
|
|
|
- name: Build the engine
|
|
if: ${{ env.DEEPSEEK_API_KEY != '' }}
|
|
run: cargo build --release -p impeccable
|
|
|
|
- name: Run Svelte adapter DeepSeek sweep
|
|
if: ${{ env.DEEPSEEK_API_KEY != '' }}
|
|
run: bun run test:live-svelte-adapter-deepseek
|
|
|
|
skill-behavior:
|
|
runs-on: ubuntu-latest
|
|
needs: changes
|
|
if: needs.changes.outputs.skill_behavior == 'true' && github.event_name != 'pull_request'
|
|
env:
|
|
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
|
GOOGLE_CLOUD_API_KEY: ${{ secrets.GOOGLE_CLOUD_API_KEY }}
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v7
|
|
|
|
- name: Setup Node
|
|
uses: actions/setup-node@v7
|
|
with:
|
|
node-version: 24
|
|
|
|
- name: Setup Bun
|
|
uses: oven-sh/setup-bun@v2
|
|
with:
|
|
bun-version: latest
|
|
|
|
- name: Install dependencies
|
|
run: bun install
|
|
|
|
- name: Run skill behavior tests
|
|
run: bun run test:skill-behavior
|