A GitHub Action that performs visual regression testing by comparing screenshots between base and head commits in pull requests.
Full setup guide and documentation →
| Action | Use Case |
|---|---|
upload-assets |
Upload built static assets for Meticulous to test (recommended for static sites) |
upload-container |
Upload a built Docker image for Meticulous to host and test (recommended for server-rendered apps, e.g. Next.js) |
cloud-compute |
Test a locally-served app via a secure tunnel (last resort) |
report-diffs-action |
Run tests in GitHub Actions runner (legacy) |
Recommendation: Pick the first approach that fits your app:
upload-assetsif your app can be served as a folder of static assets (HTML/JS/CSS).upload-containerif your app is server-rendered (Next.js, Nuxt, etc.) — build a Docker image and let Meticulous host it.cloud-computeonly if neither of the above work — it serves the app from CI and connects via a secure tunnel, which is more brittle.
- uses: alwaysmeticulous/report-diffs-action/upload-assets@v1
with:
api-token: ${{ secrets.METICULOUS_API_TOKEN }}
app-directory: "dist" # Your build output directoryBuild a Docker image of your app and upload it. Meticulous runs the container in its own infrastructure for the duration of the test run, so no server needs to stay alive in CI.
- uses: docker/setup-buildx-action@v3
- uses: docker/build-push-action@v6
with:
context: .
tags: my-app:${{ github.sha }}
push: false
- uses: alwaysmeticulous/report-diffs-action/upload-container@v1
with:
api-token: ${{ secrets.METICULOUS_API_TOKEN }}
image-tag: my-app:${{ github.sha }}
# Optional: set if your container does not respect the PORT env var
container-port: 3000
# Optional: extra env vars passed to the container at run time
container-env: |
NODE_ENV=productionThe container must:
- Be built for
linux/amd64 - Listen on the
PORTenv var (or setcontainer-portto the hard-coded port) - Respond
2xxto the health-check endpoint (defaults toGET /, override withcontainer-health-check-endpoint)
Only use this if your app can't be uploaded as static assets or as a container image.
- name: Serve app
run: |
npm run build && npm run serve &
sleep 5
- uses: alwaysmeticulous/report-diffs-action/cloud-compute@v1
with:
api-token: ${{ secrets.METICULOUS_API_TOKEN }}
app-url: "http://localhost:3000/"All inputs are documented in the action.yml files:
on:
push:
branches: [main]
pull_request: {}
workflow_dispatch: {} # Required for base commit comparison
permissions:
actions: write
contents: read
issues: write
pull-requests: write
statuses: read- Setup Guide - Complete CI setup instructions
- Troubleshooting - Cross-environment issues
- FAQ - Common questions
- Create PR to merge
mainintoreleases/v1→ Create PR - Merge as a merge commit (not squash/rebase)
- Draft a new release with tag
v1.x.ytargetingreleases/v1 - The
@v1tag auto-updates after build completes