cloudflare-workers-ci-cd — quality + safety report
In the Skillier index (secondsky__cloudflare-workers-ci-cd) · scanned 2026-06-03 · engine: builtin+triage
2 heuristic flags to review
Heuristic flags from the builtin scanner, which is known to over-flag (it trips on legitimate env-reading integrations, security skills, and library .eval calls). This is NOT an authoritative malicious verdict — re-scan with SkillSpector for the authoritative result. Run the authoritative scan →
📇 This skill is in the Skillier index (curated · deduped · quality-filtered). Install Skillier to route & load it into your AI client.
Quality notes
About this skill
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.
📄 Read the SKILL.md
---
name: cloudflare-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.
license: MIT
metadata:
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"
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?](#what-is-workers-cicd)
- [New in 2025](#new-in-2025)
- [Quick Start (10 Minutes)](#quick-start-10-minutes)
- [Critical Rules](#critical-rules)
- [Core Concepts](#core-concepts)
- [Top 5 Use Cases](#top-5-use-cases)
- [Best Practices](#best-practices)
- [Top 7 Errors Prevented](#top-7-errors-prevented)
- [When to Load References](#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**:
```yaml
# ❌ 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`**
```yaml
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**
```bash
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**:
```yaml
# Use GitHub Secrets
api-token: ${{ secrets.CLOUDFLARE_API_TOKEN }}
```
**❌ WRONG**:
```yaml
# ❌ NEVER hardcode tokens
api-token: "abc123def456..."
```
**Why**: Exposed tokens allow anyone to deploy to your account.
### 2. Always Run Tests Before Deploy
**✅ CORRECT**:
```yaml
- run: bun test # ✅ Tests run first
- name: Deploy
uses: cloudflare/wrangler-action@v4
with:
api-token: ${{ secrets.CLOUDFLARE_API_TOKEN }}
```
**❌ WRONG**:
```yaml
# ❌ Skipping tests
- name: Deploy
uses: cloudflare/wrangler-action@v4
# No tests!
```
**Why**: Broken code shouldn't reach production.
### 3. Use Different Environments
**✅ CORRECT**:
```yaml
# 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**:
```yaml
# ❌ Always deploying to production
- run: bunx wrangler deploy
```
**Why**: Test changes in staging before production.
### 4. Verify Deployment Success
**✅ CORRECT**:
```yaml
- name: Deploy
id: deploy
uses: cloudflare/wrangler-action@v4
- name: Verify Deployment
run: |
curl -f https://your-worker.workers.dev/health || exit 1
```
**❌ WRONG**:
```yaml
# ❌ 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**:
```yaml
deploy-production:
environment:
name: production
url: https://your-worker.workers.dev
# Requires manual approval
```
**❌ WRONG**:
```yaml
# ❌ 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**:
```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**:
```bash
# 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:
```yaml
- 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
```yaml
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
```yaml
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
```yaml
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
```yaml
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)
```yaml
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**:
```yaml
- run: bun run lint
- run: bun run type-check
- run: bun test
```
3. **Cache dependencies**:
```yaml
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
# Bun automatically caches dependencies
```
4. **Deploy different branches to different environments**:
```yaml
- 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**:
```yaml
- 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 → Secre
… (truncated)Want a live grade + an embeddable README badge? Run your skill through the free scanner.
Graded independently by Skillproof — nothing to sell the author. Quality is mechanical + corpus-grounded; safety flags are heuristic (builtin+triage), not a malicious verdict.