2026-02-18 23:09:07 +01:00

4.4 KiB

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, or Minor
  • 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

  1. Gets the list of files changed in the PR (added, changed, modified, renamed)
  2. Filters files by the file-pattern glob
  3. Reads the rules file and all matching changed files
  4. Sends everything to OpenAI with instructions to check each REQ-* rule
  5. Returns the review as the review output

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.