Merge pull request #390 from subsy/t3code/c30b6361 #949
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| env: | |
| BUN_VERSION: 1.3.6 | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| jobs: | |
| build: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Bun | |
| uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: ${{ env.BUN_VERSION }} | |
| - name: Clear TypeScript build cache | |
| run: | | |
| rm -rf node_modules/.cache | |
| rm -rf .tsbuildinfo | |
| - name: Install dependencies | |
| run: bun install | |
| - name: Type check | |
| run: bun run typecheck | |
| - name: Lint | |
| run: bun run lint | |
| - name: Build | |
| run: bun run build | |
| windows-smoke: | |
| runs-on: windows-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Bun | |
| uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: ${{ env.BUN_VERSION }} | |
| - name: Install dependencies | |
| run: bun install | |
| - name: Type check | |
| run: bun run typecheck | |
| - name: Build | |
| run: bun run build | |
| - name: Run Windows-focused agent tests | |
| run: bun test src/plugins/agents/base.test.ts tests/plugins/opencode-agent.test.ts | |
| test: | |
| runs-on: ubuntu-latest | |
| needs: build | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Bun | |
| uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: ${{ env.BUN_VERSION }} | |
| - name: Install dependencies | |
| run: bun install | |
| - name: Run tests with coverage | |
| run: | | |
| set -euo pipefail | |
| mkdir -p coverage-parts | |
| # Run tests in batches to avoid mock.module() conflicts between test files | |
| # Each batch outputs its own lcov file for later merging | |
| echo "=== Running tests/ (excluding commands/info.test.ts, commands/run-remote-only.test.ts and beads-rust-bv-tracker.test.ts) ===" | tee -a coverage-output.txt | |
| mapfile -t TEST_FILES < <(find tests -type f -name '*.test.ts' ! -path 'tests/commands/info.test.ts' ! -path 'tests/commands/run-remote-only.test.ts' ! -path 'tests/plugins/beads-rust-bv-tracker.test.ts' | sort) | |
| bun test "${TEST_FILES[@]}" --coverage --coverage-reporter=text --coverage-reporter=lcov 2>&1 | tee -a coverage-output.txt | |
| cp coverage/lcov.info coverage-parts/tests.lcov | |
| # Run beads-rust-bv-tracker test in isolation: it mocks node:child_process and | |
| # node:fs/promises via mock.module() which is process-wide in Bun and pollutes | |
| # other tests (json-tracker, gemini-agent detect, remote Config Push Feature) | |
| # when run in the same process. | |
| echo "=== Running tests/plugins/beads-rust-bv-tracker.test.ts (isolated) ===" | tee -a coverage-output.txt | |
| bun test tests/plugins/beads-rust-bv-tracker.test.ts --coverage --coverage-reporter=text --coverage-reporter=lcov 2>&1 | tee -a coverage-output.txt | |
| cp coverage/lcov.info coverage-parts/tests-beads-rust-bv.lcov | |
| echo "=== Running tests/commands/info.test.ts (isolated) ===" | tee -a coverage-output.txt | |
| bun test tests/commands/info.test.ts --coverage --coverage-reporter=text --coverage-reporter=lcov 2>&1 | tee -a coverage-output.txt | |
| cp coverage/lcov.info coverage-parts/tests-info.lcov | |
| # Run tests/commands/run-remote-only.test.ts in isolation: it mocks | |
| # @opentui/core, @opentui/react, ../../src/remote/index.js, and the | |
| # interruption module. Other tests (notably tests/engine/execution-engine.test.ts) | |
| # also mock.module() the agent/tracker registry, which pollutes our success-path | |
| # tests by replacing getAgentRegistry with a stub missing registerBuiltin. | |
| echo "=== Running tests/commands/run-remote-only.test.ts (isolated) ===" | tee -a coverage-output.txt | |
| bun test tests/commands/run-remote-only.test.ts --coverage --coverage-reporter=text --coverage-reporter=lcov 2>&1 | tee -a coverage-output.txt | |
| cp coverage/lcov.info coverage-parts/tests-run-remote-only.lcov | |
| echo "=== Running doctor.test.ts ===" | tee -a coverage-output.txt | |
| bun test src/commands/doctor.test.ts --coverage --coverage-reporter=text --coverage-reporter=lcov 2>&1 | tee -a coverage-output.txt | |
| cp coverage/lcov.info coverage-parts/doctor.lcov | |
| echo "=== Running info.test.ts ===" | tee -a coverage-output.txt | |
| bun test src/commands/info.test.ts --coverage --coverage-reporter=text --coverage-reporter=lcov 2>&1 | tee -a coverage-output.txt | |
| cp coverage/lcov.info coverage-parts/info.lcov | |
| echo "=== Running skills tests ===" | tee -a coverage-output.txt | |
| bun test src/commands/skills.test.ts src/commands/skills-install.test.ts --coverage --coverage-reporter=text --coverage-reporter=lcov 2>&1 | tee -a coverage-output.txt | |
| cp coverage/lcov.info coverage-parts/skills.lcov | |
| echo "=== Running run.test.ts ===" | tee -a coverage-output.txt | |
| bun test src/commands/run.test.ts --coverage --coverage-reporter=text --coverage-reporter=lcov 2>&1 | tee -a coverage-output.txt | |
| cp coverage/lcov.info coverage-parts/run.lcov | |
| echo "=== Running src/config/ ===" | tee -a coverage-output.txt | |
| bun test src/config/ --coverage --coverage-reporter=text --coverage-reporter=lcov 2>&1 | tee -a coverage-output.txt | |
| cp coverage/lcov.info coverage-parts/config.lcov | |
| echo "=== Running src/engine/ ===" | tee -a coverage-output.txt | |
| bun test src/engine/ --coverage --coverage-reporter=text --coverage-reporter=lcov 2>&1 | tee -a coverage-output.txt | |
| cp coverage/lcov.info coverage-parts/engine.lcov | |
| # Run beads-bv and beads-rust tests in isolation due to ES module mock conflicts | |
| # Both mock node:fs/promises which pollutes other tests when run together | |
| echo "=== Running beads-bv test (isolated) ===" | tee -a coverage-output.txt | |
| bun test src/plugins/trackers/builtin/beads-bv/index.test.ts --coverage --coverage-reporter=text --coverage-reporter=lcov 2>&1 | tee -a coverage-output.txt | |
| cp coverage/lcov.info coverage-parts/beads-bv.lcov | |
| echo "=== Running beads-rust test (isolated) ===" | tee -a coverage-output.txt | |
| bun test src/plugins/trackers/builtin/beads-rust/index.test.ts --coverage --coverage-reporter=text --coverage-reporter=lcov 2>&1 | tee -a coverage-output.txt | |
| cp coverage/lcov.info coverage-parts/beads-rust.lcov | |
| echo "=== Running beads test (isolated) ===" | tee -a coverage-output.txt | |
| bun test src/plugins/trackers/builtin/beads/index.test.ts --coverage --coverage-reporter=text --coverage-reporter=lcov 2>&1 | tee -a coverage-output.txt | |
| cp coverage/lcov.info coverage-parts/beads.lcov | |
| echo "=== Running src/plugins/ (excluding beads-bv, beads-rust, and linear) ===" | tee -a coverage-output.txt | |
| bun test src/plugins/agents/ src/plugins/trackers/builtin/beads.test.ts --coverage --coverage-reporter=text --coverage-reporter=lcov 2>&1 | tee -a coverage-output.txt || true | |
| cp coverage/lcov.info coverage-parts/plugins.lcov || true | |
| # Linear tracker tests: client.test.ts and index.test.ts both use mock.module() | |
| # (client mocks @linear/sdk, index mocks ./client.js) so they must run in separate processes. | |
| # body.test.ts is pure functions with no mocks and can batch with convert.test.ts. | |
| echo "=== Running jira tracker tests ===" | tee -a coverage-output.txt | |
| bun test src/plugins/trackers/builtin/jira/ --coverage --coverage-reporter=text --coverage-reporter=lcov 2>&1 | tee -a coverage-output.txt | |
| cp coverage/lcov.info coverage-parts/jira.lcov | |
| echo "=== Running linear body.test.ts + convert.test.ts ===" | tee -a coverage-output.txt | |
| bun test src/plugins/trackers/builtin/linear/body.test.ts src/commands/convert.test.ts --coverage --coverage-reporter=text --coverage-reporter=lcov 2>&1 | tee -a coverage-output.txt | |
| cp coverage/lcov.info coverage-parts/linear-body.lcov | |
| echo "=== Running linear client.test.ts (isolated) ===" | tee -a coverage-output.txt | |
| bun test src/plugins/trackers/builtin/linear/client.test.ts --coverage --coverage-reporter=text --coverage-reporter=lcov 2>&1 | tee -a coverage-output.txt | |
| cp coverage/lcov.info coverage-parts/linear-client.lcov | |
| echo "=== Running linear index.test.ts (isolated) ===" | tee -a coverage-output.txt | |
| bun test src/plugins/trackers/builtin/linear/index.test.ts --coverage --coverage-reporter=text --coverage-reporter=lcov 2>&1 | tee -a coverage-output.txt | |
| cp coverage/lcov.info coverage-parts/linear-index.lcov | |
| echo "=== Running src/session/ ===" | tee -a coverage-output.txt | |
| bun test src/session/ --coverage --coverage-reporter=text --coverage-reporter=lcov 2>&1 | tee -a coverage-output.txt | |
| cp coverage/lcov.info coverage-parts/session.lcov | |
| echo "=== Running src/sandbox/ ===" | tee -a coverage-output.txt | |
| bun test src/sandbox/ --coverage --coverage-reporter=text --coverage-reporter=lcov 2>&1 | tee -a coverage-output.txt | |
| cp coverage/lcov.info coverage-parts/sandbox.lcov | |
| # Run wizard.test.ts in isolation because it mocks skill-installer.js | |
| # which leaks into skill-installer.test.ts via bun's process-level mock.module() | |
| echo "=== Running wizard.test.ts (isolated) ===" | tee -a coverage-output.txt | |
| bun test src/setup/wizard.test.ts --coverage --coverage-reporter=text --coverage-reporter=lcov 2>&1 | tee -a coverage-output.txt | |
| cp coverage/lcov.info coverage-parts/wizard.lcov | |
| echo "=== Running src/setup/ (excluding wizard and spawn-mocked tests) ===" | tee -a coverage-output.txt | |
| bun test src/setup/skill-installer.test.ts src/setup/migration.test.ts src/setup/prompts.test.ts --coverage --coverage-reporter=text --coverage-reporter=lcov 2>&1 | tee -a coverage-output.txt | |
| cp coverage/lcov.info coverage-parts/setup.lcov | |
| # Run spawn-mocked tests isolated: they mock node:child_process which conflicts with migration.test.ts | |
| echo "=== Running skill-installer-spawn.test.ts (isolated) ===" | tee -a coverage-output.txt | |
| bun test src/setup/skill-installer-spawn.test.ts --coverage --coverage-reporter=text --coverage-reporter=lcov 2>&1 | tee -a coverage-output.txt | |
| cp coverage/lcov.info coverage-parts/skill-installer-spawn.lcov | |
| # Run migration-install test isolated: it mocks config/registry which conflicts with migration.test.ts | |
| echo "=== Running migration-install.test.ts (isolated) ===" | tee -a coverage-output.txt | |
| bun test src/setup/migration-install.test.ts --coverage --coverage-reporter=text --coverage-reporter=lcov 2>&1 | tee -a coverage-output.txt | |
| cp coverage/lcov.info coverage-parts/migration-install.lcov | |
| echo "=== Running src/templates/ ===" | tee -a coverage-output.txt | |
| bun test src/templates/ --coverage --coverage-reporter=text --coverage-reporter=lcov 2>&1 | tee -a coverage-output.txt | |
| cp coverage/lcov.info coverage-parts/templates.lcov | |
| echo "=== Running src/tui/ ===" | tee -a coverage-output.txt | |
| bun test src/tui/ --coverage --coverage-reporter=text --coverage-reporter=lcov 2>&1 | tee -a coverage-output.txt | |
| cp coverage/lcov.info coverage-parts/tui.lcov | |
| echo "=== Running src/prd/ ===" | tee -a coverage-output.txt | |
| bun test src/prd/ --coverage --coverage-reporter=text --coverage-reporter=lcov 2>&1 | tee -a coverage-output.txt | |
| cp coverage/lcov.info coverage-parts/prd.lcov | |
| echo "=== Running src/chat/ ===" | tee -a coverage-output.txt | |
| bun test src/chat/ --coverage --coverage-reporter=text --coverage-reporter=lcov 2>&1 | tee -a coverage-output.txt | |
| cp coverage/lcov.info coverage-parts/chat.lcov | |
| echo "=== Running src/parallel/ ===" | tee -a coverage-output.txt | |
| bun test src/parallel/ --coverage --coverage-reporter=text --coverage-reporter=lcov 2>&1 | tee -a coverage-output.txt | |
| cp coverage/lcov.info coverage-parts/parallel.lcov | |
| echo "=== All test batches completed ===" | tee -a coverage-output.txt | |
| ls -la coverage-parts/ | |
| - name: Check coverage threshold | |
| run: | | |
| # Keep bun's text output for quick batch-by-batch visibility, but enforce | |
| # the threshold using merged LCOV data across all batches. The merged metric | |
| # still uses an equal-weight per-file average so very large low-coverage UI | |
| # files do not drown out well-tested modules. | |
| echo "Coverage breakdown by batch:" | |
| echo " %-Funcs %-Lines" | |
| grep "^All files" coverage-output.txt | awk '{printf " %6s %6s\n", $4, $6}' | |
| echo "" | |
| bun testing/check-coverage.mjs coverage-parts 38 | |
| - name: Upload coverage to Codecov | |
| uses: codecov/codecov-action@v4 | |
| with: | |
| # Upload all batch coverage files - Codecov will merge them correctly | |
| files: ./coverage-parts/tests.lcov,./coverage-parts/tests-beads-rust-bv.lcov,./coverage-parts/tests-info.lcov,./coverage-parts/tests-run-remote-only.lcov,./coverage-parts/doctor.lcov,./coverage-parts/info.lcov,./coverage-parts/skills.lcov,./coverage-parts/run.lcov,./coverage-parts/config.lcov,./coverage-parts/engine.lcov,./coverage-parts/beads-bv.lcov,./coverage-parts/beads-rust.lcov,./coverage-parts/beads.lcov,./coverage-parts/plugins.lcov,./coverage-parts/jira.lcov,./coverage-parts/linear-body.lcov,./coverage-parts/linear-client.lcov,./coverage-parts/linear-index.lcov,./coverage-parts/session.lcov,./coverage-parts/sandbox.lcov,./coverage-parts/wizard.lcov,./coverage-parts/setup.lcov,./coverage-parts/skill-installer-spawn.lcov,./coverage-parts/migration-install.lcov,./coverage-parts/templates.lcov,./coverage-parts/tui.lcov,./coverage-parts/prd.lcov,./coverage-parts/chat.lcov,./coverage-parts/parallel.lcov | |
| fail_ci_if_error: false | |
| verbose: true | |
| env: | |
| CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} | |
| # Determine which paths changed | |
| changes: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| website: ${{ steps.filter.outputs.website }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dorny/paths-filter@v3 | |
| id: filter | |
| with: | |
| filters: | | |
| website: | |
| - 'website/**' | |
| website: | |
| needs: changes | |
| if: ${{ needs.changes.outputs.website == 'true' }} | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Bun | |
| uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: ${{ env.BUN_VERSION }} | |
| - name: Clear TypeScript build cache | |
| run: | | |
| cd website | |
| rm -rf node_modules/.cache | |
| rm -rf .tsbuildinfo | |
| - name: Install website dependencies | |
| run: cd website && bun install | |
| - name: Type check website | |
| run: cd website && bun run typecheck | |
| - name: Lint website | |
| run: cd website && bun run lint | |
| - name: Build website | |
| run: cd website && bun run build |