name: test on: push: branches: - dev - v2 pull_request: workflow_dispatch: 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: affected: name: affected packages runs-on: blacksmith-4vcpu-ubuntu-2404 outputs: app: ${{ steps.packages.outputs.app }} steps: - name: Checkout repository uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 with: token: ${{ secrets.GITHUB_TOKEN }} fetch-depth: 0 - name: Setup Bun uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 with: bun-version-file: package.json - name: Find affected packages id: packages env: TURBO_SCM_BASE: ${{ github.event_name == 'pull_request' && format('{0}^1', github.sha) || github.event.before }} TURBO_SCM_HEAD: ${{ github.sha }} run: | if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then echo "app=true" >> "$GITHUB_OUTPUT" exit 0 fi bun x turbo@2.10.2 ls --affected --filter=@opencode-ai/app --output=json > affected.json bun -e 'const result = await Bun.file("affected.json").json(); console.log(`app=${result.packages.count > 0}`)' >> "$GITHUB_OUTPUT" unit: 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 }} fetch-depth: 0 - name: Setup Node uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: "24" - name: Setup Bun uses: ./.github/actions/setup-bun - name: Test Effect simplification rules if: runner.os == 'Linux' run: bun run test:effect-simplification-rules - name: Check Effect simplifications if: runner.os == 'Linux' run: bun run lint:effect-simplifications - name: Configure git identity run: | git config --global user.email "bot@opencode.ai" git config --global user.name "opencode" - name: Install ffmpeg if: runner.os == 'Linux' run: | sudo apt-get update sudo apt-get install --yes ffmpeg - 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: | if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then GITHUB_ACTIONS=false bun turbo test exit 0 fi GITHUB_ACTIONS=false bun turbo test --affected env: OPENCODE_EXPERIMENTAL_DISABLE_FILEWATCHER: ${{ runner.os == 'Windows' && 'true' || 'false' }} TURBO_SCM_BASE: ${{ github.event_name == 'pull_request' && format('{0}^1', github.sha) || github.event.before }} TURBO_SCM_HEAD: ${{ github.sha }} - name: Verify published codemode package if: runner.os == 'Linux' working-directory: packages/codemode run: bun run script/publish.ts --dry-run - name: Verify packed workerd SDK if: runner.os == 'Linux' timeout-minutes: 15 run: | if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then bun turbo verify:package --filter=@opencode-ai/sdk exit 0 fi bun turbo verify:package --affected --filter=@opencode-ai/sdk env: TURBO_SCM_BASE: ${{ github.event_name == 'pull_request' && format('{0}^1', github.sha) || github.event.before }} TURBO_SCM_HEAD: ${{ github.sha }} - name: Verify compiled service lifecycle if: always() timeout-minutes: 10 working-directory: packages/cli env: NODE_OPTIONS: ${{ runner.os == 'Windows' && '--max-old-space-size=4096' || '' }} run: | bun run script/build.ts --single --skip-install bun run script/service-smoke.ts - name: Setup Node build runtime if: always() uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: "26.4.0" - name: Verify Node build if: always() timeout-minutes: 15 working-directory: packages/cli env: NODE_OPTIONS: ${{ runner.os == 'Windows' && '--max-old-space-size=4096' || '' }} run: | bun run script/build-node.ts --single --skip-install --outdir=dist/node bun run script/service-smoke.ts --node - name: Check generated client if: runner.os == 'Linux' working-directory: packages/client run: bun run check:generated - name: Check generated documentation if: runner.os == 'Linux' working-directory: packages/www run: bun run check:generated e2e: name: e2e (${{ matrix.settings.name }}) needs: affected 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: E2E_ENABLED: ${{ needs.affected.outputs.app == 'true' && github.ref_name != 'v2' && github.head_ref != 'v2' }} PLAYWRIGHT_BROWSERS_PATH: ${{ github.workspace }}/.playwright-browsers defaults: run: shell: bash steps: - name: Checkout repository if: env.E2E_ENABLED == 'true' uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 with: token: ${{ secrets.GITHUB_TOKEN }} - name: Setup Node if: env.E2E_ENABLED == 'true' 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 if: env.E2E_ENABLED == 'true' uses: ./.github/actions/setup-bun - name: Read Playwright version if: env.E2E_ENABLED == 'true' 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 if: env.E2E_ENABLED == 'true' 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: env.E2E_ENABLED == 'true' && runner.os == 'Linux' working-directory: packages/app run: bunx playwright install-deps chromium - name: Install Playwright browsers if: env.E2E_ENABLED == 'true' && steps.playwright-cache.outputs.cache-hit != 'true' working-directory: packages/app run: bunx playwright install chromium - name: Run app e2e tests against production build if: env.E2E_ENABLED == 'true' run: bun --cwd packages/app test:e2e:built env: CI: true timeout-minutes: 30 - name: Verify service worker precaching and upgrades if: env.E2E_ENABLED == 'true' working-directory: packages/app run: bunx playwright test --config e2e/service-worker/playwright.config.ts timeout-minutes: 5 - name: Upload Playwright artifacts if: always() && env.E2E_ENABLED == 'true' 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