Skip to main content
New aislop v0.5.0. New CLI, own AST fix engine, stable output, better experience Read more →

CI / CD.

aislop ci is the quality gate: same scan as local, exits non-zero when the score drops below your threshold or any error is present. Wire it wherever your CI runs.

Fastest path — let init write it

npx aislop init will ask "Add a GitHub Actions workflow?" — say yes and it drops a ready-to-run .github/workflows/aislop.yml. Commit it alongside .aislop/config.yml. That's the whole setup.

$ npx aislop init

GitHub Actions

If you'd rather hand-write it (or already have a workflow file), add this step. It's what init writes by default — self-contained, no external action dependencies:

# .github/workflows/aislop.yml
name: aislop

on:
  push:
    branches: [main]
  pull_request:

jobs:
  quality-gate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      # Exits 1 when score < ci.failBelow in .aislop/config.yml
      # or when any error-severity diagnostic is present.
      - run: npx aislop@latest ci .

No installed dependencies required on the runner — npx aislop@latest downloads the CLI on each run. If you want deterministic builds, pin a specific version (npx aislop@0.5.0 ci .) or add aislop to your devDependencies and run npx aislop ci . after npm ci.

GitLab CI

Equivalent shape:

# .gitlab-ci.yml
aislop:
  image: node:20
  script:
    - npx aislop@latest ci .
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_COMMIT_BRANCH == "main"

CircleCI

# .circleci/config.yml
version: 2.1

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

workflows:
  quality-gate:
    jobs:
      - aislop

Pre-commit hook

Run aislop on only staged files before a commit lands — catches slop before CI even sees it. Any pre-commit tool (Husky, lefthook, pre-commit.com) works.

# Husky — .husky/pre-commit
npx aislop scan --staged

--staged only scans files staged for commit, so the hook stays fast. Use aislop fix --staged in a pre-commit flow to auto-fix staged files, then re-add them.

Branch protection

Once aislop runs on every PR, make it required. In GitHub: Settings → Branches → Branch protection rules → Require status checks to pass before merging, then tick the aislop job. From that point, a PR that drops the score below ci.failBelow can't be merged without an explicit override.

This is where the quality gate becomes real. A CI check that only lints is advisory; a required status check is policy.

Exit codes

0 — score ≥ ci.failBelow and no error-severity diagnostics. CI passes.
1 — score below threshold, or at least one error-severity diagnostic. CI fails.
non-zero — other runtime failures (bad config, missing Node, etc). Check stderr.

Reading the JSON output

aislop ci emits JSON on stdout. Shape:

{
  "schemaVersion": "1",
  "cliVersion": "0.5.0",
  "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": [ ... ]
}