How to Automate Screenshots in Your CI/CD Pipeline
Every deploy is a visual change. Buttons move. Colors shift. Layouts break. You can't catch all of it manually.
What if your CI/CD pipeline automatically captured screenshots after each deploy? Stored them. Compared them. Surfaced visual regressions before they hit production?
That's what this tutorial covers. We'll add screenshot automation to GitHub Actions using PageBolt's API.
The Setup
What you'll need:
- A GitHub repository with GitHub Actions enabled
- A staging environment (or production)
- A PageBolt API key (free tier: 100 screenshots/month)
- 15 minutes
What you'll get:
- Screenshots captured after every deploy
- Before/after comparison storage
- Visual regression detection (manual review)
- Artifact logs for debugging
Step 1: Store Your API Key as a Secret
In GitHub: Settings → Secrets and variables → Actions → New repository secret
Name: PAGEBOLT_API_KEY
Value: your-actual-api-key-here
Your workflow will access it as ${{ secrets.PAGEBOLT_API_KEY }}.
Step 2: Create the GitHub Actions Workflow
Create .github/workflows/screenshot-deploy.yml:
name: Capture Deploy Screenshots
on:
deployment_status
jobs:
screenshot:
runs-on: ubuntu-latest
if: github.event.deployment_status.state == 'success'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Create screenshots directory
run: mkdir -p screenshots
- name: Capture deployment screenshot
env:
PAGEBOLT_API_KEY: ${{ secrets.PAGEBOLT_API_KEY }}
DEPLOYMENT_URL: ${{ github.event.deployment_status.environment_url }}
run: node scripts/capture-screenshot.js
- name: Upload screenshots as artifact
uses: actions/upload-artifact@v4
with:
name: deployment-screenshots
path: screenshots/
retention-days: 30
- name: Comment on PR with screenshot
if: github.event.pull_request
uses: actions/github-script@v7
with:
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: '📸 Deployment screenshot captured. Check artifacts tab.'
})
Step 3: Create the Screenshot Capture Script
Create scripts/capture-screenshot.js:
const fs = require('fs');
const path = require('path');
async function captureScreenshot() {
const apiKey = process.env.PAGEBOLT_API_KEY;
const deploymentUrl = process.env.DEPLOYMENT_URL;
const timestamp = new Date().toISOString().split('T')[0];
if (!apiKey || !deploymentUrl) {
console.error('❌ Missing PAGEBOLT_API_KEY or DEPLOYMENT_URL');
process.exit(1);
}
console.log(`📸 Capturing screenshot of: ${deploymentUrl}`);
try {
const response = await fetch('https://api.pagebolt.dev/v1/screenshot', {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
url: deploymentUrl,
format: 'png',
width: 1280,
height: 720
})
});
if (!response.ok) {
throw new Error(`API error: ${response.status} ${response.statusText}`);
}
// Response is binary PNG data
const buffer = await response.arrayBuffer();
const screenshotPath = path.join('screenshots', `${timestamp}-deployment.png`);
fs.writeFileSync(screenshotPath, Buffer.from(buffer));
console.log(`✅ Screenshot saved: ${screenshotPath}`);
console.log(`📊 Size: ${buffer.byteLength} bytes`);
} catch (error) {
console.error(`❌ Screenshot failed: ${error.message}`);
process.exit(1);
}
}
captureScreenshot();
Step 4: Test It
Push to your repo. Trigger a deployment. Watch the workflow run:
- GitHub Actions captures a screenshot of your staging URL
- Screenshot saves to
screenshots/directory - Artifact is stored in the workflow run
- Comment posted on PR (if applicable)
Before/After Comparison
To compare screenshots between commits, store them by date:
// Modify the script to save with commit SHA
const commitSha = process.env.GITHUB_SHA.slice(0, 7);
const screenshotPath = path.join('screenshots', `${commitSha}-screenshot.png`);
Then manually compare by downloading both artifacts:
- Current deployment screenshot
- Previous deployment screenshot
- Open in a visual diff tool (macOS Preview, ImageMagick, etc.)
Real-World Example: E-commerce Site
After every deploy to staging, capture a screenshot of:
- Homepage
- Product page
- Checkout flow
Store all three. Review manually. Catch layout shifts before they reach production.
// Capture multiple URLs
const urls = [
`${deploymentUrl}/`,
`${deploymentUrl}/products/sample-product`,
`${deploymentUrl}/checkout`
];
for (const url of urls) {
await captureScreenshot(url, `${path.basename(url) || 'home'}`);
}
Pricing
Free tier: 100 screenshots/month (covers most CI/CD pipelines)
Starter: $29/month for 5,000 screenshots (high-frequency deploys)
Growth: $79/month for 25,000 screenshots (large teams)
Scale: $199/month for 100,000 screenshots (enterprise)
For most projects, the free tier is enough. One screenshot per deploy = ~30 screenshots/month (if you deploy daily).
Next Steps
- Copy the workflow and script above
- Add your PageBolt API key to GitHub Secrets
- Deploy to staging
- Watch the artifact appear in your workflow run
- Compare screenshots manually or integrate with a visual regression tool
Start PageBolt free — 100 screenshots/month, no credit card.
Top comments (0)