Automated WCAG 2.2 accessibility review for pull requests using LLMs (Gemini or Ollama Cloud).
- Catches Accessibility Issues Early — Reviews PR diffs for WCAG 2.2 A/AA violations before merge
- Context-Aware Analysis — Hybrid file detection analyzes React, Vue, Django, WordPress, and more
- Actionable Feedback — Provides exact code fixes, not just problem descriptions
- Developer-Friendly — Integrates directly into GitHub PR workflow
- Flexible Deployment — Use Gemini or Ollama Cloud APIs with self-hosted options
- Security-First — Built-in secret detection with Gitleaks prevents leaking credentials
ax-review is a GitHub Action that:
- Triggers on pull request events (opened, synchronized, reopened)
- Fetches PR file diffs
- Detects and redacts secrets using Gitleaks
- Filters for web-relevant files (HTML, CSS, JSX, TSX, Vue, PHP, etc.)
- Analyzes code with your chosen LLM for WCAG 2.2 compliance
- Posts results as Check Runs (recommended) or PR comments
- Optionally fails the workflow on violations
In addition to pull request accessibility reviews, ax-review also supports full rendered-page accessibility auditing through a companion GitHub Actions workflow.
The URL audit workflow uses:
- Axe-core + Playwright for browser-rendered WCAG violations
- Lighthouse for accessibility scoring and audits
- Pa11y for additional WCAG2AA validation
It supports scanning:
- Direct URLs
- CSV files containing URLs
- sitemap.xml files (including nested sitemaps)
The workflow generates:
- Consolidated Markdown accessibility reports
- Highlighted element screenshots
- GitHub Actions artifacts
- Optional GitHub issue creation for tracking
This complements PR diff analysis by validating the fully rendered deployed experience after deployment.
┌──────────────────────────────────────────────────────────────────────────────┐
│ GitHub Actions Runtime │
│ │
│ ┌──────────────────────────────────────────────────────────────────────┐ │
│ │ Trigger: PR Event │ │
│ └──────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────────────────┐ │
│ │ 1. Input Validation │ │
│ │ - Token/Provider/API Key │ │
│ │ - Configuration Options │ │
│ └──────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────────────────┐ │
│ │ 2. Fetch PR Metadata │ │
│ │ - Draft Status → Skip? │ │
│ │ - Head SHA for Reviews │ │
│ │ - Pagination (100/page) │ │
│ └──────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────────────────┐ │
│ │ 3. Secret Detection (Gitleaks) │ │
│ │ - Scan All Diffs │ │
│ │ - Redact Secrets → [REDACTED] │ │
│ │ - Block on Leak Detection │ │
│ └──────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────────────────┐ │
│ │ 4. Hybrid File Detection │ │
│ │ ┌─────────────────────────────────────────────────┐ │ │
│ │ │ Markup Extensions (Always Analyze) │ │ │
│ │ │ html, jsx, tsx, vue, svelte, astro │ │ │
│ │ │ css, scss, sass, php, blade, erb, mdx │ │ │
│ │ └─────────────────────────────────────────────────┘ │ │
│ │ ┌─────────────────────────────────────────────────┐ │ │
│ │ │ Ambiguous Extensions (Content Scan) │ │ │
│ │ │ js, ts, mjs, cjs, py, rb, java │ │ │
│ │ │ → Check for JSX, templates, inline styles │ │ │
│ │ └─────────────────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────────────────┐ │
│ │ 5. Batch Processing │ │
│ │ - Split into 20-file batches │ │
│ │ - Add [N] position markers │ │
│ │ - Estimate tokens (chars/4) │ │
│ └──────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────────────────┐ │
│ │ 6. LLM Analysis │ │
│ │ ┌─────────────────────┬─────────────────────┐ │ │
│ │ │ Gemini │ Ollama │ │ │
│ │ │ - JSON Schema │ - Bearer Token │ │ │
│ │ │ - 0.1 Temperature │ - format: 'json' │ │ │
│ │ │ - Safety Filters │ - num_ctx: 32768 │ │ │
│ │ └─────────────────────┴─────────────────────┘ │ │
│ │ - WCAG 2.2 System Prompt │ │
│ │ - JSON Response Validation │ │
│ └──────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────────────────┐ │
│ │ 7. Completeness Verification │ │
│ │ - Count <img>, <input>, <button> │ │
│ │ - Check against reported issues │ │
│ │ - Log warnings for gaps │ │
│ └──────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────────────────┐ │
│ │ 8. Post Results │ │
│ │ ┌─────────────────────┬─────────────────────┐ │ │
│ │ │ Check Runs │ PR Comments │ │ │
│ │ │ (Recommended) │ (Alternative) │ │ │
│ │ │ - Max 50 annot. │ - Inline reviews │ │ │
│ │ │ - Branch status │ - Files Changed │ │ │
│ │ │ - Clean UI │ - Direct feedback │ │ │
│ │ └─────────────────────┴─────────────────────┘ │ │
│ └──────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────────────────┐ │
│ │ 9. Set Outputs │ │
│ │ - issues-found: Total count │ │
│ │ - violations: CRITICAL + SERIOUS │ │
│ │ - good-practices: MODERATE + MINOR │ │
│ └──────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────────────────┐ │
│ │ 10. Workflow Result (if fail-on-issues: true) │ │
│ │ - Fail if violations > 0 │ │
│ │ - Pass if only good practices │ │
│ └──────────────────────────────────────────────────────────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────────────────────┘
Add your API key to repository secrets:
- Gemini:
GEMINI_API_KEY(Get from Google AI Studio) - Ollama:
OLLAMA_API_KEY(Get from Ollama Cloud Settings)
Create .github/workflows/a11y-review.yml for a minimal code review worfklow with Gemini (Checkout Usage Examples for full platform (Code Review + URL Audit) workflow and other variations):
name: Accessibility Review
on:
pull_request:
types: [opened, synchronize, reopened]
jobs:
a11y-review:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
checks: write
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Gitleaks
run: |
curl -sSfL https://github.com/gitleaks/gitleaks/releases/download/v8.21.2/gitleaks_8.21.2_linux_x64.tar.gz | tar -xz
sudo mv gitleaks /usr/local/bin/gitleaks
gitleaks version
- name: Run Accessibility Review
uses: your-org/ax-review@v1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
llm-provider: gemini
api-key: ${{ secrets.GEMINI_API_KEY }}The action automatically runs when you create or update a pull request.
- GitHub repository with Actions enabled
- API key for your chosen LLM provider
Navigate to: Settings → Secrets and variables → Actions → New repository secret
For Gemini:
- Name:
GEMINI_API_KEY - Value: Your API key from Google AI Studio
For Ollama:
- Name:
OLLAMA_API_KEY - Value: Your API key from Ollama Cloud Settings
Create .github/workflows/a11y-review.yml with your preferred configuration (see Usage Examples).
The workflow needs these permissions:
permissions:
contents: read # Read repository files
pull-requests: write # Post PR comments
checks: write # Create Check RunsTo require the review to pass:
- Go to
Settings→Branches→Branch protection rules - Add rule for your main branch
- Enable "Require status checks to pass before merging"
- Select "Accessibility Review" check
If you're running your own Ollama server:
- name: Run Accessibility Review
uses: your-org/ax-review@v1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
llm-provider: ollama
api-key: ${{ secrets.OLLAMA_API_KEY }}
ollama-url: ${{ secrets.OLLAMA_SERVER_URL }}| Input | Required | Default | Description |
|---|---|---|---|
github-token |
Yes | ${{ github.token }} |
GitHub API token for PR operations |
llm-provider |
Yes | gemini |
LLM provider: gemini or ollama |
api-key |
Yes* | — | API key for LLM provider (Required for both Gemini and Ollama) |
model |
No | Provider default | Model name (e.g., gemini-2.0-flash, minimax-m2.7:cloud) |
ollama-url |
No | https://ollama.com |
Ollama Cloud or self-hosted server URL |
output-mode |
No | checks |
Output format: checks (recommended) or comments |
fail-on-issues |
No | true |
Fail workflow on VIOLATION issues |
max-files |
No | 100 |
Maximum files to analyze (0 for unlimited) |
batch-size |
No | 20 |
Files per LLM request |
skip-drafts |
No | true |
Skip analysis for draft PRs |
a11y-findings-dir |
No | — | Path to accessibility findings generated by external tools |
* Note: api-key is required for both Gemini and Ollama Cloud. The Ollama free tier no longer supports anonymous access.
| Provider | Default Model | Recommended Alternatives |
|---|---|---|
| Gemini | gemini-3-flash-preview |
gemini-2.5-pro, gemini-2.5-flash |
| Ollama | minimax-m2.7:cloud |
kimi-k2.5:cloud, glm-5:cloud |
| Output | Description |
|---|---|
issues-found |
Total number of issues detected |
violations |
Count of CRITICAL + SERIOUS issues (WCAG failures) |
good-practices |
Count of MODERATE + MINOR issues (recommendations) |
The examples/ directory contains ready-to-use workflow configurations for both PR-based AI review and rendered-page URL auditing.
| File | Use Case |
|---|---|
examples/a11y-review.yml |
Unified workflow combining PR review + URL audit |
examples/a11y-code-review.yml |
Standalone PR-based accessibility review |
examples/a11y-url-audit.yml |
Standalone rendered-page accessibility URL audit |
| File | Use Case |
|---|---|
examples/variations/minimal-gemini.yml |
Quick start with Gemini defaults |
examples/variations/minimal-ollama.yml |
Quick start with Ollama Cloud |
examples/variations/production-checks.yml |
Check Runs (recommended for production) |
examples/variations/production-comments.yml |
PR Comments (alternative for direct feedback) |
examples/variations/comprehensive.yml |
All configuration options documented |
examples/variations/large-repo.yml |
Optimized for large PRs (200+ files) |
examples/variations/monorepo.yml |
Monorepo setups with multiple apps |
examples/variations/self-hosted-ollama.yml |
Self-hosted Ollama server |
examples/variations/a11y-url-audit.yml |
Standalone rendered-page accessibility URL audit |
examples/variations/a11y-review.yml |
Unified workflow combining PR review + URL audit |
This single workflow supports both:
- Code Review Mode: Automatically reviews pull requests
- URL Audit Mode: Manually audits deployed URLs, CSVs, or sitemap.xml files
name: Accessibility Review
on:
pull_request:
types: [opened, synchronize, reopened]
workflow_dispatch:
inputs:
input-type:
description: "Input type: urls | csv | sitemap"
required: true
default: "urls"
type: choice
options:
- urls
- csv
- sitemap
urls:
description: "URLs, CSV path, or sitemap URL(s)"
required: true
default: "https://example.com"
jobs:
code-review:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
checks: write
steps:
- uses: actions/checkout@v6
- name: Install Gitleaks
run: |
curl -sSfL https://github.com/gitleaks/gitleaks/releases/download/v8.18.4/gitleaks_8.18.4_linux_x64.tar.gz | tar -xz
sudo mv gitleaks /usr/local/bin/gitleaks
- name: Run Accessibility Review
uses: rtCamp/ax-review@v1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
llm-provider: ollama
model: gpt-oss:120b-cloud
api-key: ${{ secrets.OLLAMA_API_KEY }}
output-mode: checks
fail-on-issues: true
url-audit:
if: github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
permissions:
contents: read
issues: write
steps:
# URL audit workflow steps
# See examples/a11y-url-audit.ymlname: Accessibility Review
on:
pull_request:
types: [opened, synchronize, reopened]
jobs:
a11y-review:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
checks: write
steps:
- uses: actions/checkout@v6
- name: Install Gitleaks
run: |
curl -sSfL https://github.com/gitleaks/gitleaks/releases/download/v8.18.4/gitleaks_8.18.4_linux_x64.tar.gz | tar -xz
sudo mv gitleaks /usr/local/bin/gitleaks
- uses: rtCamp/ax-review@v1.0.3
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
llm-provider: gemini
api-key: ${{ secrets.GEMINI_API_KEY }}Check Runs provide cleaner UI integration and work with branch protection rules:
- uses: rtCamp/ax-review@v1.0.3
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
llm-provider: gemini
api-key: ${{ secrets.GEMINI_API_KEY }}
model: gemini-2.0-flash
output-mode: checks
fail-on-issues: true
max-files: 100
batch-size: 20For repos with many files per PR:
- uses: rtCamp/ax-review@v1.0.3
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
llm-provider: gemini
api-key: ${{ secrets.GEMINI_API_KEY }}
max-files: 200 # Higher limit
batch-size: 30 # Larger batchesUse this workflow when you want to audit rendered pages after deployment.
Supports:
- Direct URL input
- CSV files committed to the repository
- sitemap.xml crawling (including nested sitemaps)
name: Accessibility URL Audit
on:
workflow_dispatch:
inputs:
input-type:
description: "Input type: urls | csv | sitemap"
required: true
default: "urls"
type: choice
options:
- urls
- csv
- sitemap
urls:
description: "URLs, CSV path, or sitemap URL(s)"
required: true
default: "https://example.com"
jobs:
a11y:
runs-on: ubuntu-latest
permissions:
contents: read
issues: write
steps:
# Axe-core + Playwright
# Lighthouse
# Pa11y
# Markdown report generation
# Screenshot artifacts
# GitHub issue creation| Input Type | Input |
|---|---|
URLs (urls) |
https://example.com,https://example.com/about |
CSV File (csv) |
.github/a11y-urls.csv (with url/urls column in case of mutli column file) |
Sitemap (sitemap) |
https://example.com/sitemap.xml (automatically resolves nested sitemaps) |
Creates Check Run annotations visible in the "Checks" tab:
output-mode: checksAdvantages:
- Cleaner PR interface
- Works with branch protection rules
- Grouped by file
- Supports
failureandnoticeseverity levels - Max 50 annotations per run
Best for: Production repositories, team workflows, branch protection enforcement.
Posts inline review comments on the "Files Changed" tab:
output-mode: commentsAdvantages:
- Direct visibility on changed lines
- No limit on comment count (besides API limits)
- Conversations can be threaded
- Suggested fixes shown inline
Best for: Smaller teams, quick iteration, direct code discussion.
ax-review analyzes code for WCAG 2.2 A/AA compliance across these criteria:
| Criterion | Level | What We Check | Learn More |
|---|---|---|---|
| 1.1.1 Non-text Content | A | Missing alt on images, ARIA labels on icons |
WCAG 1.1.1 |
| 1.3.1 Info and Relationships | A | Semantic HTML, headings, landmarks, lists | WCAG 1.3.1 |
| 1.4.3 Contrast (Minimum) | AA | 4.5:1 for normal text, 3:1 for large text | WCAG 1.4.3 |
| 1.4.11 Non-text Contrast | AA | 3:1 contrast for UI components | WCAG 1.4.11 |
| Criterion | Level | What We Check | Learn More |
|---|---|---|---|
| 2.1.1 Keyboard | A | All interactive elements reachable by keyboard | WCAG 2.1.1 |
| 2.4.4 Link Purpose | A | Descriptive link text, aria-label on links |
WCAG 2.4.4 |
| 2.4.7 Focus Visible | AA | Visible focus indicators, focus styles | WCAG 2.4.7 |
| Criterion | Level | What We Check | Learn More |
|---|---|---|---|
| 3.3.2 Labels or Instructions | A | Form labels, input descriptions, error messages | WCAG 3.3.2 |
| Criterion | Level | What We Check | Learn More |
|---|---|---|---|
| 4.1.2 Name, Role, Value | A | ARIA attributes, custom component accessibility | WCAG 4.1.2 |
Issues are classified by impact on users:
| Level | Impact | Description | Examples |
|---|---|---|---|
| CRITICAL | Blocks Access | User cannot complete the task at all | Missing alt on critical image, form without submit button, keyboard trap |
| SERIOUS | Significant Barrier | Task is possible but very difficult | 3:1 contrast ratio (should be 4.5:1), missing focus indicator, generic link text ("click here") |
| MODERATE | Frustrating | Works but confusing | Skipped heading level, missing field descriptions, placeholder-only labels |
| MINOR | Enhancement | Beyond WCAG minimum | Enhanced focus styles, skip links, additional ARIA labels |
Only CRITICAL and SERIOUS issues cause workflow failure when fail-on-issues: true.
MODERATE and MINOR issues are posted as recommendations but won't block your PR.
ax-review/
├── action.yml # GitHub Action definition
├── package.json # Dependencies and scripts
├── tsconfig.json # TypeScript configuration
├── src/
│ ├── index.ts # Entry point
│ ├── orchestrator.ts # Workflow coordination
│ ├── types.ts # Core type definitions
│ ├── constants.ts # Configuration constants
│ ├── inputs.ts # Input parsing and validation
│ ├── llm/
│ │ ├── index.ts # Client factory
│ │ ├── types.ts # LLM interfaces
│ │ ├── base.ts # Abstract client with retry logic
│ │ ├── gemini.ts # Google Gemini client
│ │ └── ollama.ts # Ollama Cloud client
│ ├── github/
│ │ ├── client.ts # GitHub API wrapper
│ │ ├── pr.ts # PR file fetching
│ │ ├── comments.ts # Review comment formatting
│ │ └── checks.ts # Check Run creation
│ ├── prompts/
│ │ └── a11y-prompt.ts # WCAG 2.2 system/user prompts
│ ├── security/
│ │ └── gitleaks.ts # Secret detection and redaction
│ ├── utils/
│ │ ├── batching.ts # File batch creation
│ │ ├── file-utils.ts # Hybrid file detection
│ │ ├── findings.ts # External a11y findings ingestion
│ │ ├── validation.ts # Input validation (SSRF, injection)
│ │ ├── element-counter.ts # Completeness verification
│ │ └── context.ts # GitHub context extraction
│ └── output.ts # Result posting logic
├── dist/
│ └── index.js # Compiled action (esbuild)
└── examples/ # Workflow examples
| Module | Responsibility |
|---|---|
orchestrator.ts |
Coordinates analysis workflow across all modules |
llm/base.ts |
Shared retry logic, JSON parsing, error handling for all providers |
prompts/a11y-prompt.ts |
WCAG 2.2 expert system prompt, injection detection, escaping |
security/gitleaks.ts |
Secret detection, redaction, process cleanup |
utils/file-utils.ts |
Hybrid detection (markup always, ambiguous content scan) |
ax-review uses a two-tier file detection system:
Tier 1: Always Analyze Files with markup extensions are always processed:
- HTML:
.html,.htm,.xhtml - React:
.jsx,.tsx - Vue:
.vue - Svelte:
.svelte - Astro:
.astro - CSS:
.css,.scss,.sass,.less,.styl - Templates:
.php,.blade.php,.erb,.ejs,.hbs,.twig,.liquid - Docs:
.md,.mdx
Tier 2: Content Scan
Files with ambiguous extensions (.js, .ts, .mjs, .cjs, .py, .rb, .java) are scanned for:
- JSX components (
<Button,<div, React patterns) - Vue directives (
v-if,v-for) - Angular directives (
ng-if,ng-for) - Template tags (
{{ }},{% %},<?php) - Inline styles (
style={})
This ensures React components in .js files and Django templates in .py files are analyzed.
BaseLLMClient (abstract)
├── executeWithRetry() // Exponential backoff (3 retries)
├── parseJsonResponse() // JSON extraction and validation
└── sleep() // Utility
│
├── GeminiClient
│ ├── analyze() // Google Generative AI SDK
│ ├── validateConfig()
│ └── isRateLimitError()
│
└── OllamaClient
├── analyze() // Ollama SDK (format: 'json')
├── validateConfig()
└── handleError()
Adding a new provider:
- Create
src/llm/new-provider.tsimplementingLLMClient - Add to
src/llm/index.tsfactory - Add type to
LLMProviderinsrc/types.ts
| Layer | Protection |
|---|---|
| Input Validation | SSRF protection (no private IPs), command injection prevention, length limits |
| Secret Detection | Gitleaks scans all diffs, redacts secrets to [REDACTED], blocks on detection |
| Prompt Injection | Pattern detection for malicious prompts, escaping of special characters |
| API Keys | Never logged, passed via GitHub secrets only |
- Node.js 20+
- npm or yarn
git clone https://github.com/your-org/ax-review
cd ax-review
npm install# Build for production
npm run build
# Type checking
npm run typecheck
# Run tests
npm test
# Local development
npm run dev| Package | Purpose |
|---|---|
@actions/core |
GitHub Actions input/output, logging |
@actions/github |
Octokit wrapper for GitHub API |
@google/generative-ai |
Gemini API client |
ollama |
Ollama Cloud API client |
The test suite covers:
- Input validation (SSRF, injection, length)
- File filtering (markup, ambiguous)
- LLM response parsing (JSON extraction, schema validation)
- Diff position mapping
- Secret redaction
npm test
# Run specific test file
npm test -- --testPathPattern=validation
# Coverage report
npm test -- --coverageax-review integrates Gitleaks to prevent sensitive data from being sent to LLM APIs:
# Install Gitleaks in your workflow
- name: Install Gitleaks
run: |
curl -sSfL https://github.com/gitleaks/gitleaks/releases/download/v8.21.2/gitleaks_8.21.2_linux_x64.tar.gz | tar -xz
sudo mv gitleaks /usr/local/bin/gitleaks
gitleaks versionHow it works:
- Scans all PR file diffs before sending to LLM
- Detects 200+ secret types (API keys, tokens, passwords)
- Redacts secrets to
[REDACTED]in the analysis - Blocks workflow if secrets cannot be safely redacted
- Never commit API keys to the repository
- Use GitHub repository secrets for all credentials
- Keys are loaded at runtime via
${{ secrets.* }} - Not logged or included in error messages
The action uses the default GITHUB_TOKEN with minimal scope:
permissions:
contents: read # Read repository files (checkout)
pull-requests: write # Create PR reviews/comments
checks: write # Create Check RunsAll inputs are validated to prevent injection attacks:
ollama-url: HTTP/HTTPS only, blocks private IPs (SSRF)model: Alphanumeric characters, dots, dashes, underscores, colons onlyapi-key: Length validation, control character detection- File paths: Path traversal prevention, character sanitization
Problem: Both Gemini and Ollama Cloud now require API keys.
Solution: Ensure api-key input is provided:
api-key: ${{ secrets.GEMINI_API_KEY }} # or
api-key: ${{ secrets.OLLAMA_API_KEY }}For Ollama Cloud, get your key from ollama.com/settings/keys.
Problem: gitleaks: command not found
Solution: Install Gitleaks in your workflow:
- name: Install Gitleaks
run: |
curl -sSfL https://github.com/gitleaks/gitleaks/releases/download/v8.21.2/gitleaks_8.21.2_linux_x64.tar.gz | tar -xz
sudo mv gitleaks /usr/local/bin/gitleaks
gitleaks versionProblem: Action runs but no Check Run appears.
Solution: Ensure the workflow has checks: write permission:
permissions:
contents: read
pull-requests: write
checks: write # Required for Check RunsProblem: Action completes with "0 issues found" but you know there are a11y problems.
Possible causes:
- File extension not detected —
.jsfiles with JSX need content scanning - Issue on unchanged lines — Only added lines (+ prefix) are analyzed
- Draft PR skipped — Set
skip-drafts: falseto analyze drafts
Solution: Check the action logs for file detection details.
Problem: 429 Resource Exhausted or quota errors.
Solution:
- Reduce
batch-sizeto process fewer files per request - Wait and retry (action has automatic retry with backoff)
- Upgrade your Gemini API quota
Problem: Cannot connect to self-hosted Ollama server.
Solution:
- Verify the server URL is accessible from GitHub Actions runners
- Ensure the URL scheme is
http://orhttps:// - Check firewall rules for the server
ollama-url: ${{ secrets.OLLAMA_SERVER_URL }}Problem: "Found 0 files to analyze" in logs.
Possible causes:
- All files filtered by
shouldSkipFile(node_modules, minified files) max-fileslimit too low- No web-relevant files in the PR
Solution: Check what file patterns are being skipped in the logs.
Enable verbose logging in GitHub Actions:
- name: Run Accessibility Review
uses: your-org/ax-review@v1
env:
ACTIONS_STEP_DEBUG: true
with:
# ... your configThis shows:
- File filtering decisions
- LLM request/response (without secrets)
- Batch processing details
- Position mapping for comments
- Check this troubleshooting section
- Review GitHub Issues for similar problems
- Open a new issue with:
- Workflow YAML (redact secrets)
- Full action logs
- PR file types being analyzed
MIT License
Copyright (c) 2024
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
We welcome contributions! Here's how to get started:
- Fork the repository
- Clone your fork:
git clone https://github.com/your-username/ax-review - Install dependencies:
npm install - Create a feature branch:
git checkout -b feature/my-feature
- Code Style: Follow existing TypeScript conventions
- Tests: Add tests for new functionality
- Documentation: Update README.md and TECHNICAL_SPEC.md
- Commits: Use conventional commit messages
# Run all tests
npm test
# Type checking
npm run typecheck
# Build
npm run build- Ensure all tests pass:
npm test && npm run typecheck - Update documentation for changed behavior
- Add entries to CHANGELOG.md
- Submit PR with description of changes
Use GitHub Issues for:
- Bug reports
- Feature requests
- Documentation improvements
Please include:
- Steps to reproduce
- Expected vs actual behavior
- Workflow YAML (redact secrets)
- Action logs
Built with ❤️ for accessible web development.