Skip to main content
VertaaUX Docs

GitHub Actions

Comprehensive GitHub Actions workflows for VertaaUX CI/CD integration

GitHub Actions

GitHub Actions is the most popular CI platform for VertaaUX integration. This guide covers everything from basic workflows to advanced patterns with PR comments, baselines, and caching.

Basic Workflow

The simplest GitHub Actions workflow that audits on every pull request:

.github/workflows/ux-audit.yml
name: UX Audit

on:
  pull_request:
    branches: [main]
  push:
    branches: [main]

jobs:
  audit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install VertaaUX CLI
        run: npm install -g @vertaaux/cli

      - name: Run UX Audit
        run: vertaa audit -u ${{ vars.PREVIEW_URL }} --fail-on error
        env:
          VERTAA_API_KEY: ${{ secrets.VERTAA_API_KEY }}

Configure PREVIEW_URL: Go to Settings > Secrets and variables > Actions > Variables and add PREVIEW_URL with your preview deployment URL.

With Preview Deployments

Vercel Deployments

Trigger audits when Vercel deployments complete:

.github/workflows/ux-audit-vercel.yml
name: UX Audit (Vercel)

on:
  deployment_status:

jobs:
  audit:
    # Only run when deployment succeeds
    if: github.event.deployment_status.state == 'success'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install VertaaUX CLI
        run: npm install -g @vertaaux/cli

      - name: Run UX Audit
        run: |
          vertaa audit \
            -u ${{ github.event.deployment_status.target_url }} \
            --fail-on error \
            --threshold 80 \
            --format json \
            -o results.json
        env:
          VERTAA_API_KEY: ${{ secrets.VERTAA_API_KEY }}

      - name: Upload Results
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: ux-audit-results
          path: results.json

Netlify Deployments

Wait for Netlify deployment then audit:

.github/workflows/ux-audit-netlify.yml
name: UX Audit (Netlify)

on:
  pull_request:
    branches: [main]

jobs:
  audit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Wait for Netlify
        uses: jakepartusch/wait-for-netlify-action@v1.4
        id: netlify
        with:
          site_name: 'your-site-name'
          max_timeout: 300

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install VertaaUX CLI
        run: npm install -g @vertaaux/cli

      - name: Run UX Audit
        run: vertaa audit -u ${{ steps.netlify.outputs.url }} --fail-on error
        env:
          VERTAA_API_KEY: ${{ secrets.VERTAA_API_KEY }}

AWS Amplify Deployments

Get Amplify preview URL and audit:

.github/workflows/ux-audit-amplify.yml
name: UX Audit (Amplify)

on:
  pull_request:
    branches: [main]

jobs:
  audit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Configure AWS
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: us-east-1

      - name: Get Preview URL
        id: amplify
        run: |
          URL=$(aws amplify get-branch \
            --app-id ${{ vars.AMPLIFY_APP_ID }} \
            --branch-name ${{ github.head_ref }} \
            --query 'branch.displayName' \
            --output text)
          echo "url=https://$URL.${{ vars.AMPLIFY_APP_ID }}.amplifyapp.com" >> $GITHUB_OUTPUT

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install VertaaUX CLI
        run: npm install -g @vertaaux/cli

      - name: Run UX Audit
        run: vertaa audit -u ${{ steps.amplify.outputs.url }} --fail-on error
        env:
          VERTAA_API_KEY: ${{ secrets.VERTAA_API_KEY }}

PR Comments

Post audit results as a pull request comment with issue summaries and trends:

.github/workflows/ux-audit-pr.yml
name: UX Audit with PR Comment

on:
  pull_request:
    branches: [main]

