Fork Preview Deploy #147
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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, | |
| }); |