Skip to content

Latest commit

 

History

History
214 lines (162 loc) · 16 KB

github-action.md

File metadata and controls

214 lines (162 loc) · 16 KB

GitHub Action usage

CarlasHub/accessibility-audit-plugin is a free JavaScript Action that runs an evidence-backed accessibility pre-audit for WCAG 2.2 A/AA in CI. It uses the same site-independent engine as the editor plugins and exports an accessible self-contained HTML report, a validated Excel workbook, structured JSON, CSV, SARIF 2.1.0, screenshots, and a portable ZIP.

It is an automated testing aid, not a WCAG certification. WCAG 2.2 Level AA is the conformance target; optional AAA checks are advisory. Complete the report's human assessment before making a conformance claim.

Easiest setup: public builder

Open the public Accessibility Audit builder and follow its four focused steps: add pages, choose pages, choose a repository, then review and start. Enter one website address and review the unique same-origin pages it discovers. Likely job, category, tag, archive, utility, and query-variant pages remain visible but unchecked; the user selects the exact audit scope, up to 20 pages.

Choose Use my repository (recommended), connect GitHub, select a writable repository shared with the maintained CarlasHub GitHub App, review the setup, and choose Start accessibility audit. Visitors authorize the App and do not create an App of their own. The connector creates or updates only its managed .github/workflows/accessibility-audit.yml file and starts the Action immediately. A different workflow at the same path is never replaced. Create a repository first retains the checked pages while GitHub opens in a new tab; return to the builder, grant App access if needed, refresh repositories, and select the new repository to inject those pages and launch. Manual URL entry and Preview or download the workflow instead remain available as fallback routes.

Discovery and auditing are separate: discovery proposes pages, while the Action audits exactly the selected URLs written into the workflow and never crawls. Read the public builder guide for limits, permissions, data handling, free-plan boundaries, and recovery steps.

Minimal workflow

The shortest setup delegates the audit and report upload to the maintained reusable workflow. Add this as .github/workflows/accessibility-audit.yml in your project:

name: Accessibility audit

on:
  workflow_dispatch:

permissions:
  contents: read

jobs:
  audit:
    uses: CarlasHub/accessibility-audit-plugin/.github/workflows/reusable-accessibility-audit.yml@v1
    with:
      urls: |-
        https://example.com/
        https://example.com/contact
      exact-hosts: example.com
      max-pages: '2'

List every page under urls, one per line, then open Actions → Accessibility audit → Run workflow and start the run. Its summary links directly to one combined downloadable report. No checkout, browser installation, artifact step, token, or hostname field is required.

The reusable workflow follows the latest compatible v1 release. For release-controlled environments, use the workflow generated by the public setup builder as a model and pin referenced Actions to immutable commit SHAs.

Pull-request summaries

To create or update one audit comment, grant pull-request write access and pass the workflow token:

permissions:
  contents: read
  pull-requests: write

steps:
  - uses: CarlasHub/accessibility-audit-plugin@v1
    with:
      urls: https://preview.example.test/
      github-token: ${{ secrets.GITHUB_TOKEN }}
      comment-on-pr: 'true'

The Action uses the GitHub REST API only to list, create, or update its marked pull-request comment. When baseline-path is set, that comment also shows new, persistent, and resolved finding counts. Persistent means the same stable fingerprint appears in both audits; partial comparisons call out findings whose browser engine, URL, or viewport scope was not equivalently observed. A missing or read-only token does not discard the audit; it emits a warning and continues. Workflows triggered from forks commonly receive a read-only token.

Inputs

