Intégration CI

Des modèles prêts à copier qui encapsulent la CLI (npx @surea11y/cli scan ...) dans GitHub Actions, Bitbucket Pipelines, GitLab CI et Azure DevOps. Si vous appelez la bibliothèque directement depuis votre propre script Node plutôt que via la CLI, consultez plutôt INTEGRATION.md : cette page porte spécifiquement sur la CLI utilisée comme étape de pipeline.

La CLI analyse du HTML statique : elle n’exécute pas le JavaScript de la page. Cela convient aux pages générées ou rendues côté serveur ; pour une application rendue côté client, ou pour les règles qui ont besoin de la mise en page, analysez plutôt dans un navigateur avec l’un des bindings de navigateur.

Tous reposent sur les codes de sortie de la CLI (0 si aucun fail, 1 s’il y a au moins un résultat fail (ou au moins un nouveau avec --baseline), 2 en cas d’erreur d’utilisation ou d’analyse) pour contrôler le pipeline ; aucun script supplémentaire n’est nécessaire pour un contrôle réussite/échec de base. Un pipeline au vert signifie qu’aucune vérification n’a échoué, ou qu’aucune nouvelle n’a échoué. Ce n’est pas une déclaration de conformité, et les constats cantTell ne le font pas échouer.

GitHub Actions

Base : contrôle par le code de sortie

name: Accessibility scan
on: [pull_request]
 
jobs:
a11y-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm ci && npm run build # produce whatever static HTML you're scanning
- run: npx @surea11y/cli scan ./dist/index.html

Le job échoue dès qu’un résultat fail est trouvé. Pour un site existant qui comporte déjà des violations, utilisez la variante avec baseline ci-dessous plutôt que de désactiver l’étape.

Avec une baseline (site existant, contrôle uniquement sur les nouvelles violations)

# Once, locally: record every current fail occurrence, commit the file.
$ surea11y scan ./dist/index.html --write-baseline a11y-baseline.json
$ git add a11y-baseline.json
- run: npm ci && npm run build
- run: npx @surea11y/cli scan ./dist/index.html --baseline a11y-baseline.json

Une baseline empêche les violations connues de faire échouer le build ; elle ne les rend pas acceptables. Corrigez-les et réduisez le fichier au fil du temps. Voir Baseline / allowlist pour ce qui compte comme « connu » ou « nouveau », et pour régénérer le fichier au fil des corrections.

Envoyer le SARIF vers GitHub Code Scanning

upload-sarif nécessite la permission security-events: write et ne fait pas échouer le job lui-même : associez-le à une étape de contrôle distincte (ou à continue-on-error et votre propre vérification) si vous voulez aussi que le build échoue sur les nouvelles violations.

Les constats qui penchent vers l’échec sont par défaut des alertes warning. Rendus avec renderSarifReport(result, { leanFailAs: 'error' }) depuis @surea11y/core/sarif, ce sont des error, si bien qu’un contrôle sur les erreurs s’arrête aussi sur les échecs probables (options SARIF) ; une baseline écrite avec buildBaselineEntries(result, { leanFail: true }) accepte ceux qu’une page a déjà (constats qui penchent vers l’échec).

name: Accessibility scan
on: [pull_request]
 
permissions:
contents: read
security-events: write
 
jobs:
a11y-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm ci && npm run build
- name: Scan (report, don't fail the job here)
run: npx @surea11y/cli scan ./dist/index.html --baseline a11y-baseline.json --sarif results.sarif
continue-on-error: true
id: scan
- name: Upload SARIF to Code Scanning
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: results.sarif
- name: Fail the job on new violations
if: steps.scan.outcome == 'failure'
run: exit 1

Voir le format du rapport SARIF, ainsi qu’une limite connue : l’analyse d’un fichier local de votre checkout produit des annotations en ligne dans l’interface de Code Scanning, celle d’une URL en ligne non (SARIF/Code Scanning ne peut associer un résultat qu’à un vrai fichier du dépôt).

Bitbucket Pipelines

Bitbucket Pipelines n’a pas de tableau de bord intégré exploitant SARIF équivalent à GitHub Code Scanning ; le point d’intégration pratique est donc le code de sortie de la CLI (plus, éventuellement, --html comme artefact de pipeline téléchargeable) plutôt que --sarif.

pipelines:
pull-requests:
'**':
- step:
name: Accessibility scan
image: node:22
script:
- npm ci
- npm run build
- npx @surea11y/cli scan ./dist/index.html --baseline a11y-baseline.json --html a11y-report.html
artifacts:
- a11y-report.html

L’étape fait échouer le pipeline selon le code de sortie de la CLI, exactement comme toute autre entrée script ; a11y-report.html (voir le rapport HTML) est joint comme artefact de build téléchargeable, pour qu’un relecteur puisse l’ouvrir sans relancer l’analyse en local.

Rapports de tests JUnit

GitLab, Azure DevOps, Jenkins et CircleCI affichent le JUnit XML dans leurs propres vues de tests : chaque critère WCAG devient une suite et chaque règle un test (voir le rapport JUnit). La CLI l’écrit avec --junit <path> (@surea11y/cli 1.1.0 ou ultérieure), à partir de la même analyse que ses autres sorties, et le rapport ne change jamais son code de sortie : l’étape contrôle donc toujours le build.

GitLab CI

a11y:
image: node:22
script:
- npm ci
- npm run build
- npx @surea11y/cli scan ./dist/index.html --junit a11y.junit.xml
artifacts:
when: always
reports:
junit: a11y.junit.xml

when: always envoie le rapport même quand le code de sortie de l’analyse fait échouer le job, c’est-à-dire précisément quand le widget de la merge request mérite d’être lu.

Azure DevOps

steps:
- script: |
npm ci
npm run build
npx @surea11y/cli scan ./dist/index.html --junit a11y.junit.xml
displayName: Accessibility scan
- task: PublishTestResults@2
condition: succeededOrFailed()
inputs:
testResultsFormat: JUnit
testResultsFiles: a11y.junit.xml

Les règles cantTell arrivent sous forme de tests ignorés, jamais d’échecs. Avec --baseline, les échecs déjà présents dans la baseline sont aussi des tests ignorés. Pour afficher les règles cantTell comme des échecs, la CLI n’a pas d’option : enregistrez l’analyse avec --json et produisez le rapport avec renderJunitReport(result, { cantTellAs: 'failure' }) depuis @surea11y/core/junit (voir le rapport JUnit), ce qui demande @surea11y/core dans les devDependencies du projet lui-même. { leanFailAs: 'failure' } est le choix le plus étroit : seuls les constats cantTell qui penchent vers l’échec deviennent des échecs, chacun avec sa raison et les étapes pour le confirmer. L’un comme l’autre modifie le rapport, pas le code de sortie de la CLI.

Limites de minutes des offres gratuites et dépôts privés

Si l’offre gratuite de votre fournisseur de pipelines est limitée en minutes (celle de Bitbucket Pipelines est par exemple de 50 minutes de build par mois sur les espaces de travail privés), une analyse basée sur jsdom de HTML statique ou rendu côté serveur (ce que fait la CLI) coûte bien moins cher que de piloter un vrai navigateur ; voir la documentation de la CLI pour ce à quoi vous renoncez (pas de contenu rendu côté client, pas de vraie mise en page CSS).