Deployment
Deploy zudo-doc sites to Cloudflare Pages with GitHub Actions CI/CD.
Overview
zudo-doc is a fully static site generator — the output of pnpm build is a directory of HTML, CSS, and JavaScript files that can be deployed anywhere. The default deployment target is Cloudflare Pages, using GitHub Actions for CI/CD automation.
The CI pipeline is split into parallel jobs to keep total build time low. Site generation and document history extraction run as separate jobs and are merged before deployment.
Cloudflare Pages
The built site is deployed to Cloudflare Pages using wrangler pages deploy. The deploy artifact includes:
- The Astro build output (
dist/) - Pre-generated doc history JSON files (if
docHistoryis enabled) - A redirect rule from
/to the site’s base path
ℹ️ Info
The redirect from / is a static _redirects file included in the build output. Cloudflare Pages processes it natively — no Worker or server logic is required.
CI Pipeline Structure
The project uses two GitHub Actions workflows.
Production (main-deploy.yml)
Triggered on push to main. Runs four jobs:
- build-site — shallow clone (
fetch-depth: 1), builds the Astro site withSKIP_DOC_HISTORY=1 pnpm build - build-history — full clone (
fetch-depth: 0), runs@zudo-doc/doc-history-server generateto pre-extract git history for all content files - deploy — merges the site and history artifacts, then deploys to Cloudflare Pages (production)
- notify — sends an IFTTT webhook notification with the deploy status
Concurrency: group: production-deploy, cancel-in-progress: false — earlier deploys are allowed to finish rather than being cancelled.
PR Checks (pr-checks.yml)
Triggered on pull requests targeting main. Runs five jobs:
- typecheck — runs
pnpm check(Astro type checking) - build-site — shallow clone,
SKIP_DOC_HISTORY=1 pnpm build, thencheck:links - build-history — full clone, doc history generation
- e2e — runs Playwright end-to-end tests (full clone, no
SKIP_DOC_HISTORYso history is embedded inline) - preview — merges artifacts and deploys a preview to Cloudflare Pages, then posts the URL as a PR comment
Concurrency: group: pr-checks-{pr-number}, cancel-in-progress: true — outdated runs are cancelled to save CI minutes.
Preview Deployments
Each PR gets a preview deployment at:
https://pr-{number}.zudo-doc.pages.dev
The URL is posted automatically as a comment on the PR by the preview job.
SKIP_DOC_HISTORY
When SKIP_DOC_HISTORY=1 is set, the Astro integration skips inline history generation during the build. This flag exists because history generation requires a full git clone and walks every commit — it is too slow to run inside the main build job.
| Context | Value | Why |
|---|---|---|
CI build-site job | SKIP_DOC_HISTORY=1 | History is generated by the separate build-history job |
CI e2e job | unset | E2E tests verify history features inline |
Local pnpm build | unset | History is embedded directly in the build output |
💡 Tip
If you run pnpm build locally without SKIP_DOC_HISTORY=1, the history generation runs inline. This is slower but produces a self-contained dist/ that works without a separate history artifact.
Inter-Job Data Sharing
Build artifacts are shared between jobs using actions/cache rather than actions/upload-artifact. Cache keys are scoped to github.run_id to prevent cross-run contamination:
key: dist-${{ github.run_id }}
key: doc-history-${{ github.run_id }}
The deploy (or preview) job restores both caches and merges the dist/ directories before calling wrangler pages deploy.
📝 Note
Using actions/cache for job-to-job data transfer (rather than artifacts) avoids the overhead of uploading and downloading large ZIP archives. Cache entries are cheaper for temporary intra-run data.
Required Secrets
Configure these in your repository’s Settings → Secrets and variables → Actions:
| Secret | Description |
|---|---|
CLOUDFLARE_API_TOKEN | Cloudflare API token with Pages deployment permissions |
CLOUDFLARE_ACCOUNT_ID | Your Cloudflare account ID |
IFTTT_PROD_NOTIFY | IFTTT webhook URL for deploy notifications (optional) |
⚠️ Warning
The CLOUDFLARE_API_TOKEN needs the Cloudflare Pages: Edit permission. Scoping it to the specific Pages project is recommended over granting account-wide access.