name: E2E Tests on: push: branches: [master] pull_request: branches: [master] schedule: - cron: '0 6 * * *' # Nightly at 6am UTC workflow_dispatch: permissions: contents: read # Cancel a superseded run when a newer commit lands on the same PR/branch. # PR number for pull_request events (fork-safe), github.ref fallback for # push/scheduled runs. concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true jobs: jsonb-parity: # Dedicated required guard for the JSONB double-encode bug-class (#2339). # PGLite parses a double-encoded jsonb string silently, so this assertion can # ONLY be made on real Postgres — a normal gated e2e file would skip without # DATABASE_URL and let the bug ship green (as #2339 did). This job provisions # Postgres and HARD-FAILS if DATABASE_URL is missing, so the guard can never # silently skip. name: JSONB parity (#2339 regression guard) runs-on: ubuntu-latest timeout-minutes: 15 services: postgres: image: pgvector/pgvector:pg16 env: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres POSTGRES_DB: gbrain_test ports: - 5432:5432 options: >- --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 steps: - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 with: bun-version: 1.3.13 - run: bun install - name: Require DATABASE_URL (no silent skip) env: DATABASE_URL: postgresql://postgres:postgres@localhost:5432/gbrain_test run: | if [ -z "$DATABASE_URL" ]; then echo "::error::DATABASE_URL must be set for the jsonb-parity job — the #2339 guard would silently skip (the exact failure PGLite hides). Failing the job." >&2 exit 1 fi - name: Run JSONB double-encode parity tests on real Postgres env: DATABASE_URL: postgresql://postgres:postgres@localhost:5432/gbrain_test run: bun test test/e2e/op-checkpoint-jsonb-parity.test.ts test/e2e/jsonb-roundtrip.test.ts tier1: name: Tier 1 (Mechanical) runs-on: ubuntu-latest timeout-minutes: 20 services: postgres: image: pgvector/pgvector:pg16 env: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres POSTGRES_DB: gbrain_test ports: - 5432:5432 options: >- --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 steps: - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 with: bun-version: 1.3.13 - run: bun install - name: Run Tier 1 E2E tests run: bun test test/e2e/mechanical.test.ts test/e2e/mcp.test.ts env: DATABASE_URL: postgresql://postgres:postgres@localhost:5432/gbrain_test tier2: name: Tier 2 (LLM Skills) runs-on: ubuntu-latest # Runs on every push/PR now (promoted from schedule-only in v0.19.0). # Tier 1 must pass first; Tier 2 uses OPENAI_API_KEY + ANTHROPIC_API_KEY # from repo/org secrets. Nightly + manual triggers still supported via # the workflow-level `on:` list. needs: tier1 timeout-minutes: 30 services: postgres: image: pgvector/pgvector:pg16 env: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres POSTGRES_DB: gbrain_test ports: - 5432:5432 options: >- --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 steps: - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 with: bun-version: 1.3.13 - run: bun install - name: Install OpenClaw # Bound + retry the install: a transient npm/registry stall here used to # hang unbounded and (since the v0.42.50.0 job timeout) burn the entire # 30m Tier 2 budget before failing — even though the install normally # finishes in well under a minute. `timeout` kills a hung attempt fast; # up to 3 attempts ride out a flaky registry. Step cap is a backstop. timeout-minutes: 8 run: | for attempt in 1 2 3; do if timeout 120 npm install -g openclaw@2026.4.9; then exit 0 fi echo "::warning::openclaw install attempt $attempt failed or timed out; retrying in 10s" >&2 sleep 10 done echo "::error::openclaw install failed after 3 attempts" >&2 exit 1 - name: Configure OpenClaw MCP run: | mkdir -p ~/.openclaw cat > ~/.openclaw/config.json << 'EOF' { "mcpServers": { "gbrain": { "command": "bun", "args": ["run", "src/cli.ts", "serve"], "env": { "DATABASE_URL": "${{ env.DATABASE_URL }}" } } } } EOF - name: Run Tier 2 skill tests run: bun test test/e2e/skills.test.ts test/e2e/zeroentropy-live.test.ts env: DATABASE_URL: postgresql://postgres:postgres@localhost:5432/gbrain_test OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} # v0.33.3.0: ZE live API tests skip gracefully when this is unset, # so forks without the secret stay green. The test exercises the # zeroEntropyCompatFetch response-rewriter + URL rewrite + flexible # dim handling + gateway.rerank against the real provider. ZEROENTROPY_API_KEY: ${{ secrets.ZEROENTROPY_API_KEY }}