Skip to content

Repository files navigation

ax-review

Version License: MIT Node.js

Automated WCAG 2.2 accessibility review for pull requests using LLMs (Gemini or Ollama Cloud).

Why ax-review?

  • 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

Overview

ax-review is a GitHub Action that:

  1. Triggers on pull request events (opened, synchronized, reopened)
  2. Fetches PR file diffs
  3. Detects and redacts secrets using Gitleaks
  4. Filters for web-relevant files (HTML, CSS, JSX, TSX, Vue, PHP, etc.)
  5. Analyzes code with your chosen LLM for WCAG 2.2 compliance
  6. Posts results as Check Runs (recommended) or PR comments
  7. Optionally fails the workflow on violations

URL Audit Mode

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.

How It Works

┌──────────────────────────────────────────────────────────────────────────────┐
│                           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                  │   │
│  └──────────────────────────────────────────────────────────────────────┘   │
│                                                                              │
└──────────────────────────────────────────────────────────────────────────────┘

Quick Start

1. Add Secrets

Add your API key to repository secrets:

2. Create Workflow

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 }}

3. Open a PR

The action automatically runs when you create or update a pull request.

Installation

Prerequisites

  • GitHub repository with Actions enabled
  • API key for your chosen LLM provider

Step-by-Step Setup

1. Add API Key to Secrets

Navigate to: SettingsSecrets and variablesActionsNew repository secret

For Gemini:

For Ollama:

2. Create Workflow File

Create .github/workflows/a11y-review.yml with your preferred configuration (see Usage Examples).

3. Grant Permissions

The workflow needs these permissions:

permissions:
  contents: read        # Read repository files
  pull-requests: write  # Post PR comments
  checks: write         # Create Check Runs

4. Configure Branch Protection (Optional)

To require the review to pass:

  1. Go to SettingsBranchesBranch protection rules
  2. Add rule for your main branch
  3. Enable "Require status checks to pass before merging"
  4. Select "Accessibility Review" check

Self-Hosted Ollama Setup

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 }}

Configuration

Inputs

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.

Default Models

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

Outputs

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)

Usage Examples

The examples/ directory contains ready-to-use workflow configurations for both PR-based AI review and rendered-page URL auditing.

Core Examples:

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

Alternative variations:

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

Unified Platform Workflow (Recommended)

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.yml

Minimal Setup (Gemini)

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:
      - 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 }}

Production Setup (Check Runs)

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: 20

Large Repository Setup

For 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 batches

Standalone URL Audit Workflow

Use 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

URL Audit Input Examples

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)

Output Modes

Check Runs (Recommended)

Creates Check Run annotations visible in the "Checks" tab:

output-mode: checks

Advantages:

  • Cleaner PR interface
  • Works with branch protection rules
  • Grouped by file
  • Supports failure and notice severity levels
  • Max 50 annotations per run

Best for: Production repositories, team workflows, branch protection enforcement.

PR Comments

Posts inline review comments on the "Files Changed" tab:

output-mode: comments

Advantages:

  • 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.

WCAG Criteria

ax-review analyzes code for WCAG 2.2 A/AA compliance across these criteria:

Perceivable (1.x)

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

Operable (2.x)

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

Understandable (3.x)

Criterion Level What We Check Learn More
3.3.2 Labels or Instructions A Form labels, input descriptions, error messages WCAG 3.3.2

Robust (4.x)

Criterion Level What We Check Learn More
4.1.2 Name, Role, Value A ARIA attributes, custom component accessibility WCAG 4.1.2

Severity Levels

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

Failure Behavior

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.

Architecture

Project Structure

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

Key Modules

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)

Hybrid File Detection

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.

LLM Client Architecture

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:

  1. Create src/llm/new-provider.ts implementing LLMClient
  2. Add to src/llm/index.ts factory
  3. Add type to LLMProvider in src/types.ts

Security Model

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

Development

Prerequisites

  • Node.js 20+
  • npm or yarn

