Start here

CI Integration

The CLI is built for headless environments. A single command crawls a staging URL, writes a JUnit report, and exits non-zero when findings breach a threshold — everything a CI pipeline needs to gate a deploy on SEO regressions.

The pattern

Every CI integration follows the same shape:

consuela <URL> \
  --format junit --output results.xml \
  --fail-on critical --quiet

--format junit produces XML that CI systems read natively — most will render it as a test report tab with no extra tooling. --output results.xml writes the report to a file so it can be uploaded as a build artifact. --fail-on critical sets the exit code: the step fails when any finding at or above the given severity is present. --quiet suppresses progress output on stderr so build logs stay clean.

--db is optional in CI. Without it, results live in memory for the duration of the run and are discarded after the report is written. This is faster and avoids writing a database file to ephemeral CI storage. Pass --db only if you need to inspect the crawl later in a desktop session.

GitHub Actions

Add two steps to your workflow: one to run the audit, and one to upload the report. The upload step uses if: always() so the report is available even when the audit finds issues and the first step exits non-zero.

- name: SEO audit
  run: |
    consuela https://staging.example.com \
      --format junit --output results.xml \
      --fail-on warning --quiet
- name: Upload results
  if: always()
  uses: actions/upload-artifact@v4
  with:
    name: seo-results
    path: results.xml

GitHub Actions parses JUnit XML automatically when it appears in an uploaded artifact. The workflow run will show a test report summary alongside the build logs.

GitLab CI

GitLab consumes JUnit reports through the artifacts:reports:junit keyword. Declare the output file and GitLab renders findings on the merge request and pipeline pages.

seo-audit:
  script:
    - consuela https://staging.example.com --format junit --output results.xml --fail-on warning --quiet
  artifacts:
    reports:
      junit: results.xml

Because GitLab collects artifacts even from failed jobs by default, the JUnit report is available whether the audit passes or fails.

Exit codes in CI

The CLI uses three exit codes. Understanding each one matters in CI because a pipeline must distinguish between "audit ran and found problems" and "audit did not run at all."

Code Meaning Pipeline action
0 Crawl completed, no findings at or above the threshold. Pass the step.
1 Findings at or above the threshold were found. Fail the step. Review the JUnit report for details.
2 The crawl itself failed — network error, bad URL, or zero pages fetched. Treat as a pipeline failure, not a passing audit.

Exit code 2 deserves particular attention. An empty crawl — zero pages fetched — also exits 2, which prevents a false-green result when the staging environment is unreachable or the URL is misconfigured. Without this, a DNS failure would look like a clean audit.

--fail-on controls which severity level triggers exit code 1. Use --fail-on critical for a lenient gate that only blocks on the most serious findings. Use --fail-on warning for stricter pipelines that treat any warning as a regression. The default is none, which always exits 0 on a successful crawl regardless of findings.