KB Site — Cloudflare Pages Git Migration
Migrated kb.baseworks.com from a GitHub Actions–driven Direct Upload deploy to a Cloudflare Pages Git-connected build. Eliminated the GitHub Actions usage that was about to hit the 2,000 minute/month free cap.
Trigger
Section titled “Trigger”GitHub sent a billing alert: 1,800 of 2,000 Actions minutes used for the cycle, with 11 days remaining until reset (May 1, 2026). The vault repo (p-oancia/baseworks-kb-shared-brain) was the only repo with a workflow — deploy.yml, which rebuilt and deployed the KB site on every push to main. Vault auto-sync/backup commits run frequently, so the workflow fired many times per day.
Decision
Section titled “Decision”Switch from Cloudflare Pages Direct Upload (build runs in GitHub Actions, dist pushed to Cloudflare via wrangler) to Cloudflare Pages Git Integration (Cloudflare watches the repo and runs the build itself).
Rejected alternatives:
- Path filters on the workflow — would reduce burn but not eliminate it.
- Move build to the VPS — adds a moving part for no benefit over Cloudflare’s native Git mode.
- Manual trigger only — defeats the purpose of git-driven deploys.
What changed
Section titled “What changed”| Component | Before | After |
|---|---|---|
| Pages project | baseworks-kb (Direct Upload, ad-hoc deploys) | baseworks-kb-git (Git source, auto-builds) |
| Build runner | GitHub Actions Ubuntu runner | Cloudflare Pages build environment |
| Trigger | on: push workflow + workflow_dispatch | Cloudflare polls repo via GitHub App |
| Auth | CLOUDFLARE_API_KEY + email in GitHub secrets | Cloudflare Pages GitHub App (OAuth) |
| Cache purge | Explicit curl step in workflow | Handled automatically by Pages on deploy |
| Slack failure notifications | Workflow if: failure() step | None (Cloudflare dashboard shows build status; revisit if needed) |
The build configuration itself is identical:
- Root directory:
site - Build command:
node scripts/sync-content.mjs && npm run build - Output:
dist - Node version: 20
Migration steps performed
Section titled “Migration steps performed”- Backups saved to
~/Documents/baseworks-changelog/backups/cloudflare-pages-migration-2026-04-20/:pages-project-config.json— full export of old project config (build settings, env vars, deployment configs).deploy.yml.backup— copy of the old workflow file.
- Cloudflare Pages GitHub App installed by Patrick on
p-oancia/baseworks-kb-shared-brain(browser OAuth — only step that can’t be automated via API). - New project
baseworks-kb-gitcreated via Cloudflare API with git source pointing at the repo, branchmain, identical build config to the old project. - First build triggered via API, succeeded in ~5.5 minutes (
clone_repo8s,build4m 19s,deploy1m 8s). Verified atbaseworks-kb-git.pages.dev. - Custom domain
kb.baseworks.comadded to new project via API. Cloudflare auto-detached it from the old project (one Pages project per hostname). - DNS CNAME updated from
baseworks-kb.pages.devtobaseworks-kb-git.pages.dev(proxied, in zonebaseworks.com). - Verified
https://kb.baseworks.com/returns HTTP 200 from new project. - Cleanup:
- Deleted
.github/workflows/deploy.ymlfrom the vault repo. - Deleted GitHub repo secrets:
CLOUDFLARE_ACCOUNT_ID,CLOUDFLARE_API_KEY,CLOUDFLARE_EMAIL,CLOUDFLARE_ZONE_ID,SLACK_WEBHOOK_URL. - Deleted all 1,406 deployments from the old
baseworks-kbPages project (required before project deletion — Cloudflare blocks deletion of projects with too many deployments). - Deleted the old
baseworks-kbPages project entirely.
- Deleted
Why the project is named baseworks-kb-git (not baseworks-kb)
Section titled “Why the project is named baseworks-kb-git (not baseworks-kb)”Cloudflare Pages projects can’t be renamed. To take back the original baseworks-kb name, we’d have had to delete the new project and recreate it after the old one was gone — adding risk for purely cosmetic benefit. The project name is an internal identifier; the public URL kb.baseworks.com is unchanged.
Operational notes for future Claude
Section titled “Operational notes for future Claude”- No more GitHub Actions in this repo. Any future workflow added here will start consuming the 2,000 min/cycle budget again.
- Deploy trigger is now Git push to
main. Cloudflare watches via the Pages App; no webhook on the repo (only Tina + n8n inbox webhooks remain). - Build status: Cloudflare dashboard at https://dash.cloudflare.com/5248b6291f647a77fa6852b2640a1899/pages/view/baseworks-kb-git or via API:
GET /accounts/:account_id/pages/projects/baseworks-kb-git/deployments. - Failure notifications: none configured. If KB-site build failures need to alert Slack, wire it up via Cloudflare Pages webhooks or a polling cron — don’t bring back GitHub Actions for this.
- Cache purging on deploy: automatic. The old workflow’s explicit
curl /purge_cachestep is no longer needed. - Cloudflare API credentials for any future Pages work are in
~/Documents/baseworks-changelog/CLAUDE-INSTRUCTIONS.md.
Rollback (no longer trivially possible)
Section titled “Rollback (no longer trivially possible)”The old project, workflow, and secrets are all gone. To revert, one would need to:
- Recreate a Direct Upload Pages project from
pages-project-config.jsonbackup. - Restore
deploy.ymlfromdeploy.yml.backup. - Recreate the five GitHub secrets (values would need to be regenerated/re-fetched from Cloudflare).
- Re-attach
kb.baseworks.comand update the CNAME back.
Backups exist for steps 1-2; secret values do not (GitHub doesn’t expose them, Cloudflare API key is in changelog repo).
Related
Section titled “Related”- Media Storage Plan — other Cloudflare-fronted infrastructure
- Forum Content Ingestion — also runs on push triggers, but to vault not site