$npx -y skills add mgifford/accessibility-skills --skill ci-cdLoad this skill when configuring or reviewing CI/CD pipelines, GitHub Actions workflows, or automated testing setups. Ensures accessibility regressions are caught before code reaches production by enforcing quality gates, structured reporting, and layered automated + manual testi
| 1 | # CI/CD Accessibility Skill |
| 2 | |
| 3 | > **Canonical source**: `examples/CI_CD_ACCESSIBILITY_BEST_PRACTICES.md` in `mgifford/ACCESSIBILITY.md` |
| 4 | > This skill is derived from that file. When in doubt, the example is authoritative. |
| 5 | > The canonical guide states synchronization with this skill is **not automatic** |
| 6 | > — re-check this file against canonical periodically. |
| 7 | |
| 8 | Apply these rules when adding, reviewing, or maintaining CI/CD accessibility checks. |
| 9 | |
| 10 | --- |
| 11 | |
| 12 | ## Core Mandate |
| 13 | |
| 14 | CI can prevent known accessibility regressions, preserve tested semantics, and |
| 15 | produce evidence for human review. **It cannot establish WCAG conformance by |
| 16 | itself.** Automated rules, scores, snapshots, and AI output are inputs to an |
| 17 | accessibility evaluation, not substitutes for one. This guide targets WCAG 2.2 |
| 18 | AA for in-scope content — that target is not itself a conformance claim. |
| 19 | |
| 20 | Principles: test complete user tasks and relevant states, not only page loads; |
| 21 | run fast deterministic checks locally and repeat in CI; block known |
| 22 | regressions using explicit reviewable rules; keep accessibility, performance, |
| 23 | security, and functional signals distinct; test the final rendered/sanitized/ |
| 24 | optimized output; keep humans responsible for severity, alternatives, |
| 25 | exceptions, and release decisions; give workflows and agents the least |
| 26 | authority needed for their task. |
| 27 | |
| 28 | --- |
| 29 | |
| 30 | ## Severity Scale (this skill) |
| 31 | |
| 32 | | Level | Meaning | |
| 33 | | --- | --- | |
| 34 | | **Critical** | A core or safety-critical task cannot be completed and no reasonable accessible alternative exists | |
| 35 | | **Serious** | A major task is blocked or requires an unsafe, unreliable, or highly burdensome workaround | |
| 36 | | **Moderate** | A task remains possible but creates substantial difficulty, confusion, delay, or loss of information | |
| 37 | | **Minor** | Impact is limited and the task remains understandable and operable | |
| 38 | |
| 39 | **Tool labels (axe `critical`/`serious`/`moderate`/`minor`, Lighthouse scores) |
| 40 | are triage inputs, not project severity** — map them into this taxonomy only |
| 41 | after evaluating actual user impact on the affected task. |
| 42 | |
| 43 | --- |
| 44 | |
| 45 | ## A Layered Testing Model |
| 46 | |
| 47 | No single tool covers accessibility requirements. Choose layers by the |
| 48 | affected task and the likelihood/consequence of a regression: |
| 49 | |
| 50 | | Layer | Useful for | Does not establish | |
| 51 | | --- | --- | --- | |
| 52 | | Static analysis / lint | Fast feedback on detectable source patterns | Runtime behavior or final output | |
| 53 | | Unit/component tests | Stable component contracts (names, roles, states) | Whole-page reading and focus order | |
| 54 | | Browser rule scans (axe-core) | Detectable rules in rendered states | Complete WCAG coverage or usability | |
| 55 | | Semantic assertions (role queries, ARIA snapshots) | Accessibility-tree structure and changes | Exact screen-reader speech | |
| 56 | | Visual checks | Theme/layout regressions, focus indicators | Meaning, keyboard access, or text alternatives | |
| 57 | | End-to-end tests | Operability, focus, state changes, errors | AT interoperability by itself | |
| 58 | | Manual and AT testing | Quality, sequence, interaction, compatibility | Universal behavior across all configurations | |
| 59 | |
| 60 | Use `skills/manual-testing/SKILL.md` for checks automation cannot complete. |
| 61 | |
| 62 | --- |
| 63 | |
| 64 | ## Critical: Define the CI Contract Before Choosing Tools |
| 65 | |
| 66 | For each check, document: the user task/page/component/states covered; the |
| 67 | command and config file; tool/browser/runtime/rule-set versions; whether the |
| 68 | result warns, blocks, or only produces an artifact; the baseline/expected |
| 69 | result; the owner and response process for failures; known false positives |
| 70 | and untested requirements; and evidence retained for review. |
| 71 | |
| 72 | Do not describe a check as a merge gate unless branch protection actually |
| 73 | requires it. Do not describe a warning as a failure. |
| 74 | |
| 75 | **Scores are not conformance percentages.** A Lighthouse accessibility score |
| 76 | of 100 does not mean 100% WCAG conformance, and 90 does not mean a page is 90% |
| 77 | accessible — it measures the weighted audits Lighthouse ran in one |
| 78 | configuration. Use individual audit results to investigate regressions. A |
| 79 | score threshold can be an additional signal but should not be the only gate; |
| 80 | also fail on specific rules/tasks the team has decided are blocking. Keep |
| 81 | performance budgets separate — a performance score must not raise or lower |
| 82 | accessibility severity. |
| 83 | |
| 84 | ```json |
| 85 | { |
| 86 | "ci": { |
| 87 | "collect": { "staticDistDir": "./_site", "numberOfRuns": 1 }, |
| 88 | "assert": { |
| 89 | "assertions": { "categories:accessibility": ["warn", { "minScore": 0.9 }] } |
| 90 | }, |
| 91 | "upload": { "target": "filesystem", "outputDir": ".lighthouseci" } |
| 92 | } |
| 93 | } |
| 94 | ``` |
| 95 | |
| 96 | This warns; it does not block. Raising the threshold (or moving to `"error"`) |
| 97 | can be useful after investigation, |