Make the visual check required
Block a pull request from merging until visual changes are reviewed by making the UI Verify check a required status check. Accepting a change flips it green live.
By default the UI Verify check reports visual changes but does not block a merge - a reviewer can still merge past it. To gate the pull request so it cannot merge until every visual change is reviewed, make the check a required status check in your repository's branch protection.
Make the UI Verify check required
UI Verify posts its verdict as a GitHub status check named UI Verify: <project-slug>. For a project whose slug is web-app, the check is UI Verify: web-app. Add that exact name to your branch protection rule.
- In your repository, open Settings, then Branches, and edit (or add) the branch protection rule for your default branch.
- Enable "Require status checks to pass before merging".
- Search for and select
UI Verify: <your-project-slug>. It shows up in the list once the project has posted at least one check to a pull request. - Save. New pull requests can no longer merge while that check is failing or awaiting review.
Accepting a change turns the check green, with no re-run
When a build has changes to review, the required check is failing. You do not need to re-run CI to clear it: accept the changes in the dashboard, or from your coding agent over MCP, and UI Verify recomputes the verdict and flips the same check to success on the pull request immediately. Deny a change and it flips back to failing. See Triage visual changes from your coding agent.
Re-running the CI job after you accept
If you gate the merge on the UI Verify: <slug> status check directly, there is nothing to re-run - accepting updates that check in place and the pull request becomes mergeable. But if you instead gate on the Actions job that runs uiverify upload (that job exits non-zero on an unreviewed build), the failed job stays red even after you accept, until it is re-run. Click "Re-run jobs" in the Actions tab, or automate it with a workflow that re-runs the failed job the moment the check flips to success.
name: UI Verify Auto-Rerun
# Re-runs your failed visual workflow once you accept the changes and UI Verify flips its
# check to success. Requires the visual workflow's own filename below (here, visual.yml).
on: status
permissions:
actions: write
jobs:
rerun:
if: startsWith(github.event.context, 'UI Verify:') && github.event.state == 'success'
runs-on: ubuntu-latest
steps:
- name: Re-run the failed visual workflow for this commit
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
HEAD_SHA: ${{ github.event.sha }}
run: |
set -euo pipefail
run_ids=$(gh run list --repo "$GITHUB_REPOSITORY" \
--workflow visual.yml --commit "$HEAD_SHA" \
--status failure --json databaseId --jq '.[].databaseId')
for run_id in $run_ids; do
gh run rerun "$run_id" --failed --repo "$GITHUB_REPOSITORY"
donestatus-triggered workflow only fires from the copy on your default branch, so merge this file to main before it takes effect. If several projects post their own UI Verify: <slug> checks, branch on github.event.context to re-run only the accepted project's workflow.Why does the check hang on a pull request from a fork?
GitHub withholds repository secrets from a forked-repo pull request, so UIVERIFY_API_KEY is empty, the upload is skipped, and a required check never posts - leaving the PR stuck "Expected". This affects any secret-based check. See Troubleshooting for the fork-PR options.
Set up visual testing
From no visual tests to a green check on every pull request.
Visual testing for agents
UI Verify captures your UI on every pull request and an AI judge tells an intended change from a real regression. See how it works.
Get started