name: CI permissions: contents: read on: push: # dev as well as main so every dev HEAD carries the full CI signal that # the dev->main promotion gate (check-dev-green.sh) reads. PR checks alone are # not enough: an admin-merge can land a red PR onto dev. branches: ["main", "dev"] pull_request: workflow_dispatch: concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: lint: name: Lint runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 - uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 - name: Install dependencies run: uv sync --locked --extra dev - name: Run lint run: make lint format: name: Format check runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 - uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 - name: Install dependencies run: uv sync --locked --extra dev - name: Run format check run: make format-check typecheck: name: Typecheck runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 - name: Install UI dependencies working-directory: ui run: bun install --frozen-lockfile - name: Run Typecheck working-directory: ui run: bun run typecheck unit-tests: name: Unit tests runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 - uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 - name: Install dependencies run: uv sync --locked --extra dev - name: Run unit tests run: make test e2e: name: Playwright E2E runs-on: ubuntu-latest timeout-minutes: 30 steps: - uses: actions/checkout@v7 - uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 - uses: actions/setup-node@v6 with: node-version: "24" - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 - name: Install Python deps (langgraph dev runtime) run: uv sync --locked - name: Install Playwright + Chromium working-directory: tests/e2e run: | npm ci sudo rm -f /etc/apt/sources.list.d/azure-cli.list /etc/apt/sources.list.d/microsoft-prod.list npx playwright install --with-deps chromium # Playwright's webServer boots `langgraph dev`; globalSetup builds the real # ui/ SPA. The fake LLM/GitHub/Slack boundaries need no secrets. - name: Run E2E working-directory: tests/e2e # Playwright's globalSetup runs the real `bun run build`, whose vite bundle # exceeds Node's default ~2 GB heap. # The runner has ~16 GB, so lift the heap cap. env: NODE_OPTIONS: "--max-old-space-size=8192" run: npx playwright test - name: Upload Playwright report if: ${{ !cancelled() }} uses: actions/upload-artifact@v7 with: name: playwright-report path: | tests/e2e/playwright-report tests/e2e/test-results retention-days: 7 docker-build: name: Docker build smoke runs-on: ubuntu-latest timeout-minutes: 20 steps: - uses: actions/checkout@v7 # Smoke-build the sandbox image so a bad Dockerfile pin (e.g. an # apt "nodejs=${NODEJS_VERSION}" that no longer resolves) fails a check # instead of only surfacing at sandbox-provision time. No push, no # registry credentials: this only proves the image builds. - name: Build sandbox image (no push) run: docker build --pull -t open-swe-sandbox:ci . triage-ledger: name: Triage ledger up to date runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 # docs/upstream-sync/triage.md is GENERATED from triage.jsonl. Fail if a # ledger edit forgot to regenerate it (`make triage-render`). Stdlib-only # Python, so no uv sync / deps needed. - name: triage.md is up to date with triage.jsonl run: make triage-check ui-lockfile: name: ui bun.lock in sync runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 - name: ui/package.json and ui/bun.lock agree working-directory: ui run: bun install --frozen-lockfile