GitHub Actions with Cloudflare Pages
Workflow Overview
Section titled “Workflow Overview”The workflow runs on:
- Push to
main
branch - Pull requests to
main
branch - Manual trigger via
workflow_dispatch
Only deployments to production occur on main
branch pushes or manual triggers.
Workflow Configuration
Section titled “Workflow Configuration”Concurrency Control
Section titled “Concurrency Control”concurrency: group: "pages" cancel-in-progress: true
Ensures only one deployment runs at a time, cancelling any in-progress deployments when a new one starts.
Job Environment
Section titled “Job Environment”- Runner:
ubuntu-latest
- Package Manager: Bun
- Deployment Target: Cloudflare Pages
Step-by-Step Breakdown
Section titled “Step-by-Step Breakdown”1. Repository Checkout
Section titled “1. Repository Checkout”- name: Checkout repository uses: actions/checkout@v4 with: fetch-depth: 2
- Downloads repository code
fetch-depth: 2
fetches the last 2 commits (needed for git information extraction)
2. Bun Environment Setup
Section titled “2. Bun Environment Setup”- name: Setup Bun environment uses: oven-sh/setup-bun@v1
- Installs and configures Bun runtime
- Uses the official Bun setup action
3. Dependency Caching
Section titled “3. Dependency Caching”Three separate caching layers optimize build times:
Bun Dependencies Cache
Section titled “Bun Dependencies Cache”- name: Cache Bun dependencies uses: actions/cache@v4 with: path: | ~/.bun/install/cache node_modules key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lockb') }}-${{ hashFiles('**/package.json') }}
- Caches
node_modules
and Bun’s internal cache - Cache key includes OS, lockfile hash, and package.json hash
- Invalidates when dependencies change
Playwright Browsers Cache
Section titled “Playwright Browsers Cache”- name: Cache Playwright browsers uses: actions/cache@v4 with: path: ~/.cache/ms-playwright key: ${{ runner.os }}-playwright-${{ hashFiles('**/package.json') }}
- Caches Playwright browser binaries (used by rehype-mermaid)
- Prevents re-downloading large browser files on each run
Astro Build Cache
Section titled “Astro Build Cache”- name: Cache Astro build uses: actions/cache@v4 with: path: | .astro dist key: ${{ runner.os }}-astro-${{ github.sha }}
- Caches Astro’s internal cache and build output
- Uses commit SHA as key for precise cache invalidation
4. Dependency Installation
Section titled “4. Dependency Installation”- name: Install project dependencies run: bun install
- Installs all project dependencies using Bun
- Benefits from dependency caching if available
5. Playwright Browser Installation
Section titled “5. Playwright Browser Installation”- name: Install Playwright browsers for rehype-mermaid if: steps.playwright-cache.outputs.cache-hit != 'true' run: bunx playwright install --with-deps chromium
- Only runs if Playwright cache missed
- Installs Chromium browser needed for Mermaid diagram rendering
--with-deps
ensures system dependencies are installed
6. Build with Retry Logic
Section titled “6. Build with Retry Logic”- name: Build project with retry env: MAX_ATTEMPTS: 3 RETRY_INTERVAL: 30 run: | attempt=1 until bun run build || [ $attempt -eq $MAX_ATTEMPTS ]; do echo "Build attempt $attempt failed. Retrying in $RETRY_INTERVAL seconds..." sleep $RETRY_INTERVAL attempt=$((attempt + 1)) done
- Implements retry mechanism for build failures
- Attempts build up to 3 times with 30-second delays
- Handles transient build issues (network timeouts, temporary failures)
7. Git Information Extraction
Section titled “7. Git Information Extraction”- name: Get git information id: git-info if: github.ref == 'refs/heads/main' || github.event_name == 'workflow_dispatch' run: | echo "COMMIT_HASH=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT echo "COMMIT_MESSAGE=$(git log -1 --pretty=%B)" >> $GITHUB_OUTPUT echo "BRANCH_NAME=$(git rev-parse --abbrev-ref HEAD)" >> $GITHUB_OUTPUT echo "COMMIT_DIRTY=$(if [[ -n $(git status -s) ]]; then echo true; else echo false; fi)" >> $GITHUB_OUTPUT
Only runs for deployments. Extracts:
- COMMIT_HASH: Full commit SHA
- COMMIT_MESSAGE: Last commit message
- BRANCH_NAME: Current branch name
- COMMIT_DIRTY: Whether working directory has uncommitted changes
8. Cloudflare Pages Deployment
Section titled “8. Cloudflare Pages Deployment”- name: Deploy to Cloudflare Pages if: github.ref == 'refs/heads/main' || github.event_name == 'workflow_dispatch' uses: cloudflare/wrangler-action@v3 with: apiToken: ${{ secrets.CLOUDFLARE_WRANGLER_TOKEN }} accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} command: pages deploy dist --project-name=erfi-dev-docs wranglerVersion: '4.28.1' packageManager: bun
- Deploys built assets to Cloudflare Pages
- Uses Wrangler CLI with specific version pinning
- Passes git information for deployment metadata
9. Cache Purging (Optional)
Section titled “9. Cache Purging (Optional)”- name: Purge Cloudflare Cache if: (github.ref == 'refs/heads/main' || github.event_name == 'workflow_dispatch') && success() run: | curl -X POST "https://api.cloudflare.com/client/v4/zones/${{ secrets.CLOUDFLARE_ZONE_ID }}/purge_cache" \ -H "Authorization: Bearer ${{ secrets.CLOUDFLARE_CACHE_PURGE_TOKEN }}" \ -H "Content-Type: application/json" \ --data '{"hosts":["erfi.dev"]}'
- Purges Cloudflare edge cache for the domain
- Only runs after successful deployment
- Ensures users see updated content immediately
Required Secrets
Section titled “Required Secrets”Configure these secrets in your GitHub repository settings:
Secret Name | Description |
---|---|
CLOUDFLARE_WRANGLER_TOKEN | Cloudflare API token with Pages:Edit permissions |
CLOUDFLARE_ACCOUNT_ID | Your Cloudflare account ID |
CLOUDFLARE_ZONE_ID | Zone ID for your domain |
CLOUDFLARE_CACHE_PURGE_TOKEN | API token with Zone:Cache Purge permissions |