Cc-skills cloudflare-workers-publish
Deploy static HTML files to Cloudflare Workers with 1Password credential management. TRIGGERS - Cloudflare Workers deploy, publish static site, wrangler deploy, static hosting, cloudflare publish, CF Workers, HTML hosting, workers.dev, static assets deploy
git clone https://github.com/terrylica/cc-skills
T=$(mktemp -d) && git clone --depth=1 https://github.com/terrylica/cc-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/plugins/devops-tools/skills/cloudflare-workers-publish" ~/.claude/skills/terrylica-cc-skills-cloudflare-workers-publish && rm -rf "$T"
plugins/devops-tools/skills/cloudflare-workers-publish/SKILL.mdCloudflare Workers Publish
Deploy static HTML files (Bokeh charts, dashboards, reports) to Cloudflare Workers with Static Assets, using 1Password for credential management.
Scope: Static-only deployments on workers.dev. No dynamic Workers, no R2 object storage.
Prerequisite: 1Password CLI (
brew install 1password-cli) + Node.js (npx wrangler)
Self-Evolving Skill: This skill improves through use. If instructions are wrong, parameters drifted, or a workaround was needed — fix this file immediately, don't defer. Only update for real, reproducible issues.
When to Use This Skill
- Publishing HTML files to a public URL (too large for GitHub)
- Setting up a new Cloudflare Workers static site
- Troubleshooting a failed Cloudflare deploy
- Rotating Cloudflare API tokens in 1Password
Do NOT use for: Dynamic Workers (JavaScript/TypeScript logic), Cloudflare Pages (deprecated April 2025 - CFW-01), R2 object storage, or custom domains (advanced setup not covered).
Architecture
Local project/ ├── results/published/ # Deploy root (contains wrangler.toml) │ ├── wrangler.toml # Workers config (name + assets) │ ├── index.html # Auto-generated directory listing │ └── gen800/ # Subdirectories with HTML files │ └── XRPUSDT_750/ │ └── equity_plot.html # 13MB Bokeh chart └── scripts/ └── publish_findings.sh # Deploy script (3 phases) Credential flow: 1Password (Claude Automation vault) ├── account_id (TEXT) → CLOUDFLARE_ACCOUNT_ID env var └── credential (CONCEALED) → CLOUDFLARE_API_TOKEN env var ↓ npx wrangler deploy ↓ https://{name}.{slug}.workers.dev/
TodoWrite Task Templates
Template A - New Static Site (First-Time Setup)
1. [Preflight] Verify Node.js and 1Password CLI installed 2. [Preflight] Create Cloudflare API token (Workers Scripts Edit permission) 3. [Execute] Pre-provision 1Password item in Claude Automation vault (biometric) 4. [Execute] Store token + account ID in 1Password item fields 5. [Execute] Create publish directory with wrangler.toml (3 fields only) 6. [Execute] Create deploy script from skill template (parameterize 4 vars) 7. [Execute] Create mise task wrapper in .mise/tasks/publish.toml 8. [Execute] Add .wrangler/ to .gitignore 9. [Execute] Add LFS tracking for large HTML files in .gitattributes 10. [Verify] Enable workers.dev subdomain in Cloudflare dashboard 11. [Verify] Run first deploy and verify URL in browser (NOT curl) 12. [Verify] Document the workers.dev URL in project docs
Template B - Add Files to Existing Published Site
1. [Preflight] Verify files are real content, not LFS pointers (head -1) 2. [Execute] Copy HTML files to published/{generation}/{symbol_threshold}/ 3. [Execute] Run deploy script (index.html auto-regenerates) 4. [Verify] Verify new files appear at workers.dev URL in browser
Template C - New Worker (New Subdomain/Project)
1. [Preflight] Choose worker name ({name}.{slug}.workers.dev) 2. [Execute] Create 1Password item OR reuse existing Cloudflare credentials 3. [Execute] Create wrangler.toml with chosen name and today's date 4. [Execute] Create parameterized deploy script from skill template 5. [Execute] Create mise task wrapper 6. [Verify] Deploy and discover actual workers.dev URL via wrangler output
Template D - Rotate Cloudflare API Token
1. [Execute] Create new API token in Cloudflare dashboard (Workers Scripts Edit) 2. [Execute] Update 1Password item credential field (biometric required) 3. [Verify] Run deploy script to verify new token works 4. [Execute] Revoke old token in Cloudflare dashboard
Template E - Troubleshoot Failed Deploy
1. Is wrangler.toml in current directory? (CFW-10) 2. Are credentials populated? Print first 8 chars of account ID 3. Is --reveal present for CONCEALED fields? (CFW-03) 4. Is workers.dev subdomain registered in CF dashboard? (CFW-07) 5. Does token have Workers Scripts Edit permission? (CFW-11) 6. Are HTML files real content or LFS pointers? head -1 file (CFW-12) 7. SSL handshake error? Verify in browser, not curl (CFW-08) 8. Is npx wrangler installed? npx wrangler --version
Workflow: First-Time Setup
Phase 1: Create Cloudflare API Token
- Go to https://dash.cloudflare.com/profile/api-tokens
- Click Create Token > Custom token
- Set permissions: Account > Workers Scripts > Edit (CFW-11)
- Account Resources: Include > your account
- Copy the token (shown only once)
Phase 2: Provision 1Password Credentials
CRITICAL (CFW-02): 1Password service accounts can only READ items. They CANNOT CREATE new items. Create the item manually first.
See 1Password setup guide for step-by-step instructions.
After provisioning, the item should have:
| Field | Type | | Content |
|---|---|---|---|
| TEXT | No | Cloudflare acct ID |
| CONCEALED | YES | API token |
Phase 3: Create wrangler.toml
See wrangler setup guide.
# Minimal Workers Static Assets config (CFW-09) name = "my-project-name" compatibility_date = "2026-02-18" [assets] directory = "."
Phase 4: Create Deploy Script
Copy the bundled template and edit the 4 config variables:
cp "$(skill-path)/scripts/publish_static.sh" scripts/publish_myproject.sh # Edit: PUBLISH_DIR, OP_ITEM_ID, SITE_TITLE, PROJECT_URL
Or reference the working implementation:
rangebar-patterns/scripts/publish_findings.sh
Phase 5: Create mise Task
# .mise/tasks/publish.toml (CFW-13: bash in .sh file, not inline TOML) ["publish:site"] description = "Deploy published files to Cloudflare Workers (static)" run = "bash scripts/publish_myproject.sh"
Add to
.mise.toml [task_config] includes:
[task_config] includes = [ ".mise/tasks/publish.toml", ]
Phase 6: Git Hygiene
.gitignore:
# Wrangler temp files (Cloudflare Workers deploy) .wrangler/ results/published/.wrangler/
.gitattributes (for large HTML files):
results/published/**/*.html filter=lfs diff=lfs merge=lfs -text
Phase 7: Enable workers.dev Subdomain (CFW-07)
First-time Cloudflare accounts must enable the workers.dev route:
- Go to https://dash.cloudflare.com > Workers & Pages
- Enable workers.dev subdomain
The subdomain is NOT predictable (CFW-06). Discover yours after deploy:
npx wrangler whoami
Phase 8: Deploy and Verify
mise run publish:site
Verify in BROWSER, not curl (CFW-08). macOS LibreSSL can fail TLS handshake with Cloudflare but browsers handle it fine.
Anti-Patterns Summary
Full details with code examples: references/anti-patterns.md
| ID | Severity | Gotcha | Fix |
|---|---|---|---|
| CFW-01 | HIGH | Cloudflare Pages deprecated (April 2025) | Use Workers with Static Assets |
| CFW-02 | HIGH | 1P service account creating items | Pre-provision via biometric/web UI |
| CFW-03 | HIGH | Missing for CONCEALED fields | Always pass for API tokens |
| CFW-04 | MEDIUM | SC2155 | Split: then |
| CFW-05 | LOW | Bash 4+ on macOS | Use |
| CFW-06 | MEDIUM | Assuming workers.dev URL format | Run to discover slug |
| CFW-07 | HIGH | workers.dev subdomain not registered | Enable in Cloudflare dashboard first |
| CFW-08 | LOW | curl SSL/TLS handshake failure on macOS | Verify in browser instead |
| CFW-09 | MEDIUM | Overcomplicating wrangler.toml | Only , , |
| CFW-10 | HIGH | Running wrangler from wrong directory | Always to directory with wrangler.toml |
| CFW-11 | MEDIUM | Excessive token permissions | Workers Scripts Edit (Account) only |
| CFW-12 | HIGH | Deploying LFS pointers instead of files | Run before deploy |
| CFW-13 | MEDIUM | Tera template conflict in mise TOML | Complex bash in standalone files |
| CFW-14 | MEDIUM | Pipe subshell data loss in while-read | Use process substitution |
| CFW-15 | LOW | No directory listing page | Auto-generate index.html before each deploy |
Reference Implementation
The working production deployment lives in
rangebar-patterns:
| File | Purpose |
|---|---|
| Minimal Workers config |
| 3-phase deploy script |
| mise task wrapper |
() | Ignore wrangler temp files |
| LFS tracking for HTML |
Live URL:
https://rangebar-findings.terry-301.workers.dev/
Post-Change Checklist
After modifying this skill:
- Anti-patterns table matches references/anti-patterns.md
- All bash examples use
set -euo pipefail - No hardcoded 1Password item IDs (parameterized)
- No hardcoded workers.dev slugs (discovered at runtime)
- Template script passes
syntax checkbash -n - All internal links use relative paths (
)./references/... - Link validator passes
- Skill validator passes
- Append changes to references/evolution-log.md
Troubleshooting
| Issue | Cause | Solution |
|---|---|---|
returns masked | Missing flag (CFW-03) | Add for CONCEALED fields |
fails | Service account can't create (CFW-02) | Use biometric or web UI to create item first |
| wrangler: config not found | Not in correct directory (CFW-10) | to directory containing wrangler.toml before deploy |
| SSL handshake failure | macOS LibreSSL (CFW-08) | Verify in browser; ignore curl errors |
| 403 on workers.dev URL | Subdomain not enabled (CFW-07) | Enable in Cloudflare dashboard > Workers & Pages |
| Deploy succeeds, files missing | LFS pointers deployed (CFW-12) | Run before deploy |
syntax error | Bash 3 on macOS (CFW-05) | Use |
| mise TOML parse error | Tera template conflict (CFW-13) | Move complex bash to standalone file |
| Empty index.html | No files found | Check file paths match pattern |
| Token permission denied | Wrong token scope (CFW-11) | Recreate with Account > Workers Scripts > Edit permission |
Post-Execution Reflection
After this skill completes, reflect before closing the task:
- Locate yourself. — Find this SKILL.md's canonical path (Glob for this skill's name) before editing. All corrections target THIS file and its sibling references/ — never other documentation.
- What failed? — Fix the instruction that caused it. If it could recur, add it as an anti-pattern.
- What worked better than expected? — Promote it to recommended practice. Document why.
- What drifted? — Any script, reference, or external dependency that no longer matches reality gets fixed now.
- Log it. — Every change gets an evolution-log entry with trigger, fix, and evidence.