> ## Documentation Index
> Fetch the complete documentation index at: https://scanaislop-update.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Scanaislop CI/CD integration for GitLab, CircleCI, Bitbucket

> Add scanaislop quality gates to GitLab CI, CircleCI, and Bitbucket Pipelines with copy-paste YAML configs and PR-scoped file diffing.

Scanaislop's `ci` command is designed to run identically on every CI provider. It scans your codebase, outputs structured JSON, and exits with a non-zero code when the score drops below your configured threshold or any error-severity diagnostic is present. Because `npx --yes aislop@latest ci` always fetches the latest published CLI, there is no version pin to maintain across your pipelines.

## GitLab CI

Add an `aislop` job to your `.gitlab-ci.yml`. The job runs on merge requests and pushes to `main` by default — adjust the `rules` block to match your branching strategy.

```yaml theme={null}
# .gitlab-ci.yml
aislop:
  image: node:24
  script:
    - npx --yes aislop@latest ci
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_COMMIT_BRANCH == "main"
```

## CircleCI

Add an `aislop` job to your CircleCI config and include it in your `quality-gate` workflow.

```yaml theme={null}
# .circleci/config.yml
version: 2.1

jobs:
  aislop:
    docker:
      - image: cimg/node:24.0
    steps:
      - checkout
      - run: npx --yes aislop@latest ci

workflows:
  quality-gate:
    jobs:
      - aislop
```

## Bitbucket Pipelines

Bitbucket clones repositories with a shallow history by default. Branch diffs require full history, and the PR target branch is exposed as `$BITBUCKET_PR_DESTINATION_BRANCH`. Fetch the target branch before running aislop, then gate on only the changed files using `--changes --base FETCH_HEAD`.

```yaml theme={null}
# bitbucket-pipelines.yml
pipelines:
  pull-requests:
    "**":
      - step:
          name: aislop gate
          image: node:24
          clone:
            depth: full   # branch diffs need history
          script:
            - git fetch origin "$BITBUCKET_PR_DESTINATION_BRANCH"
            - npx --yes aislop@latest ci --changes --base FETCH_HEAD
```

<Note>
  Bitbucket's clone contains only the source branch. Running `git fetch origin <branch>` sets `FETCH_HEAD` without creating a local `origin/<branch>` ref — use `--base FETCH_HEAD` rather than `--base origin/<branch>` to avoid a ref-resolution error.
</Note>

## PR-scoped gating

By default, `aislop ci` scores your entire codebase. Passing `--changes --base <ref>` restricts the scan to files that differ between the current `HEAD` and the base branch, making the gate faster and more actionable on large repositories.

```bash theme={null}
npx aislop@latest ci --changes --base origin/main
```

Both `scan` and `ci` accept `--changes` and `--base`, and the score gate and exit code apply to the scoped set of files. If `--base` cannot be resolved, the run fails rather than silently passing an empty scan.

<Warning>
  A plain `--changes` (without `--base`) diffs the working tree against `HEAD`. In CI, PR changes are already committed, so this sees nothing. Always pass `--base <ref>` when gating a pull request.
</Warning>

<Tabs>
  <Tab title="Full clone (GitLab / CircleCI)">
    ```bash theme={null}
    npx aislop@latest ci --changes --base origin/main
    ```

    Works directly when the repository was cloned with full history.
  </Tab>

  <Tab title="Shallow clone (Bitbucket)">
    ```bash theme={null}
    git fetch origin "$BITBUCKET_PR_DESTINATION_BRANCH"
    npx aislop@latest ci --changes --base FETCH_HEAD
    ```

    Fetch the target branch first; `FETCH_HEAD` is set by the fetch command.
  </Tab>
</Tabs>

## Quality gate configuration

Set your minimum acceptable score in `.aislop/config.yml`. aislop exits with code `1` when the score falls below `failBelow` or when any error-severity diagnostic is present.

```yaml theme={null}
# .aislop/config.yml
ci:
  failBelow: 70
  format: json
```

To extend a base config from a parent directory or shared policy file:

```yaml theme={null}
# .aislop/config.yml
extends: ../../.aislop/base.yml
ci:
  failBelow: 80    # override specific keys
```

## JSON output format

Both `aislop ci` and `aislop scan --json` emit structured JSON that you can parse in scripts or forward to dashboards. The shape looks like this:

```json theme={null}
{
  "schemaVersion": "1",
  "cliVersion": "<version>",
  "score": 87,
  "label": "Healthy",
  "engines": {
    "format":       { "issues": 0, "skipped": false, "elapsed": 406 },
    "lint":         { "issues": 0, "skipped": false, "elapsed": 378 },
    "code-quality": { "issues": 1, "skipped": false, "elapsed": 812 },
    "ai-slop":      { "issues": 2, "skipped": false, "elapsed": 455 },
    "security":     { "issues": 0, "skipped": false, "elapsed": 1103 }
  },
  "diagnostics": []
}
```

<Tip>
  Use `aislop ci --human` when you want readable terminal output in CI logs instead of JSON — useful during initial setup and debugging.
</Tip>
