From 369ada28c2fbdea7f73f984e06e1f5158d3b9205 Mon Sep 17 00:00:00 2001 From: Chuck McAndrew <6248903+dcmcand@users.noreply.github.com> Date: Wed, 24 Jun 2026 17:24:53 +0200 Subject: [PATCH] ci(docs): add preview-deployment cleanup on PR close --- .github/workflows/docs-preview-cleanup.yml | 43 ++++++++++++++++++++++ README.md | 16 +++++--- 2 files changed, 53 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/docs-preview-cleanup.yml diff --git a/.github/workflows/docs-preview-cleanup.yml b/.github/workflows/docs-preview-cleanup.yml new file mode 100644 index 0000000..7e8a80a --- /dev/null +++ b/.github/workflows/docs-preview-cleanup.yml @@ -0,0 +1,43 @@ +name: Docs preview cleanup +# When a PR closes (merged or not), delete the Cloudflare Pages preview +# deployments for that branch. Direct Upload deploys are not tied to the git +# branch lifecycle, so without this they linger after the branch is gone. +# +# When adopting this in your own pack: set CF_PROJECT to your pack's Cloudflare +# Pages project name (same value as --project-name in docs.yml). +on: + pull_request: + types: [closed] +permissions: + contents: read +concurrency: + group: docs-preview-cleanup-${{ github.event.pull_request.number }} + cancel-in-progress: false +env: + CF_PROJECT: nebari-software-pack-template +jobs: + cleanup: + # Fork PRs never get a preview (deploy is skipped, secrets unavailable), + # so there is nothing to clean up for them. + if: ${{ github.event.pull_request.head.repo.full_name == github.repository }} + runs-on: ubuntu-latest + steps: + - name: Delete this branch's preview deployments + env: + CF_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} + CF_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + BRANCH: ${{ github.event.pull_request.head.ref }} + run: | + set -euo pipefail + base="https://api.cloudflare.com/client/v4/accounts/${CF_ACCOUNT_ID}/pages/projects/${CF_PROJECT}/deployments" + ids=$(curl -fsS -H "Authorization: Bearer ${CF_API_TOKEN}" "${base}?env=preview&per_page=100" \ + | jq -r --arg b "$BRANCH" '.result[] | select(.deployment_trigger.metadata.branch == $b) | .id') + if [ -z "$ids" ]; then + echo "No preview deployments found for branch '$BRANCH'." + exit 0 + fi + for id in $ids; do + echo "Deleting preview deployment $id (branch '$BRANCH')" + curl -fsS -X DELETE -H "Authorization: Bearer ${CF_API_TOKEN}" "${base}/${id}?force=true" >/dev/null + done + echo "Cleaned up preview deployments for branch '$BRANCH'." diff --git a/README.md b/README.md index 5f8a9b6..7177f2a 100644 --- a/README.md +++ b/README.md @@ -864,13 +864,14 @@ unified domain, while each pack deploys and previews independently. docs: https://packs.nebari.dev// ``` -2. **Copy `.github/workflows/docs.yml` from this repo** into your pack repo and - update two values: +2. **Copy `.github/workflows/docs.yml` and `.github/workflows/docs-preview-cleanup.yml` + from this repo** into your pack repo and update these values: - | Variable | Set to | - |----------|--------| - | `PACK_SLUG` (env) | your repo's short name (the segment after `nebari-dev/`) | - | `--project-name=...` in the `wrangler` command | the matching Cloudflare Pages project name | + | Variable | In | Set to | + |----------|----|--------| + | `PACK_SLUG` (env) | `docs.yml` | your repo's short name (the segment after `nebari-dev/`) | + | `--project-name=...` in the `wrangler` command | `docs.yml` | the matching Cloudflare Pages project name | + | `CF_PROJECT` (env) | `docs-preview-cleanup.yml` | the same Cloudflare Pages project name | For most packs, `PACK_SLUG` and the project name are the same (e.g., `llm-serving-pack`). The template repo is a special case: `PACK_SLUG: building-a-software-pack` routes to @@ -890,6 +891,9 @@ unified domain, while each pack deploys and previews independently. and deploys to a preview deployment; a bot comments the preview URL on the PR. - **Fork PRs:** the build and link-check run, but the deploy step is skipped (fork PRs cannot read org secrets). +- **Cleanup:** when a PR closes (merged or not), `docs-preview-cleanup.yml` deletes that + branch's preview deployments. Direct Upload deploys are not tied to the git branch + lifecycle, so without this previews would linger after the branch is gone. The edge Worker at `packs.nebari.dev` proxies `//*` to `.pages.dev/*` transparently. For packs in `tracked-packs.yaml` with `docs_site: true`, the route is