diff --git a/.actrc b/.actrc deleted file mode 100644 index 69c54909..00000000 --- a/.actrc +++ /dev/null @@ -1,3 +0,0 @@ --P ubuntu-latest=catthehacker/ubuntu:act-latest --P ubuntu-slim=catthehacker/ubuntu:act-latest ---env npm_config_store_dir=/root/.local/share/pnpm/store diff --git a/.github/workflows/biome.yml b/.github/workflows/biome.yml index 3c23a47d..41a52470 100644 --- a/.github/workflows/biome.yml +++ b/.github/workflows/biome.yml @@ -1,6 +1,11 @@ name: Biome 'on': - workflow_call: null + workflow_call: + inputs: + since: + description: Base commit to compare against. Empty runs everything. + type: string + default: '' permissions: contents: read jobs: @@ -10,8 +15,16 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v6 + with: + fetch-depth: 0 - name: Setup workspace uses: ./.github/actions/setup - name: Lint & format (biome ci) + if: inputs.since == '' run: pnpm check:ci + - name: Lint & format changed files (biome ci) + if: inputs.since != '' + env: + SINCE: ${{ inputs.since }} + run: pnpm exec biome ci --changed --since="$SINCE" --no-errors-on-unmatched timeout-minutes: 15 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ad551df7..f82cda4f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,17 +13,46 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} jobs: + changes: + name: Changes + runs-on: ubuntu-latest + outputs: + since: ${{ steps.filter.outputs.everything != 'true' && github.event.pull_request.base.sha || '' }} + steps: + - uses: actions/checkout@v6 + - uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3 + id: filter + if: github.event_name == 'pull_request' + with: + token: '' + filters: | + everything: + - pnpm-lock.yaml + - biome.json + - 'tsconfig*.json' + - 'mcp-apps/tsconfig.json' + - 'vitest*.cts' + - '.github/**' + - package.json + timeout-minutes: 5 biome: + needs: changes uses: ./.github/workflows/biome.yml + with: + since: ${{ needs.changes.outputs.since }} typecheck: uses: ./.github/workflows/typecheck.yml test: + needs: changes uses: ./.github/workflows/test.yml + with: + since: ${{ needs.changes.outputs.since }} build: uses: ./.github/workflows/build.yml gate: name: CI Gate needs: + - changes - biome - typecheck - test @@ -42,6 +71,7 @@ jobs: report-failure: name: Open issue on main failure needs: + - changes - biome - typecheck - test diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index eef9e8c9..6a3cc59f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,6 +1,11 @@ name: Test 'on': - workflow_call: null + workflow_call: + inputs: + since: + description: Base commit to compare against. Empty runs everything. + type: string + default: '' permissions: contents: read jobs: @@ -10,10 +15,24 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v6 + with: + fetch-depth: 0 - name: Setup workspace uses: ./.github/actions/setup - name: Run integration tests + if: inputs.since == '' run: pnpm test:integration - name: Run unit tests with the coverage gate + if: inputs.since == '' run: pnpm test:coverage + - name: Run integration tests for changed files + if: inputs.since != '' + env: + SINCE: ${{ inputs.since }} + run: pnpm exec vitest run --config vitest.integration.config.cts --changed "$SINCE" + - name: Run unit tests for changed files + if: inputs.since != '' + env: + SINCE: ${{ inputs.since }} + run: pnpm exec vitest run --changed "$SINCE" timeout-minutes: 20 diff --git a/README.md b/README.md index 52be44cd..52f43f56 100644 --- a/README.md +++ b/README.md @@ -701,7 +701,7 @@ pnpm test && pnpm test:integration # Vitest unit + integration pnpm build # Build to build/ ``` -To run the CI gate locally in Docker before pushing, use [act](https://nektosact.com): `act workflow_dispatch -W .github/workflows/ci.yml`. The root `.actrc` picks the runner image and keeps the pnpm store outside the workspace. +To run the CI gate locally in Docker before pushing, use [act](https://nektosact.com): `act workflow_dispatch -W .github/workflows/ci.yml`. The machine `~/.actrc` selects the runner, architecture and shared caches. ## Resources diff --git a/biome.json b/biome.json index 7faf526b..d32c8a8c 100644 --- a/biome.json +++ b/biome.json @@ -1,6 +1,6 @@ { "$schema": "https://biomejs.dev/schemas/2.5.1/schema.json", - "vcs": { "enabled": true, "clientKind": "git", "useIgnoreFile": true }, + "vcs": { "enabled": true, "clientKind": "git", "useIgnoreFile": true, "defaultBranch": "main" }, "files": { "ignoreUnknown": true, "includes": ["**"] diff --git a/mcp-apps/tsconfig.json b/mcp-apps/tsconfig.json index 259c98f3..3208e88f 100644 --- a/mcp-apps/tsconfig.json +++ b/mcp-apps/tsconfig.json @@ -6,6 +6,8 @@ "moduleResolution": "Bundler", "jsx": "react-jsx", "noEmit": true, + "incremental": true, + "tsBuildInfoFile": "../node_modules/.cache/tsc/mcp-apps.tsbuildinfo", "verbatimModuleSyntax": true, "noUnusedLocals": true, "noUnusedParameters": true, diff --git a/package.json b/package.json index 8fbe1f1d..ccf2bc21 100644 --- a/package.json +++ b/package.json @@ -20,9 +20,9 @@ "skills": "node build/scripts/skills.js", "sync": "tsx src/scripts/devSync.ts", "diagnose": "node build/scripts/diagnostics.js", - "typecheck": "tsc --noEmit", + "typecheck": "tsc --noEmit --incremental --tsBuildInfoFile node_modules/.cache/tsc/src.tsbuildinfo", "typecheck:mcp-apps": "tsc -p mcp-apps/tsconfig.json --noEmit", - "check": "tsc --noEmit && tsc -p mcp-apps/tsconfig.json --noEmit && biome check \"{src,mcp-apps}/**/*.{ts,tsx,js,json,md,css,html}\"", + "check": "pnpm run typecheck && pnpm run typecheck:mcp-apps && biome check \"{src,mcp-apps}/**/*.{ts,tsx,js,json,md,css,html}\"", "check:ci": "biome ci .", "verify": "pnpm run check:ci && pnpm run typecheck && pnpm run typecheck:mcp-apps && pnpm run test && pnpm run build", "fix": "biome check --write --no-errors-on-unmatched --files-ignore-unknown=true \"{src,mcp-apps}/**/*.{ts,tsx,js,json,md,css,html}\"",