CI/CD-Integration

Fügen Sie Ihrer Deployment-Pipeline Barrierefreiheitsprüfungen hinzu. AllyProof kann Pull Requests, die WCAG-Verstöße einführen, blockieren oder davor warnen und so Regressionen abfangen, bevor sie in die Produktion gelangen.

Einen API-Schlüssel erstellen

Gehen Sie zu Einstellungen > API-Schlüssel und klicken Sie auf Schlüssel erstellen. Geben Sie ihm einen aussagekräftigen Namen (z. B. github-actions-ci) und kopieren Sie den Schlüssel sofort – er wird nur einmal angezeigt.

Speichern Sie den Schlüssel als Secret in Ihrer CI-Umgebung:

  • GitHub Actions: Settings > Secrets > ALLYPROOF_API_KEY
  • GitLab CI: Settings > CI/CD > Variables > ALLYPROOF_API_KEY

Der Scan-Endpunkt

Lösen Sie einen Scan aus, indem Sie eine POST-Anfrage an die Scan-API senden. Die Website muss bereits in Ihrem AllyProof-Dashboard hinzugefügt und verifiziert sein.

POST https://allyproof.com/api/v1/scan
x-api-key: <API_KEY>
Content-Type: application/json

{
  "url": "https://example.com",
  "threshold": 85,
  "wait": true,
  "max_pages": 20,
  "source": "github_actions"
}

Anfrageparameter

FeldTypErforderlichBeschreibung
urlstring (URL)JaDie verifizierte Website-URL, die gescannt werden soll.
thresholdnumber (0–100)NeinMindest-Score zum Bestehen. Standard: 0 (besteht immer).
waitbooleanNeinBei true hält die Verbindung offen, bis der Scan abgeschlossen ist (bis zu 270 s, danach wird eine poll_url zurückgegeben). Nur für kleine Websites geeignet – bevorzugen Sie asynchron + Polling. Standard: false.
max_pagesnumber (1–100)NeinMaximale Anzahl zu scannender Seiten. Wenn weggelassen, werden alle gefundenen Seiten bis zum konfigurierten Limit der Website gescannt.
sourcestringNeinWelches System den Scan ausgelöst hat. Erscheint in der Spalte „Quelle“ im Scan-Verlauf der Website. Standard: api.

Die Quelle benennen

Der Scan-Verlauf listet jeden Scan einer Website auf – aus dem Dashboard, aus geplanten Läufen, aus der CLI, aus den MCP-Werkzeugen und aus Ihren Pipelines. source ist das, was eine Release-Prüfung davon unterscheidet, dass drei Wochen später jemand auf „Jetzt scannen“ geklickt hat.

Zulässig sind github_actions, gitlab_ci, jenkins, circleci, bitbucket, azure_pipelines, other_ci. Gebräuchliche Schreibweisen wie github oder gitlab werden angenommen und normalisiert; alles Unbekannte fällt auf api zurück, statt die Anfrage scheitern zu lassen – ein Tippfehler in einer Workflow-Datei kann also niemals einen Build brechen.

Warum Sie es angeben müssen. Die Beispiele unten rufen curl innerhalb Ihres Runners auf, und curl gibt sich als curl zu erkennen – die Identität des Runners erreicht uns nie. Wir fragen lieber nach, als zu raten und Ihre GitLab-Pipeline als GitHub zu kennzeichnen. Die CLI ist die Ausnahme: Sie liest GITHUB_ACTIONS, GITLAB_CI, JENKINS_URL und Verwandte aus der Umgebung und meldet die richtige Quelle selbständig – allyproof scan in einer Pipeline braucht dafür keine Konfiguration.

Hinweis: Der API-Schlüssel wird über den x-api-key-Header übergeben, nicht über den Authorization-Header.

Antwortformate

Synchron (wait: true)

Wenn wait auf true steht, hält die API die Verbindung offen, bis der Scan abgeschlossen ist, und gibt Ergebnisse direkt zurück. Nur für kleine Websites empfohlen: Eine lange offene HTTP-Verbindung kann von Proxys und Unternehmens-Gateways getrennt werden, bevor der Scan fertig ist. Nutzen Sie für CI-Pipelines das asynchrone Muster unten – auslösen, dann mit kurzen Anfragen abfragen.

{
  "pass": true,
  "score": 92,
  "threshold": 85,
  "scan_id": "scan-uuid",
  "site": { "name": "My Site", "url": "https://example.com" },
  "summary": {
    "pages_scanned": 12,
    "pages_failed": 0,
    "total_violations": 3,
    "critical": 0,
    "serious": 1,
    "moderate": 2,
    "minor": 0
  },
  "duration_ms": 14200,
  "top_violations": [
    {
      "rule_id": "color-contrast",
      "impact": "serious",
      "description": "Elements must meet minimum color contrast ratio thresholds",
      "pages_affected": 3
    }
  ],
  "pages": [
    { "url": "example.com/", "violations": 1, "critical": 0 },
    { "url": "example.com/about", "violations": 2, "critical": 0 }
  ],
  "dashboard_url": "https://allyproof.com/sites/site-uuid"
}

Asynchron (Standard)

Ohne wait: true antwortet die API sofort mit einer Scan-ID und einer Poll-URL. Die Antwort hat den HTTP-Status 202 Accepted.

{
  "scan_id": "scan-uuid",
  "status": "pending",
  "poll_url": "/api/v1/scan?id=scan-uuid",
  "message": "Scan started. Poll the poll_url for results, or use wait=true to block."
}

