CI setup

razo's two CLIs cover two independent CI integrations: uploading runs to a hosted dashboard, and posting an AI failure analysis directly on a pull request with your own Anthropic key. Neither depends on the other — add one, both, or neither.

Recipe: upload runs to the dashboard

Create a project at razo.ar/dashboard and copy its ingest token (shown once — see Dashboard & plans). Add it as a repository secret named RAZO_INGEST_TOKEN.

Upload with if: always() so both passing and failing runs reach the dashboard — a run with zero failures is still useful history, and a run that fails outright still needs to show up:

name: e2e

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci
      - run: npx playwright install --with-deps

      - name: Run Playwright tests
        run: npx playwright test

      - name: Upload razo artifacts
        if: always()
        run: npx razo-upload --url https://YOUR-APP.vercel.app/api/ingest
        env:
          RAZO_INGEST_TOKEN: ${{ secrets.RAZO_INGEST_TOKEN }}

Replace YOUR-APP.vercel.app with your dashboard's URL (razo.ar if you're using the hosted instance). --url can also come from a RAZO_INGEST_URL repository variable instead of hardcoding it in the step. razo-upload reads GITHUB_* environment variables automatically, so branch, commit, PR number and the CI run link are attached to the run with no extra configuration.

Recipe: analyze failures on pull requests (bring your own key)

This recipe doesn't touch the dashboard at all — it runs razo-analyze --pr-comment directly, using your own ANTHROPIC_API_KEY, and posts the result as a PR comment. It only needs to run when tests actually fail:

name: e2e

on: pull_request

permissions:
  pull-requests: write

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci
      - run: npx playwright install --with-deps

      - name: Run Playwright tests
        run: npx playwright test

      - name: AI failure analysis
        if: failure()
        run: npx razo-analyze --pr-comment
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

--pr-comment needs GITHUB_TOKEN explicitly mapped into the step's environment (it isn't injected by default) and permissions: pull-requests: write on the job, or the comment post is rejected. Re-runs update the same comment instead of stacking new ones.

razo-analyzer also ships a composite GitHub Action that wraps the same command, if you'd rather not spell out the npx call:

- name: Run Playwright tests
  run: npx playwright test

- name: AI failure analysis
  if: failure()
  uses: razohq/razo/packages/razo-analyzer@main
  with:
    anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
    results-dir: test-results

It defaults pr-comment to true and still requires the same permissions block.

Combining both

The two recipes read the same test-results/ directory and don't interfere — add both steps to one job: razo-upload with if: always() keeps the dashboard's run history and AI diagnosis complete, razo-analyze --pr-comment (or the composite Action) with if: failure() gives reviewers an immediate comment on the PR without waiting to open the dashboard. Since the PR-comment recipe uses your own API key, it isn't subject to the dashboard's hosted analysis quota — see Dashboard & plans.

Next steps