Setup

git clone https://github.com/your-org/ax-review
cd ax-review
npm install

Commands

# Build for production
npm run build

# Type checking
npm run typecheck

# Run tests
npm test

# Local development
npm run dev

Project Dependencies

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

Testing

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 -- --coverage

Security

Secret Detection

ax-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 version

How it works:

  1. Scans all PR file diffs before sending to LLM
  2. Detects 200+ secret types (API keys, tokens, passwords)
  3. Redacts secrets to [REDACTED] in the analysis
  4. Blocks workflow if secrets cannot be safely redacted

API Key Handling

  • 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

Minimal Permissions

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 Runs

Input Validation

All inputs are validated to prevent injection attacks:

  • ollama-url: HTTP/HTTPS only, blocks private IPs (SSRF)
  • model: Alphanumeric characters, dots, dashes, underscores, colons only
  • api-key: Length validation, control character detection
  • File paths: Path traversal prevention, character sanitization

Troubleshooting

Common Issues

"API key is required" Error

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.

Gitleaks Not Found

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 version

Check Run Not Created

Problem: 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 Runs

No Issues Found But You Expected Some

Problem: Action completes with "0 issues found" but you know there are a11y problems.

Possible causes:

  1. File extension not detected.js files with JSX need content scanning
  2. Issue on unchanged lines — Only added lines (+ prefix) are analyzed
  3. Draft PR skipped — Set skip-drafts: false to analyze drafts

Solution: Check the action logs for file detection details.

Rate Limit Errors (Gemini)

Problem: 429 Resource Exhausted or quota errors.

Solution:

  1. Reduce batch-size to process fewer files per request
  2. Wait and retry (action has automatic retry with backoff)
  3. Upgrade your Gemini API quota

Self-Hosted Ollama Connection Failed

Problem: Cannot connect to self-hosted Ollama server.

Solution:

  1. Verify the server URL is accessible from GitHub Actions runners
  2. Ensure the URL scheme is http:// or https://
  3. Check firewall rules for the server
ollama-url: ${{ secrets.OLLAMA_SERVER_URL }}

No Files to Analyze

Problem: "Found 0 files to analyze" in logs.

Possible causes:

  1. All files filtered by shouldSkipFile (node_modules, minified files)
  2. max-files limit too low
  3. No web-relevant files in the PR

Solution: Check what file patterns are being skipped in the logs.

Debugging

Enable verbose logging in GitHub Actions:

- name: Run Accessibility Review
  uses: your-org/ax-review@v1
  env:
    ACTIONS_STEP_DEBUG: true
  with:
    # ... your config

This shows:

  • File filtering decisions
  • LLM request/response (without secrets)
  • Batch processing details
  • Position mapping for comments

Getting Help

  1. Check this troubleshooting section
  2. Review GitHub Issues for similar problems
  3. Open a new issue with:
    • Workflow YAML (redact secrets)
    • Full action logs
    • PR file types being analyzed

License

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.

Contributing

We welcome contributions! Here's how to get started:

Development Setup

  1. Fork the repository
  2. Clone your fork: git clone https://github.com/your-username/ax-review
  3. Install dependencies: npm install
  4. Create a feature branch: git checkout -b feature/my-feature

Making Changes

  1. Code Style: Follow existing TypeScript conventions
  2. Tests: Add tests for new functionality
  3. Documentation: Update README.md and TECHNICAL_SPEC.md
  4. Commits: Use conventional commit messages

Running Tests

# Run all tests
npm test

# Type checking
npm run typecheck

# Build
npm run build

Pull Request Process

  1. Ensure all tests pass: npm test && npm run typecheck
  2. Update documentation for changed behavior
  3. Add entries to CHANGELOG.md
  4. Submit PR with description of changes

Reporting Issues

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.

About

Automated WCAG 2.2 accessibility review for pull requests using LLMs (Gemini or Ollama Cloud).

Resources

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages