From a68e93dfbfdc4ef1dc9a004f4e377bc60e565a94 Mon Sep 17 00:00:00 2001 From: tgwab-claude <326333458+tgwab-claude@users.noreply.github.com> Date: Mon, 14 Sep 2026 16:34:03 -0400 Subject: [PATCH] Deploy only the site, not the repository's internals `wrangler pages deploy .` uploaded the repository root, so capondargan.com served README.md, scripts/*.sh, .github/ruleset-main.json, and .github/workflows/ci.yml. The deploy now stages the site into _site/ and uploads that. A verify step fails the deploy if an internal path was staged, or if a file the site needs was dropped by the excludes. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01KX5fU4VDLe5MbyaytQJByw --- .github/workflows/deploy.yml | 33 ++++++++++++++++++++++++++++++++- .gitignore | 1 + README.md | 4 ++-- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index ac14d87..3fad8e9 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -47,13 +47,44 @@ jobs: echo "ok=true" >> "$GITHUB_OUTPUT" fi + # Stage only the site into _site/. The repo root also holds CI config, + # scripts, and Markdown, and deploying `.` published all of them at + # capondargan.com (README.md, scripts/*.sh, .github/**). + - name: Stage site files + if: steps.gate.outputs.ok == 'true' + run: > + rsync -a + --exclude='.git' + --exclude='.github/' + --exclude='.gitignore' + --exclude='.nvmrc' + --exclude='scripts/' + --exclude='*.md' + --exclude='_site/' + ./ _site/ + + # Fails in both directions: an internal path that was staged, or a file + # the site needs that the excludes dropped. + - name: Verify the staged site + if: steps.gate.outputs.ok == 'true' + run: | + leaked=$(find _site \( -name '*.md' -o -path '_site/.github*' -o -path '_site/scripts*' -o -name '.gitignore' -o -name '.nvmrc' \) -print) + if [ -n "$leaked" ]; then + echo "Internal paths were staged:" + echo "$leaked" + exit 1 + fi + for f in index.html 404.html _headers _redirects robots.txt .well-known/security.txt; do + [ -f "_site/$f" ] || { echo "Missing from _site/: $f"; exit 1; } + done + - name: Deploy to Cloudflare Pages if: steps.gate.outputs.ok == 'true' env: CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID || '8a0d49b1f3fdcdadec135562ec8a4fdc' }} run: > - npx wrangler@4 pages deploy . + npx wrangler@4 pages deploy _site --project-name capondargan-com --branch ${{ github.ref == 'refs/heads/main' && 'main' || github.head_ref }} --commit-dirty=false diff --git a/.gitignore b/.gitignore index b0ffe0e..c360530 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ .wrangler/ .dev.vars* .env* +_site/ diff --git a/README.md b/README.md index d3bc1d9..37abc36 100644 --- a/README.md +++ b/README.md @@ -50,12 +50,12 @@ Deploy is a separate workflow (`.github/workflows/deploy.yml`). CI does not depl ## Deploy -One repo → one Cloudflare Pages project (`capondargan-com`, TechGuyWithABeard account), deployed by **GitHub Actions** with `wrangler pages deploy`. Framework preset **None**. No build step: the repo is the output. Cloudflare's Pages Git integration is off. There is no other deploy path. +One repo → one Cloudflare Pages project (`capondargan-com`, TechGuyWithABeard account), deployed by **GitHub Actions** with `wrangler pages deploy`. Framework preset **None**. No build step: the repo, minus its internals, is the output. Cloudflare's Pages Git integration is off. There is no other deploy path. 1. Open a draft pull request 2. CI (`ci` job) must pass 3. Merge to `main` -4. The deploy workflow uploads the repo root to Pages +4. The deploy workflow stages the site into `_site/`, leaving out `.github/`, `scripts/`, and Markdown, and uploads that to Pages ## Mail