---
title: Cloudflare Workers Deploys: Built-In Git vs. GitHub Actions
description: Two ways to auto-deploy a static site to Cloudflare Workers: built-in Git integration vs. a custom GitHub Actions workflow, and how to choose.
date: 2026-07-27T00:00:00.000Z
category: data-automation
tags: automation, ci-cd, cloudflare, github-actions
---

Running `wrangler deploy` from your own machine works fine for the first week of a project. It stops working the moment you want deploys to happen consistently: from a clean environment, without depending on whoever happens to be at their keyboard, and ideally gated on the build actually passing first. That's what automated deploys solve, and for a static site on Cloudflare Workers there are two reasonable ways to set it up.

## Quick Answer

Cloudflare Workers Builds deploys straight from a dashboard Git connection with zero YAML, on every push, but with no pre-deploy checks beyond the build itself. GitHub Actions needs a workflow file but lets you gate the deploy on tests, lint, or an accessibility check passing first. Start with Workers Builds; move to Actions once a bad deploy reaching production would actually cost you something.

## Option A: Cloudflare Workers Builds

Cloudflare can watch your GitHub repository directly and deploy on every push, with no YAML file of your own to maintain. In the dashboard: **Workers & Pages → your Worker → Settings → Builds → Connect to Git**, point it at the repo and branch, and set a [build command (`npm run build`) and the directory the build outputs to](https://developers.cloudflare.com/workers/ci-cd/builds/configuration/).

From then on, every push to the connected branch triggers a build and deploy automatically, and the dashboard shows build logs and history per deploy, with no infrastructure to maintain on your side.

<Callout type="tip" title="Scope the deploy, not the whole account">
  If you later add a GitHub Actions workflow alongside or instead of Workers
  Builds, generate a Cloudflare API token scoped to exactly `Workers
  Scripts:Edit` for the account/zone in question, not a broad, all-permissions
  token. A workflow only needs enough access to deploy the one Worker; if the
  token ever leaks, narrow scope limits the blast radius.
</Callout>

## Option B: GitHub Actions

The tradeoff with Workers Builds is control: it runs your build command and deploys, full stop. If you want to run tests, linting, or accessibility checks first, and only deploy if they pass, you need a workflow you author yourself.

```yaml title=".github/workflows/deploy.yml"
name: Deploy

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5

      - uses: actions/setup-node@v5
        with:
          node-version: 24

      - run: npm ci
      - run: npm run lint
      - run: npm run build

      - name: Deploy to Cloudflare Workers
        uses: cloudflare/wrangler-action@v3
        with:
          apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
          command: deploy
```

The deploy step only runs if every step above it succeeds: a broken build or a failing lint check never reaches production. The `CLOUDFLARE_API_TOKEN` secret is set once under the repo's [**Settings → Secrets and variables → Actions**](https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions), scoped the same way as described above.

## Choosing between them

|                   | Workers Builds                 | GitHub Actions                                           |
| ----------------- | ------------------------------ | -------------------------------------------------------- |
| Setup effort      | Minutes, no files to write     | A YAML file to author and maintain                       |
| Pre-deploy checks | Build command only             | Any number of steps, deploy gated on all passing         |
| Where logs live   | Cloudflare dashboard           | GitHub Actions tab                                       |
| Best for          | Small projects, fast iteration | Projects with tests/lint you want enforced before deploy |

A reasonable default: start with Workers Builds, since it costs nothing to set up and gets you automatic deploys immediately. Move to GitHub Actions once there's a build step you genuinely don't want to skip, such as tests, an accessibility check, or a broken-link scan, and you want a bad result to block the deploy rather than just show up in a log after the fact.

Both approaches deploy the exact same `wrangler deploy` command underneath; the difference is entirely about what runs before it.

Once deploys are automated, check the actual runtime behavior too, not just that the build succeeded: see [fixing Cloudflare Workers' empty 404 page](/guides-fixes/fix-cloudflare-workers-empty-404-astro/) for a config gap that a passing build won't catch.
