CI連携

CLI(npx @surea11y/cli scan ...)をGitHub Actions、Bitbucket Pipelines、GitLab CI、Azure DevOpsで実行する、そのまま貼り付けられるテンプレートです。CLIではなく自分のNodeスクリプトからライブラリーを直接呼び出す場合は、INTEGRATION.mdを参照してください。このページが扱うのは、パイプラインのステップとしてのCLIに限られます。

CLIは静的なHTMLをスキャンし、ページのJavaScriptは実行しません。ビルド済みのページやサーバーでレンダリングされたページには適していますが、クライアントサイドでレンダリングされるアプリや、レイアウトを必要とするルールには、代わりにいずれかのブラウザーのバインディングでブラウザー内でスキャンしてください。

いずれのテンプレートも、パイプラインのゲートにはCLI自体の終了コードを使います(0は失敗となる判定結果なし、1はfailの判定結果が1件以上、--baselineを付けた場合は新しいfailが1件以上、2は使い方の誤りまたはスキャンのエラー)。基本的な合否のゲートに、追加のスクリプトは必要ありません。パイプラインが成功したということは、どのチェックも(または新しいチェックが1つも)不合格にならなかったということです。適合性を主張するものではなく、cantTellの検出結果でパイプラインが失敗することもありません。

GitHub Actions

基本:終了コードでゲートする

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

failの判定結果が1つでも見つかった時点でジョブが失敗します。すでに違反を抱えている既存サイトでは、このステップを無効にするのではなく、以下のベースラインを使う例を参照してください。

ベースラインを使う(既存サイトで、新しい違反だけをゲートの対象にする)

# 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

ベースラインは既知の違反でビルドが失敗しないようにするもので、それらを許容できるものにするわけではありません。違反を修正し、時間をかけてファイルを小さくしていってください。何が「既知」で何が「新規」とみなされるか、違反の修正に合わせてファイルを再生成する方法については、ベースライン/許可リストを参照してください。

SARIFをGitHub Code Scanningにアップロードする

upload-sarifにはsecurity-events: writeの権限が必要で、それ自体はジョブを失敗させません。新しい違反でビルドも失敗させたい場合は、別のゲート用ステップ(またはcontinue-on-errorと独自のチェック)と組み合わせてください。

不合格寄りの検出結果は、既定ではwarningのアラートです。@surea11y/core/sarifのrenderSarifReport(result, { leanFailAs: 'error' })で出力するとerrorになるため、エラーで止めるゲートは不合格の可能性が高いものでも止まります(SARIFのオプション)。buildBaselineEntries(result, { leanFail: true })で書いたベースラインは、ページにすでにあるものを受け入れます(不適合の可能性が高い検出結果)。

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

SARIFレポートの形式と、既知の制限事項も確認してください。チェックアウトしたローカルファイルをスキャンした場合はCode ScanningのUIにインラインの注釈が付きますが、公開中のURLをスキャンした場合は付きません(SARIF/Code Scanningが検出結果を関連付けられるのは、リポジトリ内の実在するファイルだけです)。

Bitbucket Pipelines

Bitbucket Pipelinesには、GitHub Code Scanningに相当するSARIF対応の組み込みダッシュボードがありません。そのため、実用的な連携ポイントは--sarifではなく、CLIの終了コード(と、必要に応じてダウンロード可能なパイプラインの成果物としての--html)になります。

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

このステップは、ほかのscriptのエントリーとまったく同じように、CLIの終了コードでパイプラインを失敗させます。a11y-report.html(HTMLレポートを参照)はダウンロード可能なビルド成果物として添付されるので、レビュー担当者はローカルでスキャンを再実行せずにレポートを開けます。

JUnitのテストレポート

GitLab、Azure DevOps、Jenkins、CircleCIは、JUnit XMLをそれぞれのテストビューに表示します。WCAGの達成基準がスイートに、ルールがテストになります(JUnitレポートを参照)。CLIは--junit <path>(1.1.0以降の@surea11y/cli)で、ほかの出力と同じスキャンからそれを書き出します。レポートが終了コードを変えることはないため、このステップは引き続きビルドをゲートします。

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を指定すると、スキャンの終了コードでジョブが失敗した場合にもレポートをアップロードします。マージリクエストのウィジェットを読む価値があるのは、まさにそのときです。

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

cantTellのルールは、失敗ではなくスキップされたテストとして表示されます。--baselineを付けた場合は、ベースラインにある不合格もスキップされたテストになります。cantTellのルールを失敗として表示するCLIのフラグはありません。--jsonでスキャン結果を保存し、@surea11y/core/junitのrenderJunitReport(result, { cantTellAs: 'failure' })でレポートを生成してください(JUnitレポートを参照)。それにはプロジェクト自身のdevDependenciesに@surea11y/coreが必要です。より狭い選択肢は{ leanFailAs: 'failure' }です。不合格寄りのcantTellの検出結果だけが不合格になり、それぞれに理由と確認の手順が付きます。どちらの場合も、変わるのはレポートであり、CLIの終了コードではありません。

無料枠やプライベートリポジトリの実行時間制限

パイプラインサービスの無料枠に実行時間の制限がある場合(たとえばBitbucket Pipelinesの無料枠は、プライベートワークスペースで月50分のビルド時間です)、静的なHTMLやサーバーでレンダリングされたHTMLをjsdomベースでスキャンする方法(CLIが行っていること)は、実際のブラウザーを操作するよりはるかに低コストです。その代わりに失うもの(クライアントサイドでレンダリングされるコンテンツと実際のCSSレイアウトは対象外)についてはCLIのドキュメントを参照してください。