> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stably.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# CI Integration

> Run Stably tests in your CI/CD pipeline with automatic test fixing

Stably integrates seamlessly into your CI/CD pipeline. Run tests automatically on every push or pull request, and use `stably fix` to automatically resolve failing tests with AI assistance.

## Choose Your Approach

<CardGroup cols={2}>
  <Card title="Your Own Runner" icon="server">
    Run tests on your CI infrastructure (GitHub Actions, GitLab CI, etc.). You control the environment and pay for compute.
  </Card>

  <Card title="Stably Cloud Runner" icon="cloud">
    Run tests on Stably's scalable infrastructure. Run hundreds of tests in parallel without managing infrastructure.
  </Card>
</CardGroup>

| Feature             | Your Own Runner                   | Stably Cloud                |
| ------------------- | --------------------------------- | --------------------------- |
| **Parallelization** | Limited by CI plan                | Up to 100+ workers          |
| **Setup**           | Install browsers, manage deps     | Just add API key            |
| **Cost**            | Pay your CI provider              | Pay Stably (usage-based)    |
| **Best for**        | Small suites, custom environments | Large suites, fast feedback |

***

## Option 1: Your Own CI Runner

Run Stably CLI commands directly in your CI environment. This approach gives you full control over the test execution environment.

<AccordionGroup>
  <Accordion title="Setup Requirements" icon="gear" defaultOpen>
    Before configuring your CI workflow, you'll need credentials:

    <Steps>
      <Step title="Get Your API Key">
        Go to the [API Keys settings page](https://app.stably.ai/settings?tab=api-key) and create or copy your API key.
      </Step>

      <Step title="Find Your Project ID">
        Navigate to your project in the [Stably dashboard](https://app.stably.ai). The project ID is visible in the project settings or URL.
      </Step>

      <Step title="Add Secrets to CI">
        Add `STABLY_API_KEY` and `STABLY_PROJECT_ID` as secrets in your CI provider.

        **GitHub:** Settings → Secrets and variables → Actions → New repository secret
      </Step>
    </Steps>

    <Warning>
      Never hardcode your API key in configuration files or commit it to version control. Always use your CI provider's secret management.
    </Warning>
  </Accordion>

  <Accordion title="GitHub Actions Example" icon="github">
    The recommended pattern runs tests in a parallel matrix and uses a separate `fix` job that triggers only when tests fail:

    ```yaml .github/workflows/stably.yaml theme={null}
    name: Run Stably Tests

    on:
      push:
        branches:
          - main
      schedule:
        - cron: '0 */3 * * *'
      workflow_dispatch:

    env:
      CI_BUILD_ID: stably-${{ github.run_id }}-${{ github.run_attempt }}

    jobs:
      test:
        runs-on: ubuntu-latest
        timeout-minutes: 120
        strategy:
          fail-fast: false
          matrix:
            project:
              - 'e2e:smoke'
              - 'e2e:checkout'
              - 'e2e:login'
        steps:
          - uses: actions/checkout@v4

          - name: Setup Node.js
            uses: actions/setup-node@v4
            with:
              node-version: '20'

          - name: Install dependencies
            run: npm ci

          - name: Install Playwright browsers
            run: npx playwright install chromium --with-deps

          - name: Run Stably tests
            env:
              STABLY_API_KEY: ${{ secrets.STABLY_API_KEY }}
              STABLY_PROJECT_ID: ${{ secrets.STABLY_PROJECT_ID }}
            run: npx stably test --project=${{ matrix.project }}

      fix:
        needs: test
        if: always() && needs.test.result == 'failure'
        runs-on: ubuntu-latest
        timeout-minutes: 120
        steps:
          - uses: actions/checkout@v4

          - name: Setup Node.js
            uses: actions/setup-node@v4
            with:
              node-version: '20'

          - name: Install dependencies
            run: npm ci

          - name: Install Playwright browsers
            run: npx playwright install chromium --with-deps

          - name: Run Stably Fix
            env:
              STABLY_API_KEY: ${{ secrets.STABLY_API_KEY }}
              STABLY_PROJECT_ID: ${{ secrets.STABLY_PROJECT_ID }}
            run: npx stably fix
    ```

    <Note>
      **Key points:**

      * `CI_BUILD_ID` ties all parallel test shards to the same run, so `stably fix` can find all failures.
      * `fail-fast: false` ensures all matrix jobs complete, giving the fix agent the full picture.
      * The `fix` job uses `if: always() && needs.test.result == 'failure'` to run only when at least one test job failed.
    </Note>
  </Accordion>

  <Accordion title="Other CI Platforms" icon="circle-nodes">
    The same commands work in any CI environment. See platform-specific guides:

    * [CLI in CI guide](/run-tests/cli-in-ci) - GitLab CI, CircleCI, Jenkins, Bitbucket Pipelines, Azure DevOps
    * [GitLab CI guide](/run-tests/gitlab-ci)
  </Accordion>

  <Accordion title="CLI Commands Reference" icon="terminal">
    | Command              | Description                                              |
    | -------------------- | -------------------------------------------------------- |
    | `npx stably install` | Installs browsers needed to run tests                    |
    | `npx stably test`    | Runs your Playwright tests and reports results to Stably |
    | `npx stably fix`     | Uses AI to analyze and fix failing tests                 |

    For full CLI documentation, see the [CLI Reference](/stably-cli/commands).
  </Accordion>

  <Accordion title="How stably fix Works in CI" icon="wand-magic-sparkles">
    When you run `stably fix` in CI, it **automatically detects** which test run to fix using the `CI_BUILD_ID` environment variable.

    **Behind the scenes:**

    1. The `CI_BUILD_ID` env var (e.g., `stably-${{ github.run_id }}-${{ github.run_attempt }}`) ties all parallel test shards to a single logical run
    2. `stably fix` uses this ID to find all failures across matrix jobs
    3. The AI analyzes the failures and applies targeted fixes

    **Why a separate `fix` job?** When running tests in a parallel matrix (recommended for large suites), `stably fix` must run *after* all test jobs complete so it can see the full set of failures. The `fix` job depends on the `test` job and only triggers when at least one shard failed.
  </Accordion>
</AccordionGroup>

***

## Option 2: Stably Cloud Runner

For teams that need to run large test suites quickly, Stably offers a scalable cloud infrastructure that can run **hundreds of tests in parallel**.

<AccordionGroup>
  <Accordion title="Why Use Stably Cloud?" icon="bolt" defaultOpen>
    <CardGroup cols={2}>
      <Card title="Massive Parallelization" icon="bolt">
        Run up to 100+ tests simultaneously. A 2-hour test suite can complete in minutes.
      </Card>

      <Card title="No Infrastructure Management" icon="wand-magic-sparkles">
        No need to provision runners, manage browser installations, or scale capacity.
      </Card>

      <Card title="Consistent Environment" icon="shield-check">
        Tests run in a clean, consistent environment every time—no flaky failures from CI resource contention.
      </Card>

      <Card title="Built-in Retries" icon="rotate">
        Automatic retries and smart failure analysis included.
      </Card>
    </CardGroup>
  </Accordion>

  <Accordion title="GitHub Action (Recommended)" icon="github">
    Use the Stably GitHub Action to run tests on Stably Cloud:

    ```yaml .github/workflows/stably-cloud.yaml theme={null}
    name: Stably Cloud Tests

    on:
      pull_request:
      push:
        branches:
          - main

    permissions:
      pull-requests: write
      contents: write

    jobs:
      test:
        runs-on: ubuntu-latest

        steps:
          - name: Run Tests on Stably Cloud
            uses: stablyai/stably-runner-action@v4
            with:
              api-key: ${{ secrets.STABLY_API_KEY }}
              project-id: ${{ secrets.STABLY_PROJECT_ID }}
              playwright-project-name: smoke
    ```

    For full configuration options, see the [GitHub Actions guide](/run-tests/github-actions).
  </Accordion>

  <Accordion title="API (Non-GitHub Platforms)" icon="code">
    If you're using GitLab, CircleCI, Jenkins, or another CI platform, use the Stably API to trigger cloud runs:

    ```bash theme={null}
    # Trigger a cloud run
    RUN_ID=$(curl -s -X POST "https://api.stably.ai/v1/projects/${STABLY_PROJECT_ID}/runs" \
      -H "Authorization: Bearer ${STABLY_API_KEY}" \
      -H "Content-Type: application/json" \
      -d '{
        "playwrightProjectName": ["smoke", "regression"],
        "branch": "'"${GITHUB_HEAD_REF:-main}"'"
      }' | jq -r '.runId')

    echo "Started run: $RUN_ID"

    # Poll until the run finishes
    while true; do
      STATUS=$(curl -s "https://api.stably.ai/v1/projects/${STABLY_PROJECT_ID}/runs/${RUN_ID}" \
        -H "Authorization: Bearer ${STABLY_API_KEY}" | jq -r '.status')
      echo "Status: $STATUS"
      case "$STATUS" in
        PASSED|FAILED|TIMEDOUT|CANCELLED|INTERRUPTED) break ;;
      esac
      sleep 10
    done

    # Fail the CI step if the run didn't pass
    [ "$STATUS" = "PASSED" ] || exit 1
    ```

    See the [API Reference](/api-reference/introduction) for full documentation.
  </Accordion>
</AccordionGroup>

<Tip>
  **Start with your own runner** to get familiar with Stably, then consider Stably Cloud when your test suite grows and execution time becomes a bottleneck.
</Tip>

***

## Troubleshooting

<Accordion title="stably fix fails with missing dependencies" icon="circle-exclamation">
  If `stably fix` fails due to missing dependencies or configuration issues, you need to run `stably init` on your repository first. This command sets up the necessary Playwright and Stably SDK dependencies.

  **Solution:**

  1. Run `stably init` locally in your repository:

  ```bash theme={null}
  npx stably init
  ```

  2. The AI agent will install and configure the required dependencies
  3. Commit the changes to your repository
  4. Re-run your CI pipeline

  <Tip>
    `stably init` only needs to be run once per repository. After the initial setup, `stably fix` will work in CI without any additional configuration.
  </Tip>
</Accordion>

## Next Steps

<CardGroup cols={2}>
  <Card title="CLI Reference" icon="terminal" href="/stably-cli/commands">
    Full CLI command reference
  </Card>

  <Card title="GitHub Actions" icon="github" href="/run-tests/github-actions">
    Detailed GitHub Actions setup
  </Card>

  <Card title="Test Groups" icon="layer-group" href="/use-cases/defining-test-groups">
    Organize tests into projects
  </Card>

  <Card title="Alerting" icon="bell" href="/run-tests/alerting">
    Get notified on test failures
  </Card>
</CardGroup>
