name: test on: push: branches: - dev pull_request: workflow_dispatch: inputs: windows_opentui_repro: description: "Run targeted Windows OpenTUI standalone crash repro" required: false type: boolean default: false concurrency: # Keep every run on dev so cancelled checks do not pollute the default branch # commit history. PRs and other branches still share a group and cancel stale runs. group: ${{ case(github.ref == 'refs/heads/dev', format('{0}-{1}', github.workflow, github.run_id), format('{0}-{1}', github.workflow, github.event.pull_request.number || github.ref)) }} cancel-in-progress: true permissions: contents: read checks: write env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true jobs: unit: if: ${{ github.event_name != 'workflow_dispatch' || inputs.windows_opentui_repro != true }} name: unit (${{ matrix.settings.name }}) strategy: fail-fast: false matrix: settings: - name: linux host: blacksmith-4vcpu-ubuntu-2404 - name: windows host: blacksmith-4vcpu-windows-2025 runs-on: ${{ matrix.settings.host }} defaults: run: shell: bash steps: - name: Checkout repository uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 with: token: ${{ secrets.GITHUB_TOKEN }} - name: Setup Node uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: "24" - name: Setup Bun uses: ./.github/actions/setup-bun - name: Configure git identity run: | git config --global user.email "bot@opencode.ai" git config --global user.name "opencode" - name: Cache Turbo uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: path: node_modules/.cache/turbo key: turbo-${{ runner.os }}-${{ hashFiles('turbo.json', '**/package.json') }}-${{ github.sha }} restore-keys: | turbo-${{ runner.os }}-${{ hashFiles('turbo.json', '**/package.json') }}- turbo-${{ runner.os }}- - name: Run unit tests timeout-minutes: 20 run: GITHUB_ACTIONS=false bun turbo test env: OPENCODE_EXPERIMENTAL_DISABLE_FILEWATCHER: ${{ runner.os == 'Windows' && 'true' || 'false' }} - name: Check generated client if: runner.os == 'Linux' working-directory: packages/client run: bun run check:generated - name: Run HttpApi exerciser gates if: runner.os == 'Linux' working-directory: packages/opencode run: bun run test:httpapi e2e: if: ${{ github.event_name != 'workflow_dispatch' || inputs.windows_opentui_repro != true }} name: e2e (${{ matrix.settings.name }}) strategy: fail-fast: false matrix: settings: - name: linux host: blacksmith-4vcpu-ubuntu-2404 - name: windows host: blacksmith-4vcpu-windows-2025 runs-on: ${{ matrix.settings.host }} env: PLAYWRIGHT_BROWSERS_PATH: ${{ github.workspace }}/.playwright-browsers defaults: run: shell: bash steps: - name: Checkout repository uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 with: token: ${{ secrets.GITHUB_TOKEN }} - name: Setup Node uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: # Playwright 1.59 hangs while extracting Chromium with Node 24.16. node-version: "24.15" - name: Setup Bun uses: ./.github/actions/setup-bun - name: Read Playwright version id: playwright-version run: | version=$(node -e 'console.log(require("./package.json").workspaces.catalog["@playwright/test"])') echo "version=$version" >> "$GITHUB_OUTPUT" - name: Cache Playwright browsers id: playwright-cache uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: path: ${{ github.workspace }}/.playwright-browsers key: ${{ runner.os }}-${{ runner.arch }}-playwright-${{ steps.playwright-version.outputs.version }}-chromium - name: Install Playwright system dependencies if: runner.os == 'Linux' working-directory: packages/app run: bunx playwright install-deps chromium - name: Install Playwright browsers if: steps.playwright-cache.outputs.cache-hit != 'true' working-directory: packages/app run: bunx playwright install chromium - name: Run app e2e tests run: bun --cwd packages/app test:e2e:local env: CI: true timeout-minutes: 30 - name: Upload Playwright artifacts if: always() uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: playwright-${{ matrix.settings.name }}-${{ github.run_attempt }} if-no-files-found: ignore retention-days: 7 path: | packages/app/e2e/test-results packages/app/e2e/playwright-report windows-opentui-repro: if: ${{ github.event_name == 'workflow_dispatch' && inputs.windows_opentui_repro == true }} name: windows opentui repro (${{ matrix.name }}, ${{ matrix.version }}, ${{ matrix.host }}) strategy: fail-fast: false matrix: include: - version: "1.17.9" host: windows-latest name: baseline markdownLoops: 1 onlyMarkdown: false - version: "1.17.10" host: windows-latest name: baseline markdownLoops: 1 onlyMarkdown: false - version: "1.17.10" host: windows-latest name: markdown-stress markdownLoops: 10 onlyMarkdown: true - version: "1.17.11" host: windows-latest name: baseline markdownLoops: 1 onlyMarkdown: false - version: "1.17.10" host: windows-2022 name: baseline markdownLoops: 1 onlyMarkdown: false runs-on: ${{ matrix.host }} defaults: run: shell: pwsh steps: - name: Checkout repository uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 with: token: ${{ secrets.GITHUB_TOKEN }} - name: Setup Node uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: "24.11.1" - name: Run Windows standalone repro timeout-minutes: 30 run: | $reproArgs = @("-Version", "${{ matrix.version }}", "-MarkdownLoops", "${{ matrix.markdownLoops }}") if ("${{ matrix.onlyMarkdown }}" -eq "true") { $reproArgs += "-OnlyMarkdown" } ./script/repro-windows-opentui-crash.ps1 @reproArgs - name: Upload Windows repro artifacts if: always() uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: windows-opentui-repro-${{ matrix.name }}-${{ matrix.version }}-${{ matrix.host }}-${{ github.run_attempt }} if-no-files-found: ignore retention-days: 7 path: | ${{ runner.temp }}/opencode-windows-opentui-${{ matrix.version }}/**/*.log ${{ runner.temp }}/opencode-windows-opentui-${{ matrix.version }}/**/*.jsonl ${{ runner.temp }}/*.out.log ${{ runner.temp }}/*.err.log