Application experience improvements #607
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: | |
| branches: [main] | |
| concurrency: | |
| group: ci-${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| CARGO_TERM_COLOR: always | |
| RUST_BACKTRACE: 1 | |
| jobs: | |
| # Formatting check - only needs to run once since cargo fmt is purely textual | |
| # (no compilation, so no platform-specific code paths like #[cfg(target_os)]) | |
| format: | |
| name: Format Check | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@master | |
| with: | |
| toolchain: "1.89" | |
| components: rustfmt | |
| - name: Check formatting | |
| run: cargo fmt --all -- --check | |
| bun-ecosystem: | |
| name: Bun Ecosystem Checks | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Setup Bun | |
| uses: ./.github/actions/setup-bun | |
| - name: Verify bun.lock hash integrity | |
| run: | | |
| set -euo pipefail | |
| stored="$(bun pm hash-print | tr -d '\r\n')" | |
| computed="$(bun pm hash | tr -d '\r\n')" | |
| if [ -z "${stored}" ] || [ -z "${computed}" ]; then | |
| echo "Failed to compute bun.lock hash." | |
| exit 1 | |
| fi | |
| if [ "${stored}" != "0000000000000000-0000000000000000-0000000000000000-0000000000000000" ] && [ "${stored}" != "${computed}" ]; then | |
| echo "bun.lock hash mismatch." | |
| echo "stored: ${stored}" | |
| echo "computed: ${computed}" | |
| exit 1 | |
| fi | |
| git diff --exit-code -- bun.lock | |
| - name: Audit dependencies | |
| run: bun audit --audit-level=high | |
| marketplace-validate: | |
| name: Marketplace Packer Validate | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Assert Marketplace scripts | |
| run: | | |
| test -f infra/digitalocean/marketplace/90-cleanup.sh | |
| test -f infra/digitalocean/marketplace/99-img-check.sh | |
| - name: Setup Packer | |
| uses: hashicorp/setup-packer@v3 | |
| with: | |
| version: "1.10.0" | |
| - name: Packer init | |
| run: packer init infra/digitalocean/packer/opencode-marketplace.pkr.hcl | |
| - name: Packer fmt | |
| run: packer fmt -check infra/digitalocean/packer/opencode-marketplace.pkr.hcl | |
| - name: Packer validate | |
| run: packer validate -var-file=infra/digitalocean/packer/variables.pkr.hcl infra/digitalocean/packer/opencode-marketplace.pkr.hcl | |
| compose-validate: | |
| name: Compose File Validate | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Validate docker-compose.yml | |
| run: docker compose config --quiet | |
| docker-context-guard: | |
| name: Docker Context Guard | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| # Use docker/build-push-action with GHA + registry cache so unchanged | |
| # layers are reused across CI runs (~3 min → ~30s on cache hit). | |
| # Previously this ran a bare `docker build` with no caching at all. | |
| - name: Build Docker target stage | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: . | |
| file: packages/core/src/docker/Dockerfile | |
| target: opencode-build | |
| push: false | |
| load: false | |
| cache-from: | | |
| type=gha,scope=opencode-cloud-sandbox-context-guard,version=2 | |
| type=gha,scope=opencode-cloud-sandbox-amd64,version=2 | |
| type=registry,ref=ghcr.io/prizz/opencode-cloud-sandbox:buildcache-amd64 | |
| cache-to: type=gha,scope=opencode-cloud-sandbox-context-guard,mode=min,version=2 | |
| # Build, lint, and test on multiple platforms | |
| # Clippy/build/test must run on each platform because #[cfg(target_os)] causes | |
| # different code to compile (e.g., systemd.rs on Linux, launchd.rs on macOS) | |
| build: | |
| name: Build (${{ matrix.os }}) | |
| runs-on: ${{ matrix.os }} | |
| timeout-minutes: 20 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest] | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Verify opencode submodule pin is published | |
| run: ./scripts/check-opencode-submodule-published.sh | |
| - name: Install Linux system dependencies | |
| if: matrix.os == 'ubuntu-latest' | |
| run: | | |
| # Required by opencode-broker (libpam-sys links against -lpam). | |
| sudo apt-get update | |
| sudo apt-get install -y libpam0g-dev | |
| - name: Initialize opencode submodule | |
| run: | | |
| git -c url."https://github.com/".insteadOf=git@github.com: submodule update --init --recursive packages/opencode | |
| git submodule status --recursive | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@master | |
| with: | |
| toolchain: "1.89" | |
| components: clippy | |
| - name: Install just | |
| uses: extractions/setup-just@v3 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v5 | |
| with: | |
| node-version: '20' | |
| - name: Setup Bun | |
| uses: ./.github/actions/setup-bun | |
| - name: Rust cache | |
| uses: Swatinem/rust-cache@v2 | |
| - name: Configure git identity | |
| run: | | |
| git config --global user.email "bot@opencode.ai" | |
| git config --global user.name "opencode" | |
| # Project checks should run via shared just targets. | |
| - name: Run CI checks | |
| run: just ci-checks | |
| - name: Record CLI parity SHA | |
| if: matrix.os == 'ubuntu-latest' | |
| run: git rev-parse HEAD > cli-parity.sha | |
| - name: Upload CLI parity artifacts | |
| if: matrix.os == 'ubuntu-latest' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: cli-parity-artifacts | |
| path: | | |
| target/debug/opencode-cloud | |
| packages/cli-node/dist | |
| cli-parity.sha | |
| # CLI Parity - ensures Node CLI can invoke all Rust CLI commands | |
| cli-parity: | |
| name: CLI Parity Tests | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| needs: [build] | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Install just | |
| uses: extractions/setup-just@v3 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v5 | |
| with: | |
| node-version: '20' | |
| - name: Setup Bun | |
| uses: ./.github/actions/setup-bun | |
| with: | |
| install: "false" | |
| - name: Download CLI parity artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: cli-parity-artifacts | |
| - name: Verify artifact SHA | |
| run: | | |
| if [ -f cli-parity.sha ]; then | |
| echo "Artifact SHA: $(cat cli-parity.sha)" | |
| echo "Workflow SHA: $GITHUB_SHA" | |
| test "$(cat cli-parity.sha)" = "$GITHUB_SHA" | |
| fi | |
| - name: Ensure Rust binary executable | |
| run: chmod +x target/debug/opencode-cloud | |
| - name: Install Node dependencies (cli only) | |
| run: just ci-node-install-cli-only | |
| - name: Run CLI parity tests | |
| run: bun run --cwd packages/cli-node test | |
| # E2E Tests - Playwright browser tests for the opencode web UI | |
| e2e: | |
| name: E2E Tests | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| needs: [build] | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Initialize opencode submodule | |
| run: | | |
| git -c url."https://github.com/".insteadOf=git@github.com: submodule update --init --recursive packages/opencode | |
| git submodule status --recursive | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v5 | |
| with: | |
| node-version: '20' | |
| - name: Setup Bun | |
| uses: ./.github/actions/setup-bun | |
| with: | |
| install: "false" | |
| - name: Configure git identity | |
| run: | | |
| git config --global user.email "bot@opencode.ai" | |
| git config --global user.name "opencode" | |
| - name: Install just | |
| uses: extractions/setup-just@v3 | |
| - name: Run e2e tests | |
| run: just ci-e2e | |
| timeout-minutes: 30 | |
| - name: Upload Playwright artifacts | |
| if: failure() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: playwright-e2e-${{ github.run_attempt }} | |
| if-no-files-found: ignore | |
| retention-days: 7 | |
| path: | | |
| packages/opencode/packages/app/e2e/test-results | |
| packages/opencode/packages/app/e2e/playwright-report |