Jan 14, 2026 2 min read

How I Fixed My CI/CD: Fast, Optimized, and Pro-Level Deploys (Hugo + Cloudflare)

We’ve all been there: you push a tiny CSS tweak, and then you sit… and wait… and watch the GitHub Actions logs spin.

My Hugo site was taking nearly a minute to deploy. Not “slow” by 2010 standards, but for a modern static site? That’s an eternity. I dug into the logs, found the bottlenecks, and trimmed the fat. Here’s how I optimized my CI/CD pipeline.

1. The Problem: The “Wrangler Tax”

Looking at my logs, I saw a massive yellow wall of text. Every single time I deployed, GitHub was:

  1. Installing an ancient version of Wrangler (v2).

  2. Realizing it was outdated.

  3. Delegating to a newer version (v4).

This “version dance” was eating up about 20-30 seconds per build for absolutely no reason. Plus, I was using the deprecated pages-action@v1.

2. The Fix: Modernizing the Stack

I swapped out the old pages-action@v1 for the modern cloudflare/wrangler-action@v3. This is built to use the latest Wrangler engine by default. No more “delegation” and no more warnings.

3. The Pro Move: Preview Deploys

The “Final Form” Workflow

Here is the optimized .github/workflows/deploy.yml:

YAML

name: Deploy Hugo

on:
  push:
    branches:
      - main
      - '*' # This triggers the build for ANY branch!

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          submodules: true
          fetch-depth: 0 

      - name: Setup pnpm
        uses: pnpm/action-setup@v4
        with:
          version: 9

      - name: Setup Hugo
        uses: peaceiris/actions-hugo@v3
        with:
          hugo-version: 'latest'
          extended: true

      - name: Cache Hugo resources
        uses: actions/cache@v4
        with:
          path: resources
          key: ${{ runner.os }}-hugo-resources-${{ hashFiles('content/**', 'assets/**') }}

      - name: Build
        run: pnpm install && hugo --gc --minify

      - name: Deploy to Cloudflare Pages
        uses: cloudflare/wrangler-action@v3
        with:
          apiToken: ${{ secrets.CF_API_TOKEN }}
          accountId: ${{ secrets.CF_ACCOUNT_ID }}
          # DYNAMIC BRANCHING: This detects if it's main or a preview
          command: pages deploy ./public --project-name=olimiah --branch=${{ github.ref_name }}

The Results

  • Clean Logs: No more “Deprecated” warnings.

  • Speed: We skip the overhead of installing multiple Wrangler versions.

  • Confidence: With Preview Deploys, I can test risky changes on a separate branch without touching my live site.

Stop using pages-action@v1. Switch to wrangler-action@v3, use the pages deploy command with dynamic branching, and cache your resources.

You’re all set!