Input Default Purpose
urls Required Explicit HTTP(S) URLs, one per line (plain, bulleted, or numbered), or a JSON string array. Every entry is validated; the Action does not crawl.
auditor GitHub Actions Auditor name written into the workbook.
wcag-level AA WCAG 2.2 Level AA conformance target. Legacy AAA values enable advisory AAA automation but do not change the target.
aaa-advisory false Run supported AAA rules as clearly separated advisory evidence.
output-dir accessibility-audit-results Output directory, relative to the workspace unless absolute.
landing-page-url First URL Report metadata and same-origin link context; it does not expand scope.
allowed-hosts Hosts in urls Optional comma- or newline-separated hostname allowlist. Each entry authorizes that hostname and its subdomains. The Action securely derives this list from the explicit URLs when omitted.
exact-hosts Empty Optional comma- or newline-separated literal hostname allowlist. Use it when approved hosts must not authorize subdomains.
max-pages Unlimited Optional hard ceiling from 1 to 50,000 authorized, deduplicated pages. An oversized scope stops before browser startup instead of being truncated.
staging-only false Reject hosts that do not look like staging, QA, preview, test, or local hosts.
capture-screenshots true Retain contextual screenshot evidence when reproducible.
browser chromium Browser engine: chromium, firefox, or webkit. Firefox and WebKit are opt-in; Chromium remains the default.
publish-report false Reusable workflow only: explicitly publish the complete report folder as a public GitHub Pages site and expose hosted-report-url. Leave disabled for the normal access-controlled workflow artifact.
browser-channel Empty Optional installed Chromium channel such as chrome; invalid with Firefox or WebKit.
auto-install-browser true Install the selected Playwright browser when it is unavailable.
concurrency 2 Concurrent pages, from 1 to 8.
timeout-ms 30000 Per-operation timeout in milliseconds.
journeys Empty JSON array of project-specific keyboard, form, interaction, and dynamic-content journeys.
journeys-file Empty Workspace-relative JSON file containing the journey array. Check out the caller repository first when using the standalone Action. Mutually exclusive with journeys.
report-name Accessibility_Audit_Report.xlsx Excel report filename.
baseline-path Empty Workspace-relative path to a prior audit-results.json. The reusable workflow checks out the caller repository when this is set.
history-paths Empty Optional prior audit-results.json paths, one per line, for chronological HTML and workbook trends. The reusable workflow checks out the caller repository when this is set.
fail-on none none, new, blockers, confirmed, critical, serious, moderate, or minor. new requires baseline-path.
comment-on-pr true Attempt the marked pull-request summary when a token is supplied.
github-token Empty Token used only for the pull-request summary.

Project-specific task journeys

Generic automation cannot know the meaningful tasks in an application. Add a version-controlled journey file to test the exact keyboard and interaction outcomes your users depend on. With the reusable workflow, the complete job remains:

jobs:
  audit:
    uses: CarlasHub/accessibility-audit-plugin/.github/workflows/reusable-accessibility-audit.yml@v1
    with:
      urls: |-
        https://preview.example.test/
        https://preview.example.test/contact
      journeys-file: .github/a11y-journeys.json

Create .github/a11y-journeys.json in the caller repository:

[
  {
    "id": "submit-empty-contact-form",
    "title": "Receive an announced error after keyboard submission",
    "categories": ["keyboard", "forms", "dynamic-content"],
    "steps": [
      { "action": "focus", "selector": "#submit-contact" },
      { "action": "press", "key": "Enter" },
      { "action": "assert", "expectation": "invalid", "selector": "#email" },
      { "action": "assert", "expectation": "live-region-updated", "selector": "#form-errors", "value": "Email is required" }
    ]
  }
]

Supported actions are focus, press, type, wait, and assert. Assertions cover focus, visibility, expanded/pressed/selected/checked/valid states, URL and text content, input values, and scoped live-region updates. Optional urlIncludes and viewports filters keep a journey within its intended route and layout. Every journey starts from the requested URL, records its executed steps and selectors in JSON, and appears in the HTML evidence table.

Use the maintained BuggyLand pack for complete examples covering keyboard entry, form errors, custom tabs, modal focus/Escape behavior, and status messages. A passing scripted DOM journey does not establish equivalent screen-reader output or complete WCAG conformance; retain native assistive-technology and human task testing.

Quality gates

The gate boundaries are explicit and stable:

Policy The job fails when
none Never; the audit records evidence only.
new The baseline comparison identifies at least one new finding in equivalently observed scope.
blockers At least one audit blocker prevented complete coverage.
confirmed At least one finding has confirmed evidence, including an Advisory finding.
critical At least one confirmed finding is Critical.
serious At least one confirmed finding is Serious or Critical.
moderate At least one confirmed finding is Moderate, Serious, or Critical.
minor At least one confirmed finding is Minor, Moderate, Serious, or Critical.

Review and manual items never fail a severity gate because automation has not established that they are defects. Blockers fail only the blockers gate, and Advisory findings fail confirmed but do not satisfy a severity threshold. Supplying baseline-path does not change any existing gate; comparison results affect only fail-on: new.

Start with none while establishing a baseline. Move to a severity policy after the audited URLs are stable and the team has reviewed the evidence model.

To prevent regressions without making teams fix the complete backlog at once, commit a reviewed prior JSON report and enable the differential gate:

