GitHub Action
Scan on every push
Run a WCAG 2.2 scan when code changes, comment the result on the pull request, and fail the build when serious issues appear. Eight lines of YAML and one repository secret.
TJGaushas/accessledger-scan-action@v1
Setup
Two steps
1. Store your token
Create a token at Account, then API tokens. In your repository
go to Settings, then Secrets and variables, then Actions, and add a new repository secret
named ACCESSLEDGER_API_TOKEN.
Add it as a secret, not as a variable, and never paste it into the workflow file. A token in a committed file is public the moment the repository is, and is in the git history even after you delete the line.
2. Add the workflow
Save this as .github/workflows/accessibility.yml:
name: Accessibility
on:
push:
branches: [main]
pull_request:
permissions:
contents: read
pull-requests: write
jobs:
accessibility:
runs-on: ubuntu-latest
steps:
- uses: TJGaushas/accessledger-scan-action@v1
with:
api-token: ${{ secrets.ACCESSLEDGER_API_TOKEN }}
url: https://example.com/pricing
fail-on: serious
Change the URL to a page of your own. That is the whole setup. The next push runs a scan.
Scope
One page, or the whole site
url scans a single page and needs nothing set up first.
It is the right choice for a pull request check, because it is fast and it tests the
page you probably changed.
site-id scans every page configured for a site you have
verified you control, which is the right choice for a nightly run. Find the id in the
address bar of the site page in your account.
Send one or the other, never both. Both together is a configuration error and the Action says so rather than quietly picking one.
Inputs
Everything you can set
| Input | Required | Default | What it does |
|---|---|---|---|
api-token |
yes | Your token, from a repository secret. Never hard code it. | |
url |
no | A single page to scan. Provide this or site-id, not both. | |
site-id |
no | A verified site. Scans every page configured for it. | |
fail-on |
no | serious |
Lowest severity that fails the job: critical, serious, moderate, minor, or never. |
max-wait-seconds |
no | 300 |
How long to wait for the scan before giving up and reporting a timeout. |
comment-on-pr |
no | true |
Post a summary on the pull request, updated in place rather than added again on each push. |
github-token |
no | the workflow token | Used only to write that comment. Needs pull-requests: write. |
api-base |
no | https://theaccessledger.com/api/v1 |
Advanced. Point the Action at a different environment. |
Outputs
Using the result in later steps
| Output | What it is |
|---|---|
critical | Count of critical violations. Empty if the scan did not complete. |
serious | Count of serious violations. |
moderate | Count of moderate violations. |
minor | Count of minor violations. |
report-url | Link to the full dated record in your account. |
status | complete, service-error, quota-exceeded, timeout, or config-error. |
- uses: TJGaushas/accessledger-scan-action@v1
id: a11y
with:
api-token: ${{ secrets.ACCESSLEDGER_API_TOKEN }}
url: https://example.com
- run: echo "Serious issues: ${{ steps.a11y.outputs.serious }}"
The important part
Our outage must never look like your bug
A build that fails is a message to whoever reads it, and the worst possible version of that message is one that blames the wrong thing. So the Action separates the two cases, and you should too.
A status of complete means the
scan ran and the counts are real. Only then can the job fail for accessibility reasons,
and only when something at or above your fail-on level was
found.
service-error and timeout mean
the scan could not be completed. That is our problem, not a finding about your site. Check
the status page, which reports what is actually working at the moment
you load it.
quota-exceeded means the monthly allowance is spent, and
config-error means the inputs do not make sense, such as
both url and site-id. Neither is an accessibility result.
If you would rather never fail a build on findings and only collect the record, set
fail-on: never. The scan still runs, the comment still
appears, and the dated history still builds.
Worth doing
Two settings that save you scans
Add a concurrency group so a second push cancels the first run rather than spending two scans from your quota on the same branch:
concurrency:
group: accessibility-${{ github.ref }}
cancel-in-progress: true
And add a nightly schedule alongside the push trigger. Most accessibility regressions arrive with content rather than with code, and a content change never touches your repository at all.
on:
push:
branches: [main]
pull_request:
schedule:
- cron: '17 6 * * *'
Limits
What a passing build means
It means the automated checks found nothing at or above your threshold, on the pages they reached, on that date. Automated testing reliably detects roughly 30 to 40 percent of WCAG success criteria.
A green check is worth having and it is not a conformance statement. The value of running this on every push is the dated record it builds, which is the thing that cannot be produced afterwards when somebody asks what you have been doing about accessibility.