Skip to content

GitHub Actions with Cloudflare Pages

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.

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.

  • Runner: ubuntu-latest
  • Package Manager: Bun
  • Deployment Target: Cloudflare Pages
- 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)
- name: Setup Bun environment
uses: oven-sh/setup-bun@v1
  • Installs and configures Bun runtime
  • Uses the official Bun setup action

Three separate caching layers optimize build times:

- 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
- 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
- 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
- name: Install project dependencies
run: bun install
  • Installs all project dependencies using Bun
  • Benefits from dependency caching if available
- 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
- 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)
- 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
- 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
- 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

Configure these secrets in your GitHub repository settings:

Secret NameDescription
CLOUDFLARE_WRANGLER_TOKENCloudflare API token with Pages:Edit permissions
CLOUDFLARE_ACCOUNT_IDYour Cloudflare account ID
CLOUDFLARE_ZONE_IDZone ID for your domain
CLOUDFLARE_CACHE_PURGE_TOKENAPI token with Zone:Cache Purge permissions