CI/CDでのPlaywrightブラウザのキャッシュ
このスキルを使用するタイミング
以下の場合にこのスキルを使用します:
- Playwright E2Eテストを使用するプロジェクトでCI/CDを設定する場合
- ブラウザのダウンロード(約400MB、1〜2分)によりビルド時間が遅い場合
- Playwrightのバージョンが変わったときに自動的にキャッシュを無効化したい場合
- GitHub ActionsまたはAzure DevOpsパイプラインを使用している場合
問題点
Playwrightブラウザ(約400MB)は、デフォルトではCI実行のたびにダウンロードする必要があります。これにより:
- 毎回のビルドに1〜2分追加される
- 帯域幅を浪費する
- 一時的なネットワーク問題で失敗する可能性がある
- PRのフィードバックループが遅くなる
コアパターン
- Playwrightバージョンの抽出:
Directory.Packages.props(CPM)からキャッシュキーとして使用するPlaywrightバージョンを抽出する - ブラウザバイナリのキャッシュ: プラットフォームに適したパスを使用してブラウザバイナリをキャッシュする
- 条件付きインストール: キャッシュミス時のみダウンロードする
- 自動キャッシュバスト: キーにバージョンを含めることで、パッケージのアップグレード時にキャッシュが無効化される
OSごとのキャッシュパス
| OS | パス |
|---|---|
| Linux | ~/.cache/ms-playwright |
| macOS | ~/Library/Caches/ms-playwright |
| Windows | %USERPROFILE%\AppData\Local\ms-playwright |
GitHub Actions
- name: Playwrightバージョンを取得
shell: pwsh
run: |
$propsPath = "Directory.Packages.props"
[xml]$props = Get-Content $propsPath
$version = $props.Project.ItemGroup.PackageVersion |
Where-Object { $_.Include -eq "Microsoft.Playwright" } |
Select-Object -ExpandProperty Version
echo "PlaywrightVersion=$version" >> $env:GITHUB_ENV
- name: Playwrightブラウザをキャッシュ
id: playwright-cache
uses: actions/cache@v4
with:
path: ~/.cache/ms-playwright
key: ${{ runner.os }}-playwright-${{ env.PlaywrightVersion }}
- name: Playwrightブラウザをインストール
if: steps.playwright-cache.outputs.cache-hit != 'true'
shell: pwsh
run: ./build/playwright.ps1 install --with-deps
マルチOS GitHub Actions
複数のオペレーティングシステムで実行するワークフローの場合:
- name: Playwrightブラウザをキャッシュ
id: playwright-cache
uses: actions/cache@v4
with:
path: |
~/.cache/ms-playwright
~/Library/Caches/ms-playwright
~/AppData/Local/ms-playwright
key: ${{ runner.os }}-playwright-${{ env.PlaywrightVersion }}
Azure DevOps
- task: PowerShell@2
displayName: 'Playwrightバージョンを取得'
inputs:
targetType: 'inline'
script: |
[xml]$props = Get-Content "Directory.Packages.props"
$version = $props.Project.ItemGroup.PackageVersion |
Where-Object { $_.Include -eq "Microsoft.Playwright" } |
Select-Object -ExpandProperty Version
Write-Host "##vso[task.setvariable variable=PlaywrightVersion]$version"
- task: Cache@2
displayName: 'Playwrightブラウザをキャッシュ'
inputs:
key: 'playwright | "$(Agent.OS)" | $(PlaywrightVersion)'
path: '$(HOME)/.cache/ms-playwright'
cacheHitVar: 'PlaywrightCacheHit'
- task: PowerShell@2
displayName: 'Playwrightブラウザをインストール'
condition: ne(variables['PlaywrightCacheHit'], 'true')
inputs:
filePath: 'build/playwright.ps1'
arguments: 'install --with-deps'
ヘルパースクリプト: playwright.ps1
build/playwright.ps1スクリプトを作成して、Playwright CLIを見つけて実行します。これにより、プロジェクト構造によって異なるPlaywright CLIの場所を抽象化します。
# build/playwright.ps1
# Microsoft.Playwright.dllを見つけて、バンドルされたPlaywright CLIを実行します
param(
[Parameter(ValueFromRemainingArguments = $true)]
[string[]]$Arguments
)
# Playwright DLLを見つける(dotnet build/restore後)
$playwrightDll = Get-ChildItem -Path . -Recurse -Filter "Microsoft.Playwright.dll" -ErrorAction SilentlyContinue |
Select-Object -First 1
if (-not $playwrightDll) {
Write-Error "Microsoft.Playwright.dllが見つかりません。最初に 'dotnet build' を実行してください。"
exit 1
}
$playwrightDir = $playwrightDll.DirectoryName
# Playwright CLIを見つける(パスはOSとNodeのバージョンによって異なる)
$playwrightCmd = Get-ChildItem -Path "$playwrightDir/.playwright/node" -Recurse -Filter "playwright.cmd" -ErrorAction SilentlyContinue |
Select-Object -First 1
if (-not $playwrightCmd) {
# Unix実行可能ファイルを試す
$playwrightCmd = Get-ChildItem -Path "$playwrightDir/.playwright/node" -Recurse -Filter "playwright" -ErrorAction SilentlyContinue |
Where-Object { $_.Name -eq "playwright" } |
Select-Object -First 1
}
if (-not $playwrightCmd) {
Write-Error "Playwright CLIが $playwrightDir/.playwright/node に見つかりません"
exit 1
}
Write-Host "使用するPlaywright CLI: $($playwrightCmd.FullName)"
& $playwrightCmd.FullName @Arguments
使用法:
# ブラウザをインストール
./build/playwright.ps1 install --with-deps
# 特定のブラウザをインストール
./build/playwright.ps1 install chromium
# インストール済みブラウザを表示
./build/playwright.ps1 install --dry-run
前提条件
このパターンは以下を前提としています:
-
中央パッケージ管理(CPM) と
Directory.Packages.props:<Project> <ItemGroup> <PackageVersion Include="Microsoft.Playwright" Version="1.40.0" /> </ItemGroup> </Project> -
playwright.ps1を実行する前に プロジェクトがビルドされている こと(DLLが存在するため) -
CIエージェントで PowerShellが利用可能 であること(GitHub ActionsとAzure DevOpsではプリインストール済み)
バージョンベースのキャッシュキーが重要な理由
キャッシュキーにPlaywrightのバージョンを使用することで、以下が保証されます:
- 自動的な無効化: Playwrightをアップグレードすると自動的に無効化される
- 古いブラウザバイナリが残らない: SDKのバージョンと一致しないブラウザバイナリが存在しない
- バージョンアップ後に手動でキャッシュをクリアする必要がない
キャッシュキーをハードコード(例:playwright-browsers-v1)すると、Playwrightをアップグレードするたびに手動でキーを変更する必要があり、そうしないと理解しにくいバージョン不一致エラーが発生します。
トラブルシューティング
キャッシュが使用されない
- バージョン抽出ステップが正しいバージョンを出力していることを確認する
- キャッシュパスがOSと一致していることを確認する
Directory.Packages.propsが存在し、Playwrightパッケージを含んでいることを確認する
キャッシュヒット後に「ブラウザが見つからない」
キャッシュされたブラウザがPlaywright SDKのバージョンと一致しません。これは以下の場合に発生します:
- キャッシュキーにバージョンが含まれていない
- バージョン抽出がサイレントに失敗した
修正:キャッシュキーにPlaywrightのバージョンが含まれていることを確認します。
playwright.ps1がDLLを見つけられない
スクリプトを実行する前に dotnet build または dotnet restore を実行します。Playwright DLLはNuGetリストア後にのみ存在します。
参考情報
このパターンは本番プロジェクトで実証済みです:
関連スキル
dotnet-skills:playwright-blazor- Blazorアプリケーション向けのPlaywrightテスト作成dotnet-skills:project-structure- 中央パッケージ管理のセットアップ