AI based Accessibility Review Action
A Gitea/GitHub Action that reviews modified files against a markdown rules document using OpenAI, and outputs the review as markdown for posting as a PR comment.
The action extracts files changed in a pull request, filters them by a glob pattern, sends them along with an accessibility rules file to OpenAI for analysis, and returns the review result as an output.
Usage
name: Accessibility review
on:
pull_request:
paths:
- 'src/**/*.tsx'
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- id: ai-review
uses: https://gitea.dsv.su.se/stne3960/ai-review-action@v1
with:
openai-api-key: ${{ secrets.OPENAI_API_KEY }}
rules-file: AI_REVIEW.md
file-pattern: 'src/**/*.tsx'
- name: Post review comment
uses: actions/github-script@v7
if: steps.ai-review.outputs.review != ''
env:
REVIEW: ${{ steps.ai-review.outputs.review }}
with:
script: |
const review = process.env.REVIEW;
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `## Accessibility Review\n\n${review}`
})
Inputs
| Input | Required | Default | Description |
|---|---|---|---|
openai-api-key |
Yes | - | OpenAI API key |
rules-file |
Yes | - | Path to the accessibility rules markdown file |
file-pattern |
No | **/*.tsx |
Glob pattern for filtering changed files |
model |
No | gpt-4o |
OpenAI model to use |
Outputs
| Output | Description |
|---|---|
review |
The accessibility review result in markdown. Empty string if no matching files were changed. |
Rules File
The action expects a markdown file with structured requirements. Each requirement needs an ID, WCAG reference, severity, and a check description.
Format
# Accessibility Review Rules
## Output Format
For each requirement violation found, report using this exact structure:
VIOLATION: <REQ-ID>
FILE: <file path>
LINE: <line number or range>
SEVERITY: Critical | Major | Minor
WCAG: <SC number>
DESCRIPTION: <specific description of the violation>
FIX: <concrete suggested fix>
## Requirements
REQ-IMG-001: All `<img>` elements must have an `alt` attribute.
- WCAG: 1.1.1
- Severity: Critical
- Check: Every `<img>` has `alt`. No missing `alt` attributes.
REQ-KBD-001: All interactive elements must be operable with keyboard alone.
- WCAG: 2.1.1
- Severity: Critical
- Check: Interactive elements use `<button>`, `<a>`, `<input>`, `<select>`,
or have `tabIndex={0}` with `onKeyDown`/`onKeyUp` handlers.
REQ-FORM-002: Error messages must be programmatically associated with their input.
- WCAG: 3.3.1
- Severity: Major
- Check: Error text elements have an `id`, and the input has
`aria-describedby` pointing to that `id`.
REQ-ARIA-006: Elements with no visible label must have an accessible name.
- WCAG: 4.1.2
- Severity: Critical
- Check: Focusable elements without visible text have `aria-label`
or `aria-labelledby`.
Structure
Each requirement follows this pattern:
- ID - Unique identifier like
REQ-IMG-001,REQ-KBD-001,REQ-FORM-002 - WCAG - The success criterion number (e.g.
1.1.1,2.1.1) - Severity -
Critical,Major, orMinor - Check - Concrete instructions for what the AI should look for in code
The output format section tells the AI how to structure its response. The AI will use the requirement IDs and check descriptions to analyze the code.
Secrets
Add these as repository secrets:
- OPENAI_API_KEY - Your OpenAI API key
How It Works
- Gets the list of files changed in the PR (added, changed, modified, renamed)
- Filters files by the
file-patternglob - Reads the rules file and all matching changed files
- Sends everything to OpenAI with instructions to check each REQ-* rule
- Returns the review as the
reviewoutput
The action itself does not post comments or set commit statuses. This is left to the workflow so you can customize how results are presented.
Development
npm install
npm run build # bundles src/index.js into dist/index.js with ncc
The dist/index.js file must be committed - it is what the action runner executes.