jobs:
  audit:
    runs-on: ubuntu-latest
    permissions:
      pull-requests: write
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install VertaaUX CLI
        run: npm install -g @vertaaux/cli

      - name: Run UX Audit
        id: audit
        run: |
          vertaa audit \
            -u ${{ vars.PREVIEW_URL }} \
            --baseline baseline.json \
            --format json \
            -o results.json
        env:
          VERTAA_API_KEY: ${{ secrets.VERTAA_API_KEY }}
        continue-on-error: true

      - name: Generate PR Comment
        run: vertaa comment --file results.json --format github > comment.md

      - name: Post PR Comment
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            const comment = fs.readFileSync('comment.md', 'utf8');

            // Find existing VertaaUX comment
            const { data: comments } = await github.rest.issues.listComments({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: context.issue.number,
            });

            const existingComment = comments.find(c =>
              c.body.includes('<!-- vertaaux-audit -->')
            );

            if (existingComment) {
              // Update existing comment
              await github.rest.issues.updateComment({
                owner: context.repo.owner,
                repo: context.repo.repo,
                comment_id: existingComment.id,
                body: comment
              });
            } else {
              // Create new comment
              await github.rest.issues.createComment({
                owner: context.repo.owner,
                repo: context.repo.repo,
                issue_number: context.issue.number,
                body: comment
              });
            }

      - name: Check Audit Result
        if: steps.audit.outcome == 'failure'
        run: exit 1

PR Comment Format

The vertaa comment command generates markdown with:

<!-- vertaaux-audit -->
## VertaaUX Audit Results

**Score:** 85/100 (+3 from baseline)
**URL:** https://preview-abc123.vercel.app

### Summary
| Severity | Count | Change |
|----------|-------|--------|
| Error | 2 | +1 |
| Warning | 5 | -2 |
| Info | 8 | +0 |

### New Issues
1. **[WCAG-1.1.1] Image missing alt text** (error)
   `<img src="/hero.png">`

### Fixed Issues
- [WCAG-2.4.4] Link purpose now clear
- [WCAG-1.4.3] Contrast ratio improved

Baseline Management

Baselines track your current UX state so PRs are evaluated against new issues, not existing ones.

Full Baseline Workflow

.github/workflows/ux-audit-baseline.yml
name: UX Audit with Baseline

on:
  pull_request:
    branches: [main]
  push:
    branches: [main]

jobs:
  # Audit PRs against baseline
  audit-pr:
    if: github.event_name == 'pull_request'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install VertaaUX CLI
        run: npm install -g @vertaaux/cli

      - name: Run Audit with Baseline
        run: |
          vertaa audit \
            -u ${{ vars.PREVIEW_URL }} \
            --baseline baseline.json \
            --max-new-errors 0 \
            --max-new-warnings 5 \
            --fail-on error
        env:
          VERTAA_API_KEY: ${{ secrets.VERTAA_API_KEY }}

  # Update baseline on merge to main
  update-baseline:
    if: github.event_name == 'push'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          token: ${{ secrets.GITHUB_TOKEN }}

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install VertaaUX CLI
        run: npm install -g @vertaaux/cli

      - name: Update Baseline
        run: |
          vertaa baseline \
            -u ${{ vars.PRODUCTION_URL }} \
            --update baseline.json
        env:
          VERTAA_API_KEY: ${{ secrets.VERTAA_API_KEY }}

      - name: Commit Baseline
        run: |
          git config user.name "GitHub Actions"
          git config user.email "actions@github.com"
          git add baseline.json
          git diff --staged --quiet || git commit -m "chore: update UX baseline"
          git push

Baseline Flags

FlagDescription
--baseline <file>Path to baseline file for comparison
--max-new-errors <n>Fail if more than n new errors
--max-new-warnings <n>Fail if more than n new warnings
--max-regressions <n>Fail if more than n rules got worse

Matrix Strategy

Audit multiple URLs in parallel:

.github/workflows/ux-audit-matrix.yml
name: UX Audit (Multi-URL)

on:
  pull_request:
    branches: [main]

jobs:
  audit:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        page:
          - { name: 'Home', path: '/' }
          - { name: 'Pricing', path: '/pricing' }
          - { name: 'Docs', path: '/docs' }
          - { name: 'Dashboard', path: '/dashboard' }
      fail-fast: false
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install VertaaUX CLI
        run: npm install -g @vertaaux/cli

      - name: Audit ${{ matrix.page.name }}
        run: |
          vertaa audit \
            -u "${{ vars.PREVIEW_URL }}${{ matrix.page.path }}" \
            --fail-on error \
            --format json \
            -o results-${{ matrix.page.name }}.json
        env:
          VERTAA_API_KEY: ${{ secrets.VERTAA_API_KEY }}

      - name: Upload Results
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: ux-audit-${{ matrix.page.name }}
          path: results-${{ matrix.page.name }}.json

