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."
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.