Integrating preview environments into your CI/CD pipeline automates the deployment process and ensures every pull request gets a live preview URL. This article covers best practices and provides ready-to-use configurations for popular CI/CD platforms.
Why Automate Preview Deployments?
Manual preview deployments defeat the purpose of rapid iteration. By automating the process, you:
- Save time: No manual intervention required for each PR
- Ensure consistency: Every PR gets the same treatment
- Enable parallel workflows: Multiple PRs can have simultaneous previews
- Improve traceability: Preview URLs are automatically linked to PRs
GitHub Actions Integration
GitHub Actions is one of the most popular CI/CD platforms. Here's a complete workflow for automated preview deployments:
Basic Workflow
name: Preview Environment
on:
pull_request:
types: [opened, synchronize, reopened]
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Build project
run: npm run build
- name: Deploy to prev
id: deploy
run: |
curl -fsSL https://prev.sh/install.sh | sh
PREVIEW_URL=$(prev create . --subdomain pr-${{ github.event.number }} -o url)
echo "preview_url=$PREVIEW_URL" >> $GITHUB_OUTPUT
env:
PREV_API_KEY: ${{ secrets.PREV_API_KEY }}
- name: Comment on PR
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: '🚀 Preview deployed: ${{ steps.deploy.outputs.preview_url }}'
})
Cleanup on PR Close
name: Cleanup Preview
on:
pull_request:
types: [closed]
jobs:
cleanup:
runs-on: ubuntu-latest
steps:
- name: Destroy preview
run: |
curl -fsSL https://prev.sh/install.sh | sh
prev destroy pr-${{ github.event.number }}
env:
PREV_API_KEY: ${{ secrets.PREV_API_KEY }}
GitLab CI Integration
For GitLab users, here's an equivalent configuration:
stages:
- deploy
- cleanup
deploy_preview:
stage: deploy
image: node:20
script:
- npm ci
- npm run build
- curl -fsSL https://prev.sh/install.sh | sh
- PREVIEW_URL=$(prev create . --subdomain mr-$CI_MERGE_REQUEST_IID -o url)
- echo "Preview deployed: $PREVIEW_URL"
environment:
name: preview/$CI_MERGE_REQUEST_IID
on_stop: stop_preview
rules:
- if: $CI_MERGE_REQUEST_IID
stop_preview:
stage: cleanup
image: node:20
script:
- curl -fsSL https://prev.sh/install.sh | sh
- prev destroy mr-$CI_MERGE_REQUEST_IID
environment:
name: preview/$CI_MERGE_REQUEST_IID
action: stop
rules:
- if: $CI_MERGE_REQUEST_IID
when: manual
CircleCI Integration
version: 2.1
jobs:
deploy-preview:
docker:
- image: cimg/node:20.0
steps:
- checkout
- run:
name: Install dependencies
command: npm ci
- run:
name: Build
command: npm run build
- run:
name: Deploy preview
command: |
curl -fsSL https://prev.sh/install.sh | sh
prev create . --subdomain pr-$CIRCLE_PR_NUMBER
workflows:
preview:
jobs:
- deploy-preview:
filters:
branches:
ignore: main
Best Practices
1. Use Semantic Subdomain Names
Include identifiable information in your subdomain:
prev create . --subdomain pr-123-feature-login
2. Set Appropriate TTLs
Match TTL to your review cycle:
prev create . --ttl 3d # Most PRs are reviewed within 3 days
3. Secure Your Tokens
Never commit API tokens. Use CI/CD secrets:
- GitHub: Repository Settings → Secrets
- GitLab: Settings → CI/CD → Variables
- CircleCI: Project Settings → Environment Variables
4. Handle Build Failures Gracefully
Add error handling to prevent silent failures:
- name: Deploy preview
run: |
prev create . --subdomain pr-${{ github.event.number }} || {
echo "Preview deployment failed"
exit 1
}
5. Add Status Checks
Require preview deployment as a status check before merging.
Monitoring and Debugging
Check Deployment Status
prev list
View Logs
prev logs pr-123
List All Active Previews
prev list
Conclusion
Automating preview environments with CI/CD removes manual deploy steps from review workflows. The configurations here are starting points for GitHub Actions, GitLab CI, and CircleCI.
For CLI flags, cleanup commands, and troubleshooting, check out the CLI Commands documentation.