Um Ergebnisse abzufragen, rufen Sie die in der Antwort mitgelieferte URL mit demselben API-Schlüssel auf:

GET https://allyproof.com/api/v1/scan?id=scan-uuid
x-api-key: <API_KEY>

Konfiguration des Schwellenwerts

Der Parameter threshold legt den minimal akzeptablen Barrierefreiheits-Score fest. Nach Abschluss des Scans:

  • Liegt der Score auf oder über dem Schwellenwert, enthält die Antwort "pass": true
  • Liegt der Score unter dem Schwellenwert, enthält die Antwort "pass": false

Nutzen Sie dies in Ihrem CI-Skript, um zu entscheiden, ob der Pipeline-Schritt besteht oder fehlschlägt. Ein Schwellenwert von 85 ist für die meisten Websites ein vernünftiger Ausgangspunkt. Erhöhen Sie ihn schrittweise, während Sie bestehende Verstöße beheben.

Beispiel für GitHub Actions

Speichern Sie dies als .github/workflows/accessibility.yml:

name: Accessibility Check

on:
  pull_request:
    branches: [main]

jobs:
  a11y-scan:
    runs-on: ubuntu-latest
    steps:
      - name: Run AllyProof scan
        id: scan
        run: |
          RESPONSE=$(curl -s -X POST \
            https://allyproof.com/api/v1/scan \
            -H "x-api-key: ${{ secrets.ALLYPROOF_API_KEY }}" \
            -H "Content-Type: application/json" \
            -d '{
              "url": "${{ vars.SITE_URL }}",
              "wait": true,
              "threshold": 85,
              "source": "github_actions"
            }')

          SCORE=$(echo "$RESPONSE" | jq -r '.score')
          PASS=$(echo "$RESPONSE" | jq -r '.pass')
          VIOLATIONS=$(echo "$RESPONSE" | jq -r '.summary.total_violations')
          URL=$(echo "$RESPONSE" | jq -r '.dashboard_url')

          echo "score=$SCORE" >> "$GITHUB_OUTPUT"
          echo "pass=$PASS" >> "$GITHUB_OUTPUT"
          echo "violations=$VIOLATIONS" >> "$GITHUB_OUTPUT"
          echo "url=$URL" >> "$GITHUB_OUTPUT"

      - name: Comment on PR
        if: always()
        uses: actions/github-script@v7
        with:
          script: |
            const score = '${{ steps.scan.outputs.score }}';
            const violations = '${{ steps.scan.outputs.violations }}';
            const url = '${{ steps.scan.outputs.url }}';
            const passed = '${{ steps.scan.outputs.pass }}' === 'true';
            const emoji = passed ? '✅' : '❌';

            github.rest.issues.createComment({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: context.issue.number,
              body: `${emoji} **AllyProof Scan**\n\nScore: **${score}/100** | Violations: **${violations}**\n\n[View full report](${url})`
            });

      - name: Fail if below threshold
        if: steps.scan.outputs.pass == 'false'
        run: |
          echo "Accessibility score ${{ steps.scan.outputs.score }} is below threshold"
          exit 1

Beispiel für GitLab CI

Speichern Sie dies als .gitlab-ci.yml:

accessibility:
  stage: test
  image: alpine:latest
  before_script:
    - apk add --no-cache curl jq
  script:
    - |
      RESPONSE=$(curl -s -X POST \
        https://allyproof.com/api/v1/scan \
        -H "x-api-key: $ALLYPROOF_API_KEY" \
        -H "Content-Type: application/json" \
        -d "{
          \"url\": \"$SITE_URL\",
          \"wait\": true,
          \"threshold\": 85,
          \"source\": \"gitlab_ci\"
        }")

      SCORE=$(echo "$RESPONSE" | jq -r '.score')
      PASS=$(echo "$RESPONSE" | jq -r '.pass')

      echo "Accessibility Score: $SCORE/100"

      if [ "$PASS" = "false" ]; then
        echo "Score below threshold – failing pipeline"
        exit 1
      fi
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"

Bewährte Praktiken

  • Führen Sie Scans bei Pull Requests aus, nicht nur beim Merge nach main – erkennen Sie Regressionen frühzeitig.
  • Beginnen Sie mit einem niedrigen Schwellenwert (z. B. 70) und erhöhen Sie ihn schrittweise, während Sie bestehende Verstöße beheben.
  • Nutzen Sie max_pages, um den Scan-Umfang für schnellere CI-Läufe zu begrenzen.
  • Richten Sie E-Mail-Benachrichtigungen als Backup ein, damit Stakeholder Ergebnisse sehen, auch wenn sie CI nicht prüfen.
  • Nutzen Sie die dashboard_url in PR-Kommentaren, damit Entwickler direkt zum vollständigen Bericht springen können.

Einschränkungen

  • Automatisiertes Scannen erkennt verbreitete WCAG-2.2-AA-Fehlermuster, nicht jeden Fehler – ein grüner Build ist kein Konformitätsergebnis. Kriterien, die menschliches Urteilsvermögen erfordern (z. B. aussagekräftiger Alt-Text, logische Lesereihenfolge), werden gar nicht getestet.
  • Scans mit wait: true liefern nach 270 Sekunden eine poll_url, falls der Scan noch läuft. Nutzen Sie für alles außer kleinen Websites den asynchronen Modus mit Polling.
  • Die Website muss in Ihrem AllyProof-Dashboard verifiziert sein, bevor die API sie scannen kann.