Caching

Speed up workflows by caching the CLI installation:

.github/workflows/ux-audit-cached.yml
name: UX Audit (Cached)

on:
  pull_request:
    branches: [main]

jobs:
  audit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Cache npm global
        uses: actions/cache@v4
        with:
          path: ~/.npm
          key: vertaaux-cli-${{ runner.os }}

      - name: Install VertaaUX CLI
        run: npm install -g @vertaaux/cli

      - name: Run UX Audit
        run: vertaa audit -u ${{ vars.PREVIEW_URL }} --fail-on error
        env:
          VERTAA_API_KEY: ${{ secrets.VERTAA_API_KEY }}

Environment Variables

VariableRequiredDescription
VERTAA_API_KEYYesYour API key (set as secret)
PREVIEW_URLVariesPreview deployment URL (set as variable or use deployment event)
PRODUCTION_URLVariesProduction URL for baseline updates

Full Production Workflow

A complete workflow combining all features:

.github/workflows/ux-audit-complete.yml
name: UX Audit (Complete)

on:
  deployment_status:
  push:
    branches: [main]

jobs:
  # Audit preview deployments
  audit-preview:
    if: |
      github.event_name == 'deployment_status' &&
      github.event.deployment_status.state == 'success'
    runs-on: ubuntu-latest
    permissions:
      pull-requests: write
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Cache npm global
        uses: actions/cache@v4
        with:
          path: ~/.npm
          key: vertaaux-cli-${{ runner.os }}

      - name: Install VertaaUX CLI
        run: npm install -g @vertaaux/cli

      - name: Run Audit
        id: audit
        run: |
          vertaa audit \
            -u ${{ github.event.deployment_status.target_url }} \
            --baseline baseline.json \
            --max-new-errors 0 \
            --fail-on error \
            --format json \
            -o results.json
        env:
          VERTAA_API_KEY: ${{ secrets.VERTAA_API_KEY }}
        continue-on-error: true

      - name: Generate and Post Comment
        if: github.event.deployment.environment == 'Preview'
        uses: actions/github-script@v7
        with:
          script: |
            const { execSync } = require('child_process');
            const fs = require('fs');

            execSync('vertaa comment --file results.json --format github > comment.md');
            const comment = fs.readFileSync('comment.md', 'utf8');

            // Find the PR for this deployment
            const prs = await github.rest.pulls.list({
              owner: context.repo.owner,
              repo: context.repo.repo,
              state: 'open',
              head: `${context.repo.owner}:${context.payload.deployment.ref}`
            });

            if (prs.data.length > 0) {
              await github.rest.issues.createComment({
                owner: context.repo.owner,
                repo: context.repo.repo,
                issue_number: prs.data[0].number,
                body: comment
              });
            }

      - name: Upload Results
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: ux-audit-results
          path: results.json

      - name: Fail if Audit Failed
        if: steps.audit.outcome == 'failure'
        run: exit 1

  # Update baseline on main
  update-baseline:
    if: github.event_name == 'push' && github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          token: ${{ secrets.GITHUB_TOKEN }}

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install VertaaUX CLI
        run: npm install -g @vertaaux/cli

      - name: Update Baseline
        run: vertaa baseline -u ${{ vars.PRODUCTION_URL }} --update baseline.json
        env:
          VERTAA_API_KEY: ${{ secrets.VERTAA_API_KEY }}

      - name: Commit Baseline
        run: |
          git config user.name "GitHub Actions"
          git config user.email "actions@github.com"
          git add baseline.json
          git diff --staged --quiet || git commit -m "chore: update UX baseline [skip ci]"
          git push

Troubleshooting

Deployment URL Not Available

If github.event.deployment_status.target_url is empty:

- name: Debug deployment
  run: |
    echo "Event: ${{ github.event_name }}"
    echo "State: ${{ github.event.deployment_status.state }}"
    echo "URL: ${{ github.event.deployment_status.target_url }}"

Permission Denied on Comment

Add permissions to the job:

jobs:
  audit:
    permissions:
      pull-requests: write

Rate Limited

Check remaining quota before audit:

- name: Check Quota
  run: vertaa quota
  env:
    VERTAA_API_KEY: ${{ secrets.VERTAA_API_KEY }}

Was this page helpful?

On this page