Repository navigation
feat(protocol): expose session goal and todo endpoints #921
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: check-test | |
| on: | |
| push: | |
| branches: | |
| - dev | |
| - beta | |
| pull_request: | |
| types: [opened, synchronize, reopened, ready_for_review] | |
| workflow_dispatch: | |
| inputs: | |
| quarantine: | |
| description: Run only the quarantined browser tests (packages/app/e2e/QUARANTINE.md) | |
| type: boolean | |
| default: false | |
| concurrency: | |
| # A new push to a pull request cancels its stale run. Every push and manual run keeps its own group, so each | |
| # dev and beta commit gets a verdict and a quarantine run never cancels a normal one. | |
| group: ${{ case(github.event_name == 'pull_request', format('{0}-{1}', github.workflow, github.event.pull_request.number), format('{0}-{1}', github.workflow, github.run_id)) }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| checks: write | |
| env: | |
| FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true | |
| jobs: | |
| affected: | |
| name: affected packages | |
| if: ${{ !github.event.pull_request.draft }} | |
| runs-on: blacksmith-4vcpu-ubuntu-2404 | |
| outputs: | |
| e2e: ${{ steps.packages.outputs.app }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| # Pull requests diff against the merge's first parent; pushes diff against the previous dev head. | |
| fetch-depth: ${{ github.event_name == 'pull_request' && 2 || 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 | |
| # packages/stories hosts the component tests, but no app package depends on it. | |
| bun x turbo@2.10.2 ls --affected --filter=@opencode/app --filter=@opencode/stories --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 }}) | |
| if: ${{ !inputs.quarantine && !github.event.pull_request.draft }} | |
| 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 }} | |
| # Pull requests diff against the merge's first parent; pushes diff against the previous dev head. | |
| fetch-depth: ${{ github.event_name == 'pull_request' && 2 || 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: Run unit tests | |
| timeout-minutes: 20 | |
| run: | | |
| # The runners have four vCPUs, and each Bun test process performs its own concurrent work. | |
| if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then | |
| GITHUB_ACTIONS=false bun turbo test --concurrency=3 | |
| exit 0 | |
| fi | |
| GITHUB_ACTIONS=false bun turbo test --affected --concurrency=3 | |
| 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 packed codemode package | |
| if: runner.os == 'Linux' | |
| working-directory: packages/codemode | |
| run: bun run pack | |
| - 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/sdk | |
| exit 0 | |
| fi | |
| bun turbo verify:package --affected --filter=@opencode/sdk | |
| env: | |
| TURBO_SCM_BASE: ${{ github.event_name == 'pull_request' && format('{0}^1', github.sha) || github.event.before }} | |
| TURBO_SCM_HEAD: ${{ github.sha }} | |
| - name: Check generated client | |
| if: runner.os == 'Linux' | |
| working-directory: packages/client | |
| run: bun run check:generated | |
| - name: Check generated OpenAPI document | |
| if: runner.os == 'Linux' | |
| working-directory: packages/protocol | |
| run: bun run check:generated | |
| build: | |
| name: build (${{ matrix.settings.name }}) | |
| if: ${{ !inputs.quarantine && !github.event.pull_request.draft }} | |
| 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 }} | |
| # Pull requests diff against the merge's first parent; pushes diff against the previous dev head. | |
| fetch-depth: ${{ github.event_name == 'pull_request' && 2 || 0 }} | |
| - name: Setup Bun | |
| uses: ./.github/actions/setup-bun | |
| - name: Verify compiled service lifecycle | |
| 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 | |
| # Unit tests import workspace sources and never build the libraries they use, so this checks those builds. The | |
| # CLI and app closures hold every library a tested package depends on. The builds are tsc and Bun.build with no | |
| # platform-specific steps, and the libraries publish from Linux, so Windows skips them. | |
| - name: Build workspace libraries | |
| if: ${{ !cancelled() && runner.os == 'Linux' }} | |
| timeout-minutes: 10 | |
| run: | | |
| if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then | |
| bun turbo build --concurrency=3 --filter='@opencode/cli^...' --filter='@opencode/app^...' | |
| exit 0 | |
| fi | |
| bun turbo build --affected --concurrency=3 --filter='@opencode/cli^...' --filter='@opencode/app^...' | |
| env: | |
| TURBO_SCM_BASE: ${{ github.event_name == 'pull_request' && format('{0}^1', github.sha) || github.event.before }} | |
| TURBO_SCM_HEAD: ${{ github.sha }} | |
| - name: Setup Node build runtime | |
| if: ${{ !cancelled() }} | |
| uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 | |
| with: | |
| node-version: "26.4.0" | |
| - name: Verify Node build | |
| if: ${{ !cancelled() }} | |
| 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 | |
| e2e-suite: | |
| name: e2e (${{ matrix.settings.name }}, ${{ matrix.suite.id }}${{ matrix.quarantine && ', quarantine' || '' }}) | |
| needs: affected | |
| if: needs.affected.outputs.e2e == 'true' | |
| # Quarantined tests are known red; their legs report without failing the e2e checks. | |
| continue-on-error: ${{ matrix.quarantine }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| # Beta PRs gate on Linux; Windows runs on pushes and manual runs (nightly-beta.yml dispatches beta). | |
| settings: ${{ fromJSON(github.base_ref == 'beta' && '[{"name":"linux","host":"blacksmith-4vcpu-ubuntu-2404"}]' || '[{"name":"linux","host":"blacksmith-4vcpu-ubuntu-2404"},{"name":"windows","host":"blacksmith-4vcpu-windows-2025"}]') }} | |
| quarantine: ${{ fromJSON(inputs.quarantine && '[true]' || '[false]') }} | |
| # Playwright splits whole spec files across shards by test count, not duration. Every app-N | |
| # entry must use the same total, and the entries must cover 1..total. The service worker suite | |
| # reuses shard 2's production build. Each component suite runs once per OS in its own leg, so the | |
| # two suites' story servers and test time are not added up on one runner. | |
| suite: | |
| - id: app-1 | |
| shard: 1/2 | |
| - id: app-2 | |
| shard: 2/2 | |
| - id: session-ui-components | |
| - id: app-components | |
| runs-on: ${{ matrix.settings.host }} | |
| env: | |
| PLAYWRIGHT_BROWSERS_PATH: ${{ github.workspace }}/.playwright-browsers | |
| # Beta only (packages/app/e2e/QUARANTINE.md): gate legs skip quarantined tests, retry once and stop after 8 | |
| # failures; quarantine legs run only those tests, to the end. Other branches keep the config defaults. | |
| PLAYWRIGHT_ARGS: ${{ matrix.quarantine && '--grep @quarantine --pass-with-no-tests --retries=1' || (github.base_ref == 'beta' || github.ref == 'refs/heads/beta') && '--grep-invert @quarantine --max-failures=8 --retries=1' || '' }} | |
| 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 against production build | |
| if: matrix.suite.shard | |
| run: bun --cwd packages/app test:e2e:built --shard=${{ matrix.suite.shard }} ${{ env.PLAYWRIGHT_ARGS }} | |
| env: | |
| CI: true | |
| timeout-minutes: ${{ (matrix.quarantine || github.base_ref == 'beta' || github.ref == 'refs/heads/beta') && 10 || 15 }} | |
| - name: Verify service worker precaching and upgrades | |
| if: matrix.suite.shard == '2/2' && !matrix.quarantine | |
| working-directory: packages/app | |
| run: bunx playwright test --config e2e/service-worker/playwright.config.ts | |
| timeout-minutes: 5 | |
| - name: Run session UI component tests | |
| if: matrix.suite.id == 'session-ui-components' | |
| run: bun --cwd packages/session-ui test:components ${{ env.PLAYWRIGHT_ARGS }} | |
| env: | |
| CI: true | |
| timeout-minutes: ${{ (matrix.quarantine || github.base_ref == 'beta' || github.ref == 'refs/heads/beta') && 10 || 15 }} | |
| - name: Run app component tests | |
| if: matrix.suite.id == 'app-components' | |
| run: bun --cwd packages/app test:components ${{ env.PLAYWRIGHT_ARGS }} | |
| env: | |
| CI: true | |
| timeout-minutes: ${{ (matrix.quarantine || github.base_ref == 'beta' || github.ref == 'refs/heads/beta') && 10 || 15 }} | |
| - name: Upload Playwright artifacts | |
| if: always() | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 | |
| with: | |
| name: playwright-${{ matrix.settings.name }}-${{ matrix.suite.id }}${{ matrix.quarantine && '-quarantine' || '' }}-${{ github.run_attempt }} | |
| if-no-files-found: ignore | |
| retention-days: 7 | |
| path: | | |
| packages/app/e2e/test-results | |
| packages/app/e2e/playwright-report | |
| packages/session-ui/component-tests/test-results | |
| packages/session-ui/component-tests/playwright-report | |
| packages/app/component-tests/test-results | |
| packages/app/component-tests/playwright-report | |
| # Branch rules require one e2e check per OS. These keep those names and pass only when every | |
| # leg above passed, or when no leg was needed; a failing leg on either OS fails both checks. | |
| e2e: | |
| name: e2e (${{ matrix.os }}) | |
| needs: [affected, e2e-suite] | |
| if: ${{ !cancelled() && !inputs.quarantine && !github.event.pull_request.draft }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [linux, windows] | |
| runs-on: blacksmith-4vcpu-ubuntu-2404 | |
| steps: | |
| - name: Check browser test results | |
| env: | |
| AFFECTED: ${{ needs.affected.result }} | |
| SUITES: ${{ needs.e2e-suite.result }} | |
| EXPECTED: ${{ needs.affected.outputs.e2e == 'true' && 'success' || 'skipped' }} | |
| run: | | |
| if [ "${{ matrix.os }}" = windows ] && [ "${{ github.base_ref }}" = beta ]; then | |
| echo "Windows browser tests run on beta pushes and nightly, not on beta pull requests" | |
| exit 0 | |
| fi | |
| echo "affected packages: $AFFECTED, browser test legs: $SUITES (expected $EXPECTED)" | |
| test "$AFFECTED" = success && test "$SUITES" = "$EXPECTED" |