How to Deploy a Preview Environment Per PR in GitHub Actions
Reviewers move faster when every PR ships a live preview they can click, scoped to that PR alone.
Trigger on pull_request, derive a per-PR slug from the PR number, deploy to that namespace, and comment the URL.
Steps
- Trigger the workflow on
pull_request(opened, synchronize, reopened). - Build a unique environment name like
pr-<number>. - Deploy your app to that namespace or subdomain.
- Post the preview URL back to the PR.
Workflow
.github/workflows/preview.yml
on:
pull_request:
types: [opened, synchronize, reopened]
jobs:
preview:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy preview
run: ./deploy.sh "pr-${{ github.event.number }}"
- uses: marocchino/sticky-pull-request-comment@v2
with:
header: preview
message: |
Preview ready: https://pr-${{ github.event.number }}.preview.example.comGotchas
- Always pair this with a teardown on PR close or previews pile up and cost money.
- A sticky comment avoids spamming the PR with a new comment on every push.
- Latchkey runs preview deploys on cheaper runners and retries if a deploy step hits a transient error.
Related guides
How to Tear Down a Preview on PR Close in GitHub ActionsAutomatically destroy a per-PR preview environment when the pull request closes in GitHub Actions, so closed…
How to Run E2E Tests Against a Deployed Preview in GitHub ActionsRun end-to-end tests against a live per-PR preview deployment in GitHub Actions, gating the test job on the d…