Skip to content

Add GitHub Actions for Astro deploy and PR previews #8

Add GitHub Actions for Astro deploy and PR previews

Add GitHub Actions for Astro deploy and PR previews #8

Workflow file for this run

name: Preview on Pull Request
on:
pull_request:
types: [opened, synchronize, reopened]
workflow_dispatch:
inputs:
pr_number:
description: "Pull request number to deploy preview for"
required: true
type: string
permissions:
contents: write
pull-requests: write
concurrency:
group: preview-${{ github.event.pull_request.number || inputs.pr_number }}
cancel-in-progress: true
env:
PAGES_BRANCH: gh-pages
jobs:
preview-deploy:
runs-on: ubuntu-latest
env:
PR_NUMBER: ${{ github.event.pull_request.number || inputs.pr_number }}
DEPLOY_TARGET: pr
DEPLOY_PREVIEW_PATH: pr-${{ github.event.pull_request.number || inputs.pr_number }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Ensure gh-pages branch exists
shell: bash
run: |
set -euo pipefail
git fetch --all
if git ls-remote --exit-code --heads origin "$PAGES_BRANCH" >/dev/null 2>&1; then
echo "Branch $PAGES_BRANCH exists"
exit 0
fi
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git checkout --orphan "$PAGES_BRANCH"
git rm -rf . >/dev/null 2>&1 || true
printf '<!doctype html><title>Bootstrap</title><p>Preview bootstrap.</p>' > index.html
touch .nojekyll
git add index.html .nojekyll
git commit -m "Bootstrap gh-pages for previews"
git push origin "$PAGES_BRANCH"
- name: Setup Astro
uses: withastro/action@v3
with:
path: .
node-version: 20
package-manager: npm
- name: Build site
run: npm run build
- name: Add .nojekyll for GitHub Pages
run: touch dist/.nojekyll
- name: Deploy PR preview to gh-pages
uses: JamesIves/github-pages-deploy-action@v4
with:
branch: ${{ env.PAGES_BRANCH }}
folder: dist
target-folder: preview/pr-${{ env.PR_NUMBER }}
clean: true
- name: Compute preview URL
id: preview_url
shell: bash
env:
OWNER: ${{ github.repository_owner }}
REPO: ${{ github.event.repository.name }}
run: |
set -euo pipefail
user_site_repo="${OWNER}.github.io"
if [ "$REPO" = "$user_site_repo" ]; then
url="https://${OWNER}.github.io/preview/pr-${PR_NUMBER}/"
else
url="https://${OWNER}.github.io/${REPO}/preview/pr-${PR_NUMBER}/"
fi
echo "url=$url" >> "$GITHUB_OUTPUT"
- name: Verify preview URL is reachable
id: verify_preview
continue-on-error: true
shell: bash
env:
PREVIEW_URL: ${{ steps.preview_url.outputs.url }}
run: |
set -euo pipefail
echo "Checking $PREVIEW_URL"
for i in $(seq 1 40); do
code=$(curl -s -L -o /dev/null -w "%{http_code}" "$PREVIEW_URL" || true)
if [ "$code" = "200" ]; then
echo "Preview is live"
exit 0
fi
echo "Attempt $i/40: HTTP $code, retrying in 15s..."
sleep 15
done
echo "Preview did not become reachable in time"
exit 1
- name: Comment preview URL on PR
if: github.event_name == 'pull_request' && steps.verify_preview.outcome == 'success'
uses: actions/github-script@v7
env:
PREVIEW_URL: ${{ steps.preview_url.outputs.url }}
with:
script: |
const pr = context.payload.pull_request.number;
const body = [
'🔍 PR preview is ready.',
'',
`**Open preview:** ${process.env.PREVIEW_URL}`
].join('\n');
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr,
body
});
- name: Comment failure help on PR
if: github.event_name == 'pull_request' && steps.verify_preview.outcome == 'failure'
uses: actions/github-script@v7
env:
PREVIEW_URL: ${{ steps.preview_url.outputs.url }}
with:
script: |
const pr = context.payload.pull_request.number;
const body = [
'⚠️ PR preview was deployed but the URL was not reachable yet.',
'',
`Try opening: ${process.env.PREVIEW_URL}`,
'',
'If it still does not load, wait 2-5 minutes and re-run the `Preview on Pull Request` workflow.'
].join('\n');
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr,
body
});