name: Cloudflare Pages PR Preview — Deploy description: >- Deploys a pre-built static HTML directory to Cloudflare Pages under a per-PR branch alias, injects noindex headers/meta tags, and posts/updates a sticky PR comment with the preview URLs. inputs: directory: description: Path to the built static HTML directory (e.g. blog/public) required: true project-name: description: Cloudflare Pages project name (must already exist in the CF dashboard) required: true api-token: description: Cloudflare API token with Pages:Edit permission on the project required: true account-id: description: Cloudflare account ID required: true branch: description: Cloudflare Pages branch alias for this deployment required: false default: pr-${{ github.event.pull_request.number }} inject-noindex: description: >- Whether to inject X-Robots-Tag headers (via _headers file) and a tag into all HTML pages to prevent search engine indexing of the preview. Set to 'false' to skip. required: false default: 'true' comment-marker: description: HTML comment marker used to identify and update the sticky PR comment required: false default: '' comment-title: description: Heading shown in the sticky PR comment required: false default: 'Preview Deployed' comment-mode: description: >- How to handle prior preview comments. 'sticky' (default) updates the existing marker comment in place. 'repost' minimizes all prior marker comments as OUTDATED (GitHub's native hide-comment UI) and posts a fresh comment at the bottom of the conversation — preserving history while surfacing the latest links prominently. required: false default: sticky github-token: description: GitHub token for posting/updating the PR comment required: false default: ${{ github.token }} pr-number: description: >- PR number to comment on. Only needed on triggers where context.payload.pull_request is unavailable (e.g. workflow_dispatch). Defaults to the event payload's PR number. required: false default: ${{ github.event.pull_request.number }} commit-sha: description: >- Commit SHA shown in the sticky comment. Useful when the checked-out ref differs from github.sha (e.g. building a pinned head SHA on workflow_dispatch). Defaults to github.sha. required: false default: ${{ github.sha }} outputs: deployment-url: description: URL of the specific deployment (changes per push) value: ${{ steps.deploy.outputs.deployment-url }} alias-url: description: Stable branch-alias URL (same across pushes to this PR) value: ${{ steps.deploy.outputs.pages-deployment-alias-url }} runs: using: composite steps: # Prevent preview deployments from being indexed by search engines. # Cloudflare Pages serves _headers as HTTP headers for matching paths. # X-Robots-Tag covers all content types (HTML, RSS, sitemaps, etc.) - name: Add noindex headers if: inputs.inject-noindex == 'true' shell: bash env: DIR: ${{ inputs.directory }} run: | cat > "${DIR}/_headers" <<'EOF' /* X-Robots-Tag: noindex, nofollow, noarchive, nosnippet EOF # Also inject a tag into every HTML page as belt-and-suspenders # in case the site is later served from somewhere that ignores _headers. - name: Inject noindex meta tag if: inputs.inject-noindex == 'true' shell: bash env: DIR: ${{ inputs.directory }} run: | find "${DIR}" -name '*.html' -print0 | \ xargs -0 -r sed -i 's|
||' - name: Deploy to Cloudflare Pages id: deploy uses: cloudflare/wrangler-action@v3 with: apiToken: ${{ inputs.api-token }} accountId: ${{ inputs.account-id }} command: pages deploy ${{ inputs.directory }} --project-name=${{ inputs.project-name }} --branch=${{ inputs.branch }} - name: Comment with preview URL uses: actions/github-script@v8 env: DEPLOY_URL: ${{ steps.deploy.outputs.deployment-url }} ALIAS_URL: ${{ steps.deploy.outputs.pages-deployment-alias-url }} COMMENT_MARKER: ${{ inputs.comment-marker }} COMMENT_TITLE: ${{ inputs.comment-title }} COMMENT_MODE: ${{ inputs.comment-mode }} INJECT_NOINDEX: ${{ inputs.inject-noindex }} PR_NUMBER: ${{ inputs.pr-number }} COMMIT_SHA: ${{ inputs.commit-sha }} with: github-token: ${{ inputs.github-token }} script: | const main = require(process.env.GITHUB_ACTION_PATH + '/comment.js'); await main({ github, context, core });