GitHub Action — accessibility scan + VPAT auto-update
The Wholisphere Scan action runs the agent against your site (sitemap or URL list), submits findings to your org’s scan history, and optionally fails the build when WCAG conformance regresses since the last scan. The next render of your VPAT (POST /v1/vpat) reflects the new findings immediately — no manual re-issue.
Quick start
name: Accessibility scan
on: push: branches: [main] pull_request:
jobs: scan: runs-on: ubuntu-latest steps: - uses: wholisphere/scanner-runner@v0 with: api-key: ${{ secrets.WHOLISPHERE_API_KEY }} product-name: Acme App product-version: ${{ github.sha }} sitemap: https://acme.test/sitemap.xmlThat’s it. The action installs @wholisphere.ai/scanner-runner, walks your sitemap, runs the agent’s reference evaluators against each page, and submits findings.
Add regression gating
To fail the build when conformance regresses since the previous scan:
- uses: wholisphere/scanner-runner@v0 with: api-key: ${{ secrets.WHOLISPHERE_API_KEY }} product-name: Acme App product-version: ${{ github.sha }} sitemap: https://acme.test/sitemap.xml fail-on-regression: 'true'The action looks up your most recent completed scan for the same product, compares findings via GET /v1/scans/:id/diff, and exits non-zero when any criterion regressed (e.g., Supports → Partially Supports or Partially Supports → Does Not Support).
Scanning a fixed URL list
Use urls instead of sitemap:
- uses: wholisphere/scanner-runner@v0 with: api-key: ${{ secrets.WHOLISPHERE_API_KEY }} product-name: Acme App product-version: ${{ github.sha }} urls: | https://acme.test/ https://acme.test/pricing https://acme.test/aboutNewlines and commas are both accepted. URLs must be absolute (http:// or https://).
Inputs
| Input | Required | Description |
|---|---|---|
api-key | yes | Wholisphere API key (issue from Dashboard → Keys → Create) |
base-url | no | Backend base URL. Default https://api.wholisphere.ai. |
product-name | conditional | Required when scan-id is omitted. |
product-version | conditional | Required when scan-id is omitted. Often ${{ github.sha }}. |
scan-id | conditional | Append to an existing scan instead of creating one. |
sitemap | conditional | Sitemap URL — pick this OR urls. |
urls | conditional | Newline- or comma-separated URLs — pick this OR sitemap. |
build-ref | no | Defaults to ${{ github.sha }}. |
max-concurrency | no | Parallel page count. Default 3. |
fail-on-regression | no | When 'true', fail the workflow on any regression vs the previous scan. Default 'false'. |
runner-version | no | Pin a specific @wholisphere.ai/scanner-runner version. Default latest. |
Outputs
| Output | Description |
|---|---|
scan-id | The scan that was created or appended to. |
page-count | Pages successfully scanned. |
finding-count | Total findings emitted. |
What the workflow summary looks like
The action writes a step summary to your workflow run page:
Wholisphere Scan
Metric Value Scan ID abc123def456Pages scanned 24 Findings emitted 87 Build ref a3f2c91…Regression check — Compared scan
abc123againstxyz789— 0 criterion(s) regressed.
Combining with the VPAT
After every successful scan, you can render the latest VPAT directly:
curl -X POST https://api.wholisphere.ai/v1/vpat \ -H "x-api-key: $WHOLISPHERE_API_KEY" \ -H "accept: text/html" \ -d '{ "product": { "productName": "Acme App", "productVersion": "1.4.2", "vendorName": "Acme Inc.", "contactInfo": "a11y@acme.test", "reportDate": "2026-04-26", "productDescription": "An ordering app.", "standards": ["WCAG 2.2 Level AA"], "edition": "INT" }, "findings": [] }' > vpat.htmlThe findings array can be empty — the route auto-pulls the latest scan’s findings. The generated VPAT reflects only what the scan found; nothing is derived, measured, or inferred from an agent, and open issues are disclosed rather than filled in.
See also
- CLI and the OpenAPI 3.1 spec — for non-GitHub CI systems
- VPAT generator + approval workflow — the next step after a scan