Let users choose new vs. same chat when switching to plan mode #6958
Workflow file for this run
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 | |
| on: | |
| push: | |
| branches: | |
| - main | |
| pull_request: | |
| types: [opened, synchronize, reopened, closed] | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| defaults: | |
| run: | |
| shell: bash | |
| jobs: | |
| check-changes: | |
| # Skip closed PR events (we only listen to 'closed' to trigger cancellation of in-progress runs) | |
| if: github.event.action != 'closed' | |
| runs-on: ubuntu-latest | |
| outputs: | |
| should_run_tests: ${{ steps.check.outputs.should_run_tests }} | |
| should_run_schema_diff_tests: ${{ steps.check.outputs.should_run_schema_diff_tests }} | |
| should_run_schema_classifier_tests: ${{ steps.check.outputs.should_run_schema_classifier_tests }} | |
| build_os: ${{ steps.matrix.outputs.build_os }} | |
| e2e_os: ${{ steps.matrix.outputs.e2e_os }} | |
| e2e_shard: ${{ steps.matrix.outputs.e2e_shard }} | |
| e2e_shard_total: ${{ steps.matrix.outputs.e2e_shard_total }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v5 | |
| with: | |
| repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }} | |
| ref: ${{ github.event.pull_request.head.ref || '' }} | |
| fetch-depth: 0 | |
| - name: Check changed files | |
| id: check | |
| run: | | |
| if [ "${{ github.event_name }}" = "pull_request" ]; then | |
| BASE_SHA="${{ github.event.pull_request.base.sha }}" | |
| HEAD_SHA="${{ github.event.pull_request.head.sha }}" | |
| else | |
| # For push events, compare with parent commit | |
| BASE_SHA="${{ github.event.before }}" | |
| HEAD_SHA="${{ github.sha }}" | |
| fi | |
| # Get list of changed files | |
| CHANGED_FILES=$(git diff --name-only "$BASE_SHA" "$HEAD_SHA" 2>/dev/null || echo "") | |
| if [ -z "$CHANGED_FILES" ]; then | |
| echo "should_run_tests=true" >> $GITHUB_OUTPUT | |
| echo "should_run_schema_diff_tests=false" >> $GITHUB_OUTPUT | |
| echo "should_run_schema_classifier_tests=false" >> $GITHUB_OUTPUT | |
| echo "Running tests: could not determine changed files" | |
| echo "Skipping ts-pg-schema-diff tests: could not determine changed files" | |
| echo "Skipping pg-schema-classifier tests: could not determine changed files" | |
| exit 0 | |
| fi | |
| echo "Changed files:" | |
| echo "$CHANGED_FILES" | |
| if echo "$CHANGED_FILES" | grep -q "^packages/ts-pg-schema-diff/"; then | |
| echo "should_run_schema_diff_tests=true" >> $GITHUB_OUTPUT | |
| echo "Running ts-pg-schema-diff tests: package files changed" | |
| else | |
| echo "should_run_schema_diff_tests=false" >> $GITHUB_OUTPUT | |
| echo "Skipping ts-pg-schema-diff tests: no package files changed" | |
| fi | |
| if echo "$CHANGED_FILES" | grep -q "^packages/pg-schema-classifier/"; then | |
| echo "should_run_schema_classifier_tests=true" >> $GITHUB_OUTPUT | |
| echo "Running pg-schema-classifier tests: package files changed" | |
| else | |
| echo "should_run_schema_classifier_tests=false" >> $GITHUB_OUTPUT | |
| echo "Skipping pg-schema-classifier tests: no package files changed" | |
| fi | |
| if [ "${{ github.event_name }}" = "push" ] && [ "${{ github.ref }}" = "refs/heads/main" ]; then | |
| # Always run app tests on pushes to main. | |
| echo "should_run_tests=true" >> $GITHUB_OUTPUT | |
| echo "Running tests: push to main branch" | |
| exit 0 | |
| fi | |
| # Check if all changed files are in config-only directories (.claude, rules) | |
| NON_CONFIG_FILES=$(echo "$CHANGED_FILES" | grep -v "^\.claude/" | grep -v "^rules/" || true) | |
| if [ -z "$NON_CONFIG_FILES" ]; then | |
| echo "should_run_tests=false" >> $GITHUB_OUTPUT | |
| echo "Skipping tests: all changed files are in .claude/ or rules/" | |
| else | |
| echo "should_run_tests=true" >> $GITHUB_OUTPUT | |
| echo "Running tests: found files outside .claude/ and rules/:" | |
| echo "$NON_CONFIG_FILES" | |
| fi | |
| - name: Detect privileged author | |
| id: author-check | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| AUTHOR="" | |
| if [ "${{ github.event_name }}" = "pull_request" ]; then | |
| AUTHOR="${{ github.event.pull_request.user.login }}" | |
| fi | |
| echo "Author: $AUTHOR" | |
| # Lowercase before matching so a login like "RyanGroch" matches the | |
| # same lowercased allowlist used by the AI-review workflows. | |
| AUTHOR_LC="${AUTHOR,,}" | |
| case "$AUTHOR_LC" in | |
| wwwillchen|keppo-bot|keppo-bot\[bot\]|dyad-assistant|azizmejri1|ryangroch) | |
| echo "is_privileged=true" >> $GITHUB_OUTPUT | |
| ;; | |
| *) | |
| echo "is_privileged=false" >> $GITHUB_OUTPUT | |
| ;; | |
| esac | |
| # Sets the dynamic matrix for the build and e2e-tests jobs based on the PR author. | |
| # The "image" field is a JSON-encoded array string so that fromJSON() in runs-on | |
| # can produce the correct label(s) for both GitHub-hosted and self-hosted runners. | |
| # | |
| # Privileged authors (wwwillchen, keppo-bot/keppo-bot[bot], dyad-assistant, azizmejri1, ryangroch): | |
| # - Self-hosted macOS ARM64 runners, no Windows, 4 shards. | |
| # | |
| # build (macOS self-hosted) ──> e2e-tests (macOS self-hosted, shards 1-4) ──> merge-reports | |
| # | |
| # All other authors: | |
| # - GitHub-hosted runners for macOS + Windows, 4 shards each. | |
| # | |
| # build (macOS) ──┐ | |
| # build (Windows) ┼──> e2e-tests (macOS shards 1-4) ──┐ | |
| # │ e2e-tests (Windows shards 1-4) ──┼──> merge-reports | |
| # └──────────────────────────────────────┘ | |
| - name: Set CI matrix | |
| id: matrix | |
| run: | | |
| if [ "${{ steps.author-check.outputs.is_privileged }}" = "true" ]; then | |
| echo 'build_os=[{"name":"macos","image":"[\"self-hosted\",\"macOS\",\"ARM64\"]"}]' >> $GITHUB_OUTPUT | |
| echo 'e2e_os=[{"name":"macos","image":"[\"self-hosted\",\"macOS\",\"ARM64\"]"}]' >> $GITHUB_OUTPUT | |
| echo 'e2e_shard=[1,2,3,4]' >> $GITHUB_OUTPUT | |
| echo 'e2e_shard_total=[4]' >> $GITHUB_OUTPUT | |
| else | |
| echo 'build_os=[{"name":"windows","image":"[\"windows-latest\"]"},{"name":"macos","image":"[\"macos-latest\"]"}]' >> $GITHUB_OUTPUT | |
| echo 'e2e_os=[{"name":"windows","image":"[\"windows-latest\"]"},{"name":"macos","image":"[\"macos-latest\"]"}]' >> $GITHUB_OUTPUT | |
| echo 'e2e_shard=[1,2,3,4]' >> $GITHUB_OUTPUT | |
| echo 'e2e_shard_total=[4]' >> $GITHUB_OUTPUT | |
| fi | |
| ts-pg-schema-diff-tests: | |
| needs: [check-changes] | |
| if: needs.check-changes.outputs.should_run_schema_diff_tests == 'true' | |
| runs-on: ubuntu-latest | |
| services: | |
| postgres: | |
| image: postgres:16 | |
| env: | |
| POSTGRES_PASSWORD: postgres | |
| ports: | |
| - 5432:5432 | |
| options: >- | |
| --health-cmd "pg_isready -U postgres" | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v5 | |
| with: | |
| repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }} | |
| ref: ${{ github.event.pull_request.head.ref || '' }} | |
| - name: Initialize environment | |
| uses: actions/setup-node@v5 | |
| with: | |
| node-version: v24.13.1 | |
| cache: npm | |
| cache-dependency-path: package-lock.json | |
| - name: Install npm 11.8.0 | |
| run: npm install -g npm@11.8.0 | |
| - name: Install PostgreSQL | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y postgresql-client | |
| pg_dump --version | |
| - name: Install node modules | |
| run: bash scripts/npm-ci-retry.sh | |
| env: | |
| # Required for @vscode/ripgrep to download binaries without hitting GitHub API rate limits | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Type-check ts-pg-schema-diff | |
| run: npm --prefix packages/ts-pg-schema-diff run typecheck | |
| - name: Unit tests | |
| run: npm --prefix packages/ts-pg-schema-diff test | |
| - name: Integration tests | |
| run: npm --prefix packages/ts-pg-schema-diff run test:integration | |
| env: | |
| PG_SCHEMA_DIFF_TEST_DATABASE_URL: postgresql://postgres:postgres@localhost:5432/postgres | |
| pg-schema-classifier-tests: | |
| needs: [check-changes] | |
| if: needs.check-changes.outputs.should_run_schema_classifier_tests == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v5 | |
| with: | |
| repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }} | |
| ref: ${{ github.event.pull_request.head.ref || '' }} | |
| - name: Initialize environment | |
| uses: actions/setup-node@v5 | |
| with: | |
| node-version: v24.13.1 | |
| cache: npm | |
| cache-dependency-path: package-lock.json | |
| - name: Install npm 11.8.0 | |
| run: npm install -g npm@11.8.0 | |
| - name: Install node modules | |
| run: bash scripts/npm-ci-retry.sh | |
| env: | |
| # Required for @vscode/ripgrep to download binaries without hitting GitHub API rate limits | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Type-check pg-schema-classifier | |
| run: npm --prefix packages/pg-schema-classifier run typecheck | |
| - name: Unit tests | |
| run: npm --prefix packages/pg-schema-classifier test | |
| build: | |
| needs: [check-changes] | |
| if: needs.check-changes.outputs.should_run_tests == 'true' | |
| # Why Mac and Windows? | |
| # I can't run electron playwright on ubuntu-latest and | |
| # Linux support for Dyad is experimental so not as important | |
| # as Mac + Windows | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: ${{ fromJSON(needs.check-changes.outputs.build_os) }} | |
| runs-on: ${{ fromJSON(matrix.os.image) }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v5 | |
| with: | |
| repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }} | |
| ref: ${{ github.event.pull_request.head.ref || '' }} | |
| - name: Initialize environment | |
| uses: actions/setup-node@v5 | |
| with: | |
| node-version: v24.13.1 | |
| cache: npm | |
| cache-dependency-path: package-lock.json | |
| - name: Install npm 11.8.0 | |
| run: npm install -g npm@11.8.0 | |
| - name: Install node modules | |
| run: bash scripts/npm-ci-retry.sh | |
| env: | |
| # Required for @vscode/ripgrep to download binaries without hitting GitHub API rate limits | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Presubmit check (e.g. lint, format) | |
| # do not run this on Windows (it fails and not necessary) | |
| if: contains(matrix.os.name, 'macos') | |
| run: npm run presubmit | |
| - name: Type-checking | |
| # do not run this on windows (it's redundant) | |
| if: contains(matrix.os.name, 'macos') | |
| run: npm run ts | |
| - name: Unit tests | |
| # do not run this on windows (it's redundant) | |
| if: contains(matrix.os.name, 'macos') | |
| run: npm run test | |
| - name: Build | |
| env: | |
| NODE_OPTIONS: "--max-old-space-size=4096" | |
| run: npm run pre:e2e | |
| - name: Prep test server | |
| run: cd testing/fake-llm-server && npm install && npm run build && cd - | |
| # macOS: Archive app bundle with tar to preserve metadata (code signatures, extended attributes) | |
| # This is necessary because GitHub artifact upload/download loses these attributes | |
| - name: Archive macOS app bundle | |
| if: contains(matrix.os.name, 'macos') | |
| run: tar -cvf out-macos.tar out/ | |
| - name: Upload build artifacts (macOS) | |
| if: contains(matrix.os.name, 'macos') | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: build-${{ matrix.os.name }} | |
| path: | | |
| out-macos.tar | |
| scaffold/ | |
| testing/fake-llm-server/ | |
| retention-days: 1 | |
| - name: Upload build artifacts (Windows) | |
| if: contains(matrix.os.name, 'windows') | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: build-${{ matrix.os.name }} | |
| path: | | |
| out/ | |
| scaffold/ | |
| testing/fake-llm-server/ | |
| retention-days: 1 | |
| - name: Cleanup (self-hosted macOS) | |
| if: always() && contains(matrix.os.image, 'self-hosted') | |
| run: bash scripts/ci-cleanup-macos.sh | |
| e2e-tests: | |
| needs: [check-changes, build] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: ${{ fromJSON(needs.check-changes.outputs.e2e_os) }} | |
| shard: ${{ fromJSON(needs.check-changes.outputs.e2e_shard) }} | |
| shardTotal: ${{ fromJSON(needs.check-changes.outputs.e2e_shard_total) }} | |
| runs-on: ${{ fromJSON(matrix.os.image) }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v5 | |
| with: | |
| repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }} | |
| ref: ${{ github.event.pull_request.head.ref || '' }} | |
| - name: Initialize environment | |
| uses: actions/setup-node@v5 | |
| with: | |
| node-version: v24.13.1 | |
| cache: npm | |
| cache-dependency-path: package-lock.json | |
| - name: Install npm 11.8.0 | |
| run: npm install -g npm@11.8.0 | |
| - name: Install node modules | |
| run: bash scripts/npm-ci-retry.sh | |
| env: | |
| # Required for @vscode/ripgrep to download binaries without hitting GitHub API rate limits | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0 | |
| with: | |
| version: 10.33.2 | |
| - name: Clone nextjs-template | |
| run: git clone --depth 1 https://github.com/dyad-sh/nextjs-template.git nextjs-template | |
| - name: Get pnpm store directory | |
| id: pnpm-cache | |
| shell: bash | |
| run: | | |
| echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT | |
| - name: Setup pnpm cache | |
| uses: actions/cache@v5 | |
| with: | |
| path: ${{ steps.pnpm-cache.outputs.STORE_PATH }} | |
| key: ${{ matrix.os.name }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} | |
| restore-keys: | | |
| ${{ matrix.os.name }}-pnpm-store- | |
| # Not strictly needed but makes the e2e tests faster (and less flaky) | |
| - name: Install scaffold dependencies | |
| run: cd scaffold && pnpm install | |
| - name: Install nextjs-template dependencies | |
| run: cd nextjs-template && pnpm install | |
| - name: Download build artifacts | |
| uses: actions/download-artifact@v7 | |
| with: | |
| name: build-${{ matrix.os.name }} | |
| # macOS: Extract tar archive to restore app bundle with preserved metadata | |
| - name: Extract macOS app bundle | |
| if: contains(matrix.os.name, 'macos') | |
| run: tar -xvf out-macos.tar | |
| - name: Install Chromium browser for Playwright | |
| run: npx playwright install chromium --with-deps | |
| - name: E2E tests (Shard ${{ matrix.shard }}/${{ matrix.shardTotal }}) | |
| env: | |
| FLAKINESS_ACCESS_TOKEN: ${{ secrets.FLAKINESS_ACCESS_TOKEN }} | |
| # Self-hosted macOS runners use fewer retries (1) vs GitHub-hosted CI (2) | |
| PLAYWRIGHT_RETRIES: ${{ contains(matrix.os.image, 'self-hosted') && '1' || '2' }} | |
| # You can add debug logging to make it easier to see what's failing | |
| # by adding "DEBUG=pw:browser" in front. | |
| # Use blob reporter for sharding and merge capabilities | |
| run: DEBUG=pw:browser npx playwright test --shard=${{ matrix.shard }}/${{ matrix.shardTotal }} | |
| - name: Record shard metadata | |
| if: ${{ !cancelled() }} | |
| run: | | |
| mkdir -p blob-report | |
| cat <<EOF > "blob-report/_playwright-shard-metadata-${{ matrix.os.name }}-shard-${{ matrix.shard }}-of-${{ matrix.shardTotal }}.json" | |
| { | |
| "os": "${{ matrix.os.name }}", | |
| "shard": ${{ matrix.shard }}, | |
| "total": ${{ matrix.shardTotal }} | |
| } | |
| EOF | |
| - name: Upload shard results | |
| uses: actions/upload-artifact@v6 | |
| if: ${{ !cancelled() }} | |
| with: | |
| name: blob-report-${{ matrix.os.name }}-shard-${{ matrix.shard }} | |
| path: blob-report | |
| retention-days: 1 | |
| - name: Upload flakiness report (for fork PRs) | |
| uses: actions/upload-artifact@v6 | |
| if: ${{ !cancelled() }} | |
| with: | |
| name: flakiness-report-${{ matrix.os.name }}-shard-${{ matrix.shard }} | |
| path: flakiness-report | |
| retention-days: 1 | |
| - name: Cleanup (self-hosted macOS) | |
| if: always() && contains(matrix.os.image, 'self-hosted') | |
| run: bash scripts/ci-cleanup-macos.sh | |
| merge-reports: | |
| # Merge reports after playwright-tests, even if some shards have failed | |
| # Skip if tests were skipped (only .claude files changed) | |
| if: ${{ !cancelled() && needs.check-changes.outputs.should_run_tests == 'true' }} | |
| needs: [check-changes, e2e-tests] | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| actions: read | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v5 | |
| with: | |
| repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }} | |
| ref: ${{ github.event.pull_request.head.ref || '' }} | |
| - uses: actions/setup-node@v5 | |
| with: | |
| node-version: v24.13.1 | |
| - name: Install npm 11.8.0 | |
| run: npm install -g npm@11.8.0 | |
| - name: Install dependencies | |
| run: npm ci --no-audit --no-fund --progress=false | |
| env: | |
| # Required for @vscode/ripgrep to download binaries without hitting GitHub API rate limits | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Download blob reports from GitHub Actions Artifacts | |
| uses: actions/download-artifact@v7 | |
| with: | |
| path: all-blob-reports | |
| pattern: blob-report-* | |
| merge-multiple: true | |
| - name: Debug - List downloaded blob reports | |
| run: | | |
| echo "Contents of all-blob-reports directory:" | |
| ls -la all-blob-reports/ | |
| echo "File sizes and details:" | |
| find all-blob-reports/ -type f -exec ls -lh {} \; || echo "No files found" | |
| - name: Merge into HTML Report | |
| run: PLAYWRIGHT_HTML_OUTPUT_DIR=playwright-report npx playwright merge-reports --config=merge.config.ts ./all-blob-reports | |
| - name: Debug - List playwright-report contents | |
| run: | | |
| echo "Contents of playwright-report directory:" | |
| ls -la playwright-report/ || echo "playwright-report directory does not exist" | |
| echo "Current directory contents:" | |
| ls -la | |
| - name: Upload HTML report | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: html-report | |
| path: playwright-report | |
| retention-days: 3 | |
| overwrite: true | |
| - name: Generate Playwright summary | |
| uses: actions/github-script@v8 | |
| env: | |
| PLAYWRIGHT_RUN_ID: ${{ github.run_id }} | |
| with: | |
| script: | | |
| const { run } = require('./scripts/generate-playwright-summary.js'); | |
| await run({ github, context, core }); |