jobs:
  audit:
    uses: CarlasHub/accessibility-audit-plugin/.github/workflows/reusable-accessibility-audit.yml@v1
    with:
      urls: https://preview.example.test/
      baseline-path: .github/accessibility-baseline.json
      history-paths: |-
        reports/august/audit-results.json
        reports/september/audit-results.json
      fail-on: new

The comparison qualifies incomplete or unmatched browser-engine, URL, and viewport scope as indeterminate instead of reporting it as new or resolved. History is optional and reporting-only: paths may be listed in any order, the report sorts audits chronologically, and it does not change the existing baseline gate.

Outputs

The Action exposes output-dir, html-path, report-path, json-path, csv-path, sarif-path, archive-path, confirmed-findings, review-findings, blockers, requested-pages, audited-pages, completed-pages, partial-pages, not-started-pages, skipped-pages, and gate-result. An if: always() upload step preserves evidence even when the configured gate fails. Upload both output-dir and archive-path: the first supports direct artifact browsing, while the ZIP is the portable package to share. Download the workflow artifact and open Accessibility_Audit_Report.html first; keep the workbook, raw JSON, CSV register, SARIF results, and screenshots together for deeper analysis and automation.

Optional hosted report

Local CLI and plugin runs never upload reports. The reusable workflow normally keeps its report in the workflow artifact, governed by repository access and the configured retention period. For an audit that contains only content approved for public disclosure, it can instead publish a directly browsable GitHub Pages copy:

permissions:
  contents: read
  pages: write
  id-token: write

jobs:
  audit:
    uses: CarlasHub/accessibility-audit-plugin/.github/workflows/reusable-accessibility-audit.yml@v1
    with:
      urls: https://example.com/
      exact-hosts: example.com
      publish-report: true

Before enabling it, configure the caller repository's Pages source as GitHub Actions. The workflow stages a copy of the established report folder, makes its HTML report the site index, deploys it with permissions confined to the opt-in publish job, writes the public URL to the run summary, and returns it as the reusable workflow's hosted-report-url output. A later deployment to the same Pages site replaces the prior one.

GitHub Pages visibility depends on the caller repository and organization plan; do not assume the URL is private. Never enable publish-report for authenticated audits, private URLs, personal data, confidential screenshots, or any report not explicitly approved for its resulting Pages audience. Disabling the input again prevents future deployments but does not itself remove an already published site; unpublish or disable Pages in the repository settings when the public copy must be withdrawn.

Native screen-reader evidence

The separate Native screen-reader evidence workflow can be started from the repository's Actions tab with an explicit target URL and a bounded navigation-step count. It runs Guidepup on the native combinations it supports in CI:

  • VoiceOver with WebKit on macOS;
  • NVDA with Firefox on Windows.

Each job uploads JSON, Markdown, HTML, and Playwright artifacts containing the spoken phrase log, browser and operating-system metadata, commands performed, page structure inventory, and limitations. These scripted journeys are supplementary evidence: a qualified tester must still evaluate meaningful announcements, dynamic states, real tasks, supported product combinations, and mobile assistive technology.

Security and privacy

  • Pin third-party Actions to complete commit SHAs and grant the workflow only the permissions it needs.
  • The Action derives allowed-hosts from urls; set exact-hosts when every approved hostname must match literally, or set allowed-hosts explicitly when parent-domain-and-subdomain authorization is intended. Use max-pages to reject unexpectedly large explicit scopes before browser startup. Use staging-only: 'true' where naming conventions make it reliable.
  • Main-page redirects are checked against the same host and staging restrictions; out-of-scope destinations are rejected and are not accepted as audit results.
  • Do not put credentials, session tokens, private URLs, or secrets in urls or workflow logs.
  • Treat reports and screenshots as potentially sensitive. Set an appropriate artifact retention period and restrict repository access.
  • publish-report is deliberately off by default. Enable it only after approving the complete report for the repository's GitHub Pages audience, and disable or unpublish Pages when the hosted copy is no longer needed.
  • Do not run untrusted pull-request changes with production credentials or network access to private targets.
  • Keep manual review in the release process; no automated result proves complete WCAG conformance.

The bundled Action code and Playwright runtime are committed under action/dist so a consumer does not run npm install. Maintainers reproduce and verify that bundle with npm run build:action and npm run test:action.

The Action is designed for publicly reachable HTTP(S) pages. Sites that require authentication, CAPTCHA completion, private-network access, or anti-bot exceptions need an explicitly authorized, site-specific workflow and manual review.