Two composite actions extracted from modelcontextprotocol's blog-preview workflow: - deploy: injects noindex headers/meta, deploys to CF Pages under a per-PR branch alias, posts/updates a sticky PR comment with preview URLs - cleanup: deletes all CF Pages deployments for the PR branch alias on close, updates the sticky comment Callers provide a pre-built static HTML directory; the actions handle everything Cloudflare-specific.
87 lines
3.1 KiB
YAML
87 lines
3.1 KiB
YAML
name: Cloudflare Pages PR Preview — Cleanup
|
|
description: >-
|
|
Deletes all Cloudflare Pages deployments for a PR's branch alias and updates
|
|
the sticky PR comment to indicate the preview has been cleaned up. Intended
|
|
to run on pull_request.closed.
|
|
|
|
inputs:
|
|
project-name:
|
|
description: Cloudflare Pages project name
|
|
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 whose deployments should be deleted
|
|
required: false
|
|
default: pr-${{ github.event.pull_request.number }}
|
|
comment-marker:
|
|
description: HTML comment marker used to locate the sticky PR comment
|
|
required: false
|
|
default: '<!-- cf-pages-preview -->'
|
|
github-token:
|
|
description: GitHub token for updating the PR comment
|
|
required: false
|
|
default: ${{ github.token }}
|
|
|
|
runs:
|
|
using: composite
|
|
steps:
|
|
- name: Delete preview deployments
|
|
shell: bash
|
|
env:
|
|
CF_API_TOKEN: ${{ inputs.api-token }}
|
|
CF_ACCOUNT_ID: ${{ inputs.account-id }}
|
|
CF_PROJECT: ${{ inputs.project-name }}
|
|
PR_BRANCH: ${{ inputs.branch }}
|
|
run: |
|
|
set -euo pipefail
|
|
api="https://api.cloudflare.com/client/v4/accounts/${CF_ACCOUNT_ID}/pages/projects/${CF_PROJECT}/deployments"
|
|
|
|
echo "Listing deployments for branch alias: ${PR_BRANCH}"
|
|
# Cloudflare paginates at 25/page. One PR rarely has >25 deploys, but
|
|
# loop until the branch alias returns empty just in case of a long-
|
|
# running PR with many pushes.
|
|
while :; do
|
|
ids=$(curl -sS -H "Authorization: Bearer ${CF_API_TOKEN}" "${api}?per_page=25" \
|
|
| jq -r --arg b "$PR_BRANCH" '.result[] | select(.deployment_trigger.metadata.branch == $b) | .id')
|
|
|
|
if [ -z "$ids" ]; then
|
|
echo "No deployments remaining for ${PR_BRANCH}."
|
|
break
|
|
fi
|
|
|
|
for id in $ids; do
|
|
echo "Deleting deployment ${id}"
|
|
curl -sS -X DELETE -H "Authorization: Bearer ${CF_API_TOKEN}" "${api}/${id}?force=true" \
|
|
| jq -r '" → success=\(.success) errors=\(.errors // [])"'
|
|
done
|
|
done
|
|
|
|
- name: Update PR comment
|
|
uses: actions/github-script@v8
|
|
env:
|
|
COMMENT_MARKER: ${{ inputs.comment-marker }}
|
|
with:
|
|
github-token: ${{ inputs.github-token }}
|
|
script: |
|
|
const { owner, repo } = context.repo;
|
|
const prNumber = context.payload.pull_request.number;
|
|
const marker = process.env.COMMENT_MARKER;
|
|
|
|
const { data: comments } = await github.rest.issues.listComments({
|
|
owner, repo, issue_number: prNumber
|
|
});
|
|
const existing = comments.find(c =>
|
|
c.user.type === 'Bot' && c.body.includes(marker)
|
|
);
|
|
|
|
if (existing) {
|
|
await github.rest.issues.updateComment({
|
|
owner, repo, comment_id: existing.id,
|
|
body: `${marker}\n## Preview\n\n_Preview deployments for this PR have been cleaned up._`
|
|
});
|
|
}
|