Skip to content

Fork Preview Deploy #143

Fork Preview Deploy

Fork Preview Deploy #143

name: Fork Preview Deploy
on:
workflow_run:
workflows:
- Fork Preview Build
types:
- completed
permissions:
actions: read
contents: read
pull-requests: write
concurrency:
group: fork-preview-deploy-${{ github.event.workflow_run.id }}
cancel-in-progress: false
jobs:
deploy:
if: >
github.event.workflow_run.conclusion == 'success' &&
github.event.workflow_run.event == 'pull_request' &&
github.event.workflow_run.head_repository.full_name != github.repository
runs-on: ubuntu-latest
env:
PREVIEW_PROJECT: ${{ vars.CLOUDFLARE_PREVIEW_PAGES_PROJECT }}
steps:
- name: Validate preview project configuration
run: |
set -euo pipefail
if [ -z "${PREVIEW_PROJECT}" ]; then
echo "Repository variable CLOUDFLARE_PREVIEW_PAGES_PROJECT is required." >&2
exit 1
fi
- name: Download preview artifact
uses: actions/download-artifact@v8
with:
name: pr-preview-site
path: preview-artifact
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Read preview metadata
id: meta
run: |
set -euo pipefail
metadata_file="preview-artifact/.preview-artifact/metadata.json"
pr_number="$(jq -r '.pr_number' "${metadata_file}")"
head_sha="$(jq -r '.head_sha' "${metadata_file}")"
head_ref="$(jq -r '.head_ref' "${metadata_file}")"
preview_branch="pr-${pr_number}"
{
echo "pr_number=${pr_number}"
echo "head_sha=${head_sha}"
echo "head_ref=${head_ref}"
echo "preview_branch=${preview_branch}"
} >> "${GITHUB_OUTPUT}"
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: 24.15.0
- name: Deploy preview to Cloudflare Pages
id: deploy
run: |
set -euo pipefail
deploy_log="$(mktemp)"
npx wrangler@4 pages deploy preview-artifact/build \
--project-name "${PREVIEW_PROJECT}" \
--branch "${{ steps.meta.outputs.preview_branch }}" \
--commit-hash "${{ steps.meta.outputs.head_sha }}" \
--commit-message "PR #${{ steps.meta.outputs.pr_number }} preview deployment" \
| tee "${deploy_log}"
preview_url="$(
sed -n 's/^.*Deployment alias URL: \(https:\/\/[^[:space:]]*\).*$/\1/p' "${deploy_log}" | tail -n 1
)"
if [ -z "${preview_url}" ]; then
echo "Unable to determine Cloudflare preview alias URL from Wrangler output." >&2
exit 1
fi
echo "preview_url=${preview_url}" >> "${GITHUB_OUTPUT}"
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_DEPLOY_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
- name: Upsert preview comment
uses: actions/github-script@v9
env:
PREVIEW_URL: ${{ steps.deploy.outputs.preview_url }}
HEAD_REF: ${{ steps.meta.outputs.head_ref }}
with:
script: |
const prNumber = Number("${{ steps.meta.outputs.pr_number }}");
const body = [
"## Cloudflare Preview",
"",
`Preview URL: ${process.env.PREVIEW_URL}`,
`Source branch: \`${process.env.HEAD_REF}\``,
`Run: ${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`,
].join("\n");
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
});
const existing = comments.find((comment) =>
comment.user?.type === "Bot" && comment.body?.startsWith("## Cloudflare Preview")
);
if (existing) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: existing.id,
body,
});
return;
}
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body,
});