workers-ci-cd

Cloudflare Workers CI/CD

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "workers-ci-cd" with this command: npx skills add secondsky/claude-skills/secondsky-claude-skills-workers-ci-cd

Cloudflare Workers CI/CD

Status: ✅ Production Ready | Last Verified: 2025-01-27 GitHub Actions: v4 | GitLab CI: Latest | Wrangler: 4.50.0

Table of Contents

  • What Is Workers CI/CD?

  • New in 2025

  • Quick Start (10 Minutes)

  • Critical Rules

  • Core Concepts

  • Top 5 Use Cases

  • Best Practices

  • Top 7 Errors Prevented

  • When to Load References

What Is Workers CI/CD?

Automated testing and deployment of Cloudflare Workers using GitHub Actions or GitLab CI. Enables running tests on every commit, deploying to preview/staging/production environments automatically, managing secrets securely, and implementing deployment gates for safe releases.

Key capabilities: Automated testing, multi-environment deployments, preview URLs per PR, secrets management, deployment verification, automatic rollbacks.

New in 2025

GitHub Actions Updates (January 2025):

  • NEW: cloudflare/wrangler-action@v4 (improved caching, faster deployments)

  • IMPROVED: Secrets support with vars and secrets parameters

  • ADDED: Built-in preview environment cleanup

  • BREAKING: apiToken renamed to api-token (kebab-case)

Migration from v3:

❌ OLD (v3)

  • uses: cloudflare/wrangler-action@3 with: apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}

✅ NEW (v4)

  • uses: cloudflare/wrangler-action@v4 with: api-token: ${{ secrets.CLOUDFLARE_API_TOKEN }}

Wrangler 4.50.0 (January 2025):

  • NEW: --dry-run flag for deployment validation

  • IMPROVED: Faster deployments with parallel uploads

  • ADDED: --keep-vars to preserve environment variables

Quick Start (10 Minutes)

GitHub Actions Setup

  1. Create Cloudflare API Token

Go to: https://dash.cloudflare.com/profile/api-tokens

Create token with permissions:

  • Account.Cloudflare Workers Scripts - Edit

  • Account.Cloudflare Pages - Edit (if using Pages)

  1. Add Secret to GitHub

Repository → Settings → Secrets → Actions → New repository secret:

  • Name: CLOUDFLARE_API_TOKEN

  • Value: [paste token]

  1. Create .github/workflows/deploy.yml

name: Deploy

on: push: branches: [main] pull_request: branches: [main]

jobs: deploy: runs-on: ubuntu-latest name: Deploy to Cloudflare Workers

steps:
  - uses: actions/checkout@v4

  - uses: oven-sh/setup-bun@v2
    with:
      bun-version: latest

  - run: bun install

  - run: bun test

  - name: Deploy
    uses: cloudflare/wrangler-action@v4
    with:
      api-token: ${{ secrets.CLOUDFLARE_API_TOKEN }}
      command: deploy

4. Push and Verify

git add .github/workflows/deploy.yml git commit -m "Add CI/CD pipeline" git push

Check Actions tab on GitHub to see deployment progress.

Critical Rules

  1. Never Commit Secrets to Git

✅ CORRECT:

Use GitHub Secrets

api-token: ${{ secrets.CLOUDFLARE_API_TOKEN }}

❌ WRONG:

❌ NEVER hardcode tokens

api-token: "abc123def456..."

Why: Exposed tokens allow anyone to deploy to your account.

  1. Always Run Tests Before Deploy

✅ CORRECT:

  • run: bun test # ✅ Tests run first

  • name: Deploy uses: cloudflare/wrangler-action@v4 with: api-token: ${{ secrets.CLOUDFLARE_API_TOKEN }}

❌ WRONG:

❌ Skipping tests

  • name: Deploy uses: cloudflare/wrangler-action@v4

    No tests!

Why: Broken code shouldn't reach production.

  1. Use Different Environments

✅ CORRECT:

Production (main branch)

  • name: Deploy to Production if: github.ref == 'refs/heads/main' run: bunx wrangler deploy --env production

Staging (other branches)

  • name: Deploy to Staging if: github.ref != 'refs/heads/main' run: bunx wrangler deploy --env staging

❌ WRONG:

❌ Always deploying to production

  • run: bunx wrangler deploy

Why: Test changes in staging before production.

  1. Verify Deployment Success

✅ CORRECT:

❌ WRONG:

❌ No verification

  • name: Deploy uses: cloudflare/wrangler-action@v4

    Assuming it worked...

Why: Deployments can fail silently (DNS issues, binding errors).

  1. Use Deployment Gates for Production

✅ CORRECT:

deploy-production: environment: name: production url: https://your-worker.workers.dev

Requires manual approval

❌ WRONG:

❌ Auto-deploy to production without review

deploy-production: runs-on: ubuntu-latest

Why: Human review catches issues automation misses.

Core Concepts

Multi-Environment Strategy

Recommended setup:

  • Production: main branch → production environment

  • Staging: Pull requests → staging environment

  • Preview: Each PR → unique preview URL

wrangler.jsonc:

{ "name": "my-worker", "main": "src/index.ts",

"env": { "production": { "name": "my-worker-production", "vars": { "ENVIRONMENT": "production" } }, "staging": { "name": "my-worker-staging", "vars": { "ENVIRONMENT": "staging" } } } }

Secrets Management

Types of configuration:

  • Public variables (wrangler.jsonc) - Non-sensitive config

  • Secrets (wrangler secret) - API keys, tokens

  • CI variables (GitHub Secrets) - Deployment credentials

Setting secrets:

Local development

wrangler secret put DATABASE_URL

CI/CD (via GitHub Actions)

bunx wrangler secret put DATABASE_URL --env production <<< "${{ secrets.DATABASE_URL }}"

Preview Deployments

Automatically deploy each PR to a unique URL for testing:

  • name: Deploy Preview uses: cloudflare/wrangler-action@v4 with: api-token: ${{ secrets.CLOUDFLARE_API_TOKEN }} command: deploy --env preview-${{ github.event.number }}

Each PR gets URL like: my-worker-preview-42.workers.dev

Top 5 Use Cases

  1. Deploy on Push to Main

name: Deploy Production

on: push: branches: [main]

jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: oven-sh/setup-bun@v2 - run: bun install - run: bun test - run: bun run build

  - name: Deploy to Production
    uses: cloudflare/wrangler-action@v4
    with:
      api-token: ${{ secrets.CLOUDFLARE_API_TOKEN }}
      command: deploy --env production

2. Preview Deployments for PRs

name: Preview

on: pull_request: branches: [main]

jobs: preview: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: oven-sh/setup-bun@v2 - run: bun install - run: bun test

  - name: Deploy Preview
    id: deploy
    uses: cloudflare/wrangler-action@v4
    with:
      api-token: ${{ secrets.CLOUDFLARE_API_TOKEN }}
      command: deploy --env preview-${{ github.event.number }}

  - name: Comment PR
    uses: actions/github-script@v7
    with:
      script: |
        github.rest.issues.createComment({
          issue_number: context.issue.number,
          owner: context.repo.owner,
          repo: context.repo.repo,
          body: '✅ Preview deployed to: https://my-worker-preview-${{ github.event.number }}.workers.dev'
        })

3. Run Tests on Every Commit

name: Test

on: push: branches: ['**'] pull_request:

jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: oven-sh/setup-bun@v2 - run: bun install - run: bun test --coverage

  - name: Upload Coverage
    uses: codecov/codecov-action@v4
    with:
      files: ./coverage/lcov.info

4. Deploy with Approval Gate

name: Deploy Production (Manual Approval)

on: push: branches: [main]

jobs: deploy: runs-on: ubuntu-latest environment: name: production url: https://my-worker.workers.dev # Requires manual approval in GitHub Settings

steps:
  - uses: actions/checkout@v4
  - uses: oven-sh/setup-bun@v2
  - run: bun install
  - run: bun test

  - name: Deploy
    uses: cloudflare/wrangler-action@v4
    with:
      api-token: ${{ secrets.CLOUDFLARE_API_TOKEN }}
      command: deploy --env production

5. Staged Rollout (Canary)

name: Canary Deployment

on: workflow_dispatch: inputs: percentage: description: 'Traffic percentage to new version' required: true default: '10'

jobs: canary: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: oven-sh/setup-bun@v2 - run: bun install

  # Deploy to canary environment
  - name: Deploy Canary
    uses: cloudflare/wrangler-action@v4
    with:
      api-token: ${{ secrets.CLOUDFLARE_API_TOKEN }}
      command: deploy --env canary

  # Configure traffic split via Cloudflare API
  # (See references/deployment-strategies.md for full example)

Best Practices

✅ DO

Use semantic commit messages:

feat: add user authentication fix: resolve rate limiting issue chore: update dependencies

Run linting and type checking:

  • run: bun run lint

  • run: bun run type-check

  • run: bun test

Cache dependencies:

  • uses: oven-sh/setup-bun@v2 with: bun-version: latest

Bun automatically caches dependencies

Deploy different branches to different environments:

  • name: Deploy run: | if [ "${{ github.ref }}" == "refs/heads/main" ]; then bunx wrangler deploy --env production else bunx wrangler deploy --env staging fi

Monitor deployments:

  • name: Notify Slack if: failure() uses: slackapi/slack-github-action@v1 with: payload: | {"text": "Deployment failed: ${{ github.sha }}"}

❌ DON'T

  • Don't skip tests

  • Don't deploy without verification

  • Don't hardcode secrets

  • Don't deploy to production from feature branches

  • Don't ignore deployment failures

Top 7 Errors Prevented

  1. ❌ Error: A valid Cloudflare API token is required

Cause: Missing or invalid CLOUDFLARE_API_TOKEN secret.

Fix:

  1. ❌ Error: Not enough permissions to deploy

Cause: API token lacks required permissions.

Fix: Recreate token with:

  • Account.Cloudflare Workers Scripts - Edit

  • Account settings - Read

  1. ❌ Error: wrangler.toml not found

Cause: Missing wrangler configuration.

Fix: Ensure wrangler.jsonc exists in repository root.

  1. ❌ Deployment succeeds but worker doesn't work

Cause: Missing secrets or environment variables.

Fix: Set secrets in CI:

  • name: Set Secrets run: | echo "${{ secrets.DATABASE_URL }}" | bunx wrangler secret put DATABASE_URL --env production
  1. ❌ Tests pass locally but fail in CI

Cause: Environment differences (Node version, missing dependencies).

Fix:

  • uses: oven-sh/setup-bun@v2 with: bun-version: latest # Lock version

  • run: bun install --frozen-lockfile # Use exact versions

  1. ❌ Preview deployments conflict

Cause: Multiple PRs deploying to same preview environment.

Fix: Use PR number in environment name:

command: deploy --env preview-${{ github.event.number }}

  1. ❌ Secrets exposed in logs

Cause: Echoing secrets in workflow.

Fix:

❌ WRONG

  • run: echo "Token: ${{ secrets.API_TOKEN }}"

✅ CORRECT

  • run: echo "Deploying..." # No secrets in output

When to Load References

Load reference files for detailed, specialized content:

Load references/github-actions.md when:

  • Setting up GitHub Actions from scratch

  • Configuring matrix builds (multiple Node versions)

  • Using GitHub environments and deployment protection

  • Implementing deployment gates and approvals

Load references/gitlab-ci.md when:

  • Setting up GitLab CI pipelines

  • Configuring GitLab environments

  • Using GitLab secret variables

  • Implementing review apps

Load references/deployment-strategies.md when:

  • Implementing blue-green deployments

  • Setting up canary releases

  • Configuring traffic splitting

  • Planning rollback procedures

Load references/secrets-management.md when:

  • Managing secrets across environments

  • Rotating API tokens

  • Using external secret providers (Vault, 1Password)

  • Implementing least-privilege access

Load templates/github-actions-full.yml for:

  • Complete production-ready GitHub Actions workflow

  • Multi-environment deployment example

  • All deployment gates configured

Load templates/gitlab-ci-full.yml for:

  • Complete GitLab CI pipeline

  • Multi-stage deployment

  • Review app configuration

Load templates/preview-deployment.yml for:

  • PR preview deployment setup

  • Automatic cleanup on PR close

  • Comment with preview URL

Load templates/rollback-workflow.yml for:

  • Manual rollback workflow

  • Deployment history tracking

  • Automated rollback on health check failure

Load scripts/verify-deployment.sh for:

  • Automated deployment verification

  • Health check implementation

  • Smoke tests after deployment

Related Cloudflare Plugins

For deployment testing, load:

  • cloudflare-workers-testing - Test Workers before deployment

  • cloudflare-manager - Manage deployments via Cloudflare API

This skill focuses on CI/CD automation for ALL Workers deployments regardless of bindings used.

Questions? Load references/secrets-management.md or use /workers-deploy command for guided deployment.

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

tailwind-v4-shadcn

No summary provided by upstream source.

Repository SourceNeeds Review
General

aceternity-ui

No summary provided by upstream source.

Repository SourceNeeds Review
General

playwright

No summary provided by upstream source.

Repository SourceNeeds Review
General

zod

No summary provided by upstream source.

Repository SourceNeeds Review