シリーズ一覧
- Playwright+Github Actionでビジュアルリグレッションテストしてみた — 1
- Playwright+Github Actionでビジュアルリグレッションテストしてみた — 2 ← 今はここ
- Playwright+Github Actionでビジュアルリグレッションテストしてみた — 3
残課題1—スナップショットの更新
スナップショットをDockerの中で更新するのが面倒です。プルリクエストの中で更新できるようにしましょう。大まかな手順はこちらです。
- VercelのプレビューURLを取れるなら、自動的にチェックボックス付きのコメントをする。
- チェックボックスにチェックを入れると、workflowを動かして、最新のスナップショットを取り、PRへコミットする。
自動的にチェックボックス付きのコメントをする
自動コメントは難しくありません。ただし、workflowをトリガーするイベントに要注意です。deployment_status
のイベントなら、プルリクエストのissue numberをどうしても取れないため、PRを特定できずコメントできません。なので、コメントステップのあるworkflowはdeployment_status
ではなく、pull_request
イベントの利用が必要です。
ダメな例。
name: e2e
on: [deployment_status]
jobs:
visual-tests:
steps:
# ... your own steps
- name: Find Comment for updating snapshots
uses: peter-evans/find-comment@v2
with:
# ここはダメ、github.event.numberがundefined, contextの中にもissue numberがない
issue-number: ${{ github.event.number }}
comment-author: 'github-actions[bot]'
body-includes: '### Title'
コメントする方法
VercelのPreview URLを取れたら、コメントを探し、存在しなければコメントを追加、存在する場合コメントを上書きをします。上のダメな例と同じ、peter-evans/find-comment
の使用がおすすめです。
name: e2e
on:
pull_request:
jobs:
visual-tests:
steps:
# ... your own steps
- name: Get Vercel's Alias Preview URL
id: alias-preview-url
uses: justincase-jp/vercel-preview-url-alias@0.3.0
with:
vercel_access_token: ${{ secrets.VERCEL_ACCESS_TOKEN }}
vercel_project_id: ${{ secrets.VERCEL_PROJECT_ID }}
fail_when_cancelled: false
- name: Find Comment for updating snapshots
if: |
github.ref != 'refs/heads/main' &&
steps.alias-preview-url.outputs.status == 'READY'
uses: peter-evans/find-comment@v2
id: fc
with:
issue-number: ${{ github.event.number }}
comment-author: 'github-actions[bot]'
# Find comment which title is ### Check the checkbox to automatically update all changed snapshots
body-includes: '### Check the checkbox to automatically update all changed snapshots'
- name: Comment
if: |
github.ref != 'refs/heads/main' &&
steps.alias-preview-url.outputs.status == 'READY'
uses: peter-evans/create-or-update-comment@v2
with:
comment-id: ${{ steps.fc.outputs.comment-id }}
issue-number: ${{ github.event.number }}
edit-mode: replace
# Add comment with checkbox [Update All Snapshots]
body: |
### Check the checkbox to automatically update all changed snapshots
- [ ] Update All Snapshots
コメントが変わったらスナップショットを更新する
コメント- [ ] Update All Snapshots
のチェックボックスにチェックを入れたら、- [x] Update All Snapshots
に変わります。そのコメントの変化を検知して、workflowを動かしましょう。
コメント変更のイベントで絞り込む
プルリクエストのコメント変更を検知するイベントがissue_comment
となります。
どのissue、PRと関わらず、コメントが変わったらissue_comment
イベントが発火され、workflowが勝手に動きます。そのため、コメントの内容が- [x] Update All Snapshots
に変わったことで絞り込む必要があるでしょう。github.event.comment.bodyとcontains関数を使えば難しくありません。
name: snapshot
on:
issue_comment: types: [edited]
jobs:
update-snapshots:
runs-on: ubuntu-latest
timeout-minutes: 5
if: ${{ github.event.issue.pull_request && contains(github.event.comment.body, '- [x] Update All Snapshots') }}
PRのブランチ名を取る
ここはハマるポイントです。pull_requestイベントなら、contextからブランチ名を取れるが、issue_commentイベントならissueでも動くイベントなので、ブランチ情報がcontextに入っていません。Github APIを使って、対象のPRを探す必要があります。
使うAPIはこちらです。Get a pull request
cURLなどでもできますが、[actions/github-script
]の方が使いやすいです。
- name: Get target branch's head commit info
id: target-pull-request
uses: actions/github-script@v6
with:
script: |
const head = (await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.issue.number,
})).data.head;
// target branch name
core.setOutput('ref', head.ref);
steps.target-pull-request.outputs.ref
でブランチ名を取れるようになりました。
VercelのPreview URLを取得
ここにも結構ハマりました。issue_commentイベントなので、pull_request.head
からコミットのshaを正しく取れません。
ですから、ブランチ名と同じように、対象のPRを検索して、コミットshaを手に入る必要があります。この先のスクリプトを少し修正すると。
- name: Get target branch's head commit info
id: target-pull-request
uses: actions/github-script@v6
with:
script: |
const head = (await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.issue.number,
})).data.head;
// target branch name
core.setOutput('ref', head.ref);
// target branch commit sha core.setOutput('sha', head.sha);
そして、VercelのPreview URLを取るGithub Actionにcommit_sha渡せば、コメントの変わったPRのPreview URLを取れます。
- name: Get Vercel's Alias Preview URL
id: alias-preview-url
uses: justincase-jp/vercel-preview-url-alias@0.3.0
with:
vercel_access_token: ${{ secrets.VERCEL_ACCESS_TOKEN }}
vercel_project_id: ${{ secrets.VERCEL_PROJECT_ID }}
fail_when_cancelled: true
commit_sha: ${{ steps.target-pull-request.outputs.sha }}
スナップショットを更新する
大体な手順はこちらです。
- 対象のブランチをチェックアウト
- ここもハマるポイント。自分がPlaywrightのDockerコンテナーの中テストを走らせているため、git権限の問題があり、対象ブランチをチェックアウトする前に、次のコマンドを叩く必要がある
git config --global --add safe.directory /__w/next-startbootstrap-agency/next-startbootstrap-agency;
- ここもハマるポイント。自分がPlaywrightのDockerコンテナーの中テストを走らせているため、git権限の問題があり、対象ブランチをチェックアウトする前に、次のコマンドを叩く必要がある
playwright test --update-snapshots
にて新しいスナップショットを生成
- name: Checkout target branch
if: steps.alias-preview-url.outputs.status == 'READY'
run:
# next-startbootstrap-agencyはレポジトリ名となる
git config --global --add safe.directory /__w/next-startbootstrap-agency/next-startbootstrap-agency;
git fetch;
git checkout ${{ steps.target-pull-request.outputs.ref }};
- name: Update Snapshots
if: steps.alias-preview-url.outputs.status == 'READY'
# run 'playwright test --update-snapshots'
run: HOME=/root pnpm e2e:upd
env:
BASE_URL: https://${{ steps.alias-preview-url.outputs.preview_url_origin }}
PRへコミットする
ここもハマるポイントとなります。Githubのworkflowのデフォルトのtoken(GITHUB_TOKEN
)なら、workflowをtriggerできません。(https://docs.github.com/en/actions/using-workflows/triggering-a-workflow#triggering-a-workflow-from-a-workflow)
スナップショットが更新されて、それがPRにコミットされたとしても、ワークフローが機能しないため、更新されたスナップショットに対するE2Eテストは実行されません。
問題を解決するために、ソースコードをチェックアウトする際、個人のPAT(Personal Access Token)をtokenとして渡す必要があります。
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
token: ${{ secrets.PAT }} ref: ${{ github.head_ref }}
そして、stefanzweifel/git-auto-commit-actionを使えば、変更ファイルをPRへコミットできます。
- uses: stefanzweifel/git-auto-commit-action@v4
if: steps.alias-preview-url.outputs.status == 'READY'
with:
commit_message: 'chore: update changed snapshots'
早速試してみる
PRを出したら、コメントが追加されました。
チェックボックスにチェックを入れると、ワークフローが実行され、必要に応じてスナップショットを更新してコミットしてくれます。
完了
まとめるとワークフローのyamlファイルが長くなります。よろしければ、こちらのファイルupdate-snapshot.yamlをご覧ください。では。