Marketplace

workers-ci-cd

Complete CI/CD guide for Cloudflare Workers using GitHub Actions and GitLab CI. Use for automated testing, deployment pipelines, preview environments, secrets management, or encountering deployment failures, workflow errors, environment configuration issues.

$ 설치

git clone https://github.com/secondsky/claude-skills /tmp/claude-skills && cp -r /tmp/claude-skills/plugins/cloudflare-workers/skills/cloudflare-workers-ci-cd ~/.claude/skills/claude-skills

// tip: Run this command in your terminal to install the skill


name: workers-ci-cd description: Complete CI/CD guide for Cloudflare Workers using GitHub Actions and GitLab CI. Use for automated testing, deployment pipelines, preview environments, secrets management, or encountering deployment failures, workflow errors, environment configuration issues. keywords:

  • cloudflare-workers
  • workers-ci-cd
  • github-actions
  • gitlab-ci
  • continuous-integration
  • continuous-deployment
  • automated-testing
  • deployment-pipeline
  • preview-deployments
  • staging-deployment
  • production-deployment
  • secrets-management
  • wrangler-deploy
  • environment-variables
  • github-secrets
  • deployment-verification
  • rollback-strategy
  • blue-green-deployment
  • canary-deployment
  • deployment-gates
  • ci-cd-best-practices
  • workflow-automation
  • pull-request-previews
  • branch-deployments license: MIT metadata: version: "1.0.0" last_verified: "2025-01-27" production_tested: true token_savings: "~75%" errors_prevented: 7 templates_included: 4 references_included: 4 scripts_included: 1 github_actions_version: "v4" wrangler_version: "4.50.0"

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?

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)

2. Add Secret to GitHub

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

  • Name: CLOUDFLARE_API_TOKEN
  • Value: [paste token]

3. 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.

2. 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.

3. 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.

4. Verify Deployment Success

✅ CORRECT:

- name: Deploy
  id: deploy
  uses: cloudflare/wrangler-action@v4

- name: Verify Deployment
  run: |
    curl -f https://your-worker.workers.dev/health || exit 1

❌ WRONG:

# ❌ No verification
- name: Deploy
  uses: cloudflare/wrangler-action@v4
  # Assuming it worked...

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

5. 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:

  1. Public variables (wrangler.jsonc) - Non-sensitive config
  2. Secrets (wrangler secret) - API keys, tokens
  3. 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

  1. Use semantic commit messages:

    feat: add user authentication
    fix: resolve rate limiting issue
    chore: update dependencies
    
  2. Run linting and type checking:

    - run: bun run lint
    - run: bun run type-check
    - run: bun test
    
  3. Cache dependencies:

    - uses: oven-sh/setup-bun@v2
      with:
        bun-version: latest
    # Bun automatically caches dependencies
    
  4. 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
    
  5. Monitor deployments:

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

❌ DON'T

  1. Don't skip tests
  2. Don't deploy without verification
  3. Don't hardcode secrets
  4. Don't deploy to production from feature branches
  5. 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. Create API token: https://dash.cloudflare.com/profile/api-tokens
  2. Add to GitHub Secrets: Settings → Secrets → Actions
  3. Use in workflow: api-token: ${{ secrets.CLOUDFLARE_API_TOKEN }}

2. ❌ Error: Not enough permissions to deploy

Cause: API token lacks required permissions.

Fix: Recreate token with:

  • Account.Cloudflare Workers Scripts - Edit
  • Account settings - Read

3. ❌ Error: wrangler.toml not found

Cause: Missing wrangler configuration.

Fix: Ensure wrangler.jsonc exists in repository root.


4. ❌ 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

5. ❌ 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

6. ❌ 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 }}

7. ❌ 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.

Repository

secondsky
secondsky
Author
secondsky/claude-skills/plugins/cloudflare-workers/skills/cloudflare-workers-ci-cd
9
Stars
0
Forks
Updated3d ago
